generated from helsingborg-stad/gdi-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of https://github.com/helsingborg-stad/haffa-backend
- Loading branch information
Showing
8 changed files
with
227 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,3 +51,11 @@ FS_DATA_PATH=.local/data | |
# Passwordless configuration | ||
# | ||
#PASSWORDLESS_TTL=10m | ||
|
||
#------------------------------------------------------------ | ||
# | ||
# Brevo email notifications (https://www.brevo.com/) | ||
# | ||
#BREVO_API_KEY=abc123 | ||
#BREVO_FROM_NAME=Haffa | ||
#[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import request from 'superagent' | ||
import type { | ||
BrevoConfig, | ||
BrevoClient, | ||
RelevantGetTemplatesResult, | ||
Identity, | ||
TemplateName, | ||
SendMailPostRequestBody, | ||
} from './types' | ||
|
||
export function createClient(config: BrevoConfig): BrevoClient { | ||
const doGet = async <T>(endpoint: string, data?: string) => { | ||
const { body } = await request | ||
.get(`https://api.brevo.com/v3/${endpoint}`) | ||
.set('api-key', config.apiKey) | ||
.set('Content-Type', 'application/json') | ||
.send(data) | ||
return body as T | ||
} | ||
|
||
const doPost = async <T = undefined>(endpoint: string, data: object) => { | ||
const { body } = await request | ||
.post(`https://api.brevo.com/v3/${endpoint}`) | ||
.set('api-key', config.apiKey) | ||
.set('Content-Type', 'application/json') | ||
.send(data) | ||
return body as T | ||
} | ||
|
||
const getTemplateId = async (commonName: string) => { | ||
const { templates } = await doGet<RelevantGetTemplatesResult>( | ||
'smtp/templates' | ||
) | ||
const relevantTemplate = templates.find( | ||
template => template.name === commonName | ||
) | ||
|
||
if (!relevantTemplate) { | ||
console.error( | ||
`Brevo notifications: no template found for event '${commonName}'` | ||
) | ||
return -1 | ||
} | ||
|
||
return relevantTemplate.id | ||
} | ||
|
||
const send = async ( | ||
to: Identity, | ||
templateCommonName: TemplateName, | ||
params: Record<string, string> | ||
) => { | ||
const templateId = await getTemplateId(templateCommonName) | ||
|
||
if (templateId === -1) { | ||
return | ||
} | ||
|
||
await doPost<SendMailPostRequestBody>('smtp/email', { | ||
sender: config.from, | ||
to: [to], | ||
templateId, | ||
params, | ||
}) | ||
} | ||
|
||
return { | ||
getTemplateId, | ||
send, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { getEnv } from '@helsingborg-stad/gdi-api-node' | ||
import type { NotificationService } from '../types' | ||
import type { Advert } from '../../adverts/types' | ||
import { createClient } from './brevo-client' | ||
import type { BrevoConfig } from './types' | ||
|
||
export const createBrevoNotifications = ( | ||
config: BrevoConfig | ||
): NotificationService => { | ||
const client = createClient(config) | ||
|
||
const stripAdvert = (advert: Advert): Partial<Advert> => ({ | ||
...advert, | ||
images: undefined, | ||
claims: undefined, | ||
}) | ||
|
||
return { | ||
pincodeRequested: (email, pincode) => | ||
client.send({ name: email, email }, 'pincode-requested', { | ||
email, | ||
pincode, | ||
}), | ||
|
||
advertWasReserved: (by, quantity, advert) => | ||
client.send({ name: by.id, email: by.id }, 'advert-was-reserved', { | ||
quantity, | ||
advert: stripAdvert(advert), | ||
}), | ||
|
||
advertReservationWasCancelled: (by, quantity, advert) => | ||
client.send( | ||
{ name: by.id, email: by.id }, | ||
'advert-reservation-was-cancelled', | ||
{ | ||
quantity, | ||
advert: stripAdvert(advert), | ||
} | ||
), | ||
|
||
advertWasCollected: (by, quantity, advert) => | ||
client.send({ name: by.id, email: by.id }, 'advert-was-collected', { | ||
quantity, | ||
advert: stripAdvert(advert), | ||
}), | ||
} | ||
} | ||
|
||
export const tryCreateBrevoNotificationsFromEnv = | ||
(): NotificationService | null => { | ||
const apiKey = getEnv('BREVO_API_KEY', { fallback: '' }) | ||
const fromName = getEnv('BREVO_FROM_NAME', { fallback: '' }) | ||
const fromEmail = getEnv('BREVO_FROM_EMAIL', { fallback: '' }) | ||
return apiKey && fromName && fromEmail | ||
? createBrevoNotifications({ | ||
apiKey, | ||
from: { name: fromName, email: fromEmail }, | ||
}) | ||
: null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Brevo notifications | ||
|
||
Notifications are sent via the transactional mail service [www.brevo.com](https://www.brevo.com/) when environment contains: | ||
|
||
```sh | ||
BREVO_API_KEY=<api key> | ||
BREVO_FROM_NAME=<sender name> | ||
BREVO_FROM_EMAIL=<sender email> | ||
``` | ||
|
||
Templates must be named `pincode-requested`, `advert-was-reserved` etc. according | ||
to the common name of the notification event. See [types.ts](types.ts) for more details. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
export type TemplateName = | ||
| 'pincode-requested' | ||
| 'advert-was-reserved' | ||
| 'advert-reservation-was-cancelled' | ||
| 'advert-was-collected' | ||
|
||
export interface Identity { | ||
name: string | ||
email: string | ||
} | ||
|
||
export interface BrevoConfig { | ||
apiKey: string | ||
from: Identity | ||
} | ||
|
||
export interface BrevoClient { | ||
getTemplateId(commonName: TemplateName): Promise<number> | ||
send( | ||
to: Identity, | ||
templateCommonName: TemplateName, | ||
params: Record<string, unknown> | ||
): Promise<void> | ||
} | ||
|
||
export interface RelevantGetTemplatesResult { | ||
templates: { | ||
id: number | ||
name: string | ||
}[] | ||
} | ||
|
||
export interface SendMailPostRequestBody { | ||
sender: { | ||
name: string | ||
email: string | ||
} | ||
|
||
to: [ | ||
{ | ||
name: string | ||
email: string | ||
} | ||
] | ||
|
||
templateId: number | ||
|
||
params: Record<string, string> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
import { tryCreateBrevoNotificationsFromEnv } from './brevo/brevo-notifications' | ||
import { createConsoleNotificationService } from './console-notifications' | ||
import { tryCreateSendGridNofificationsFromEnv } from './sendgrid' | ||
import type { NotificationService } from './types' | ||
|
||
export const createNotificationServiceFromEnv = (): NotificationService => | ||
tryCreateSendGridNofificationsFromEnv() || createConsoleNotificationService() | ||
export const createNotificationServiceFromEnv = (): NotificationService => | ||
tryCreateSendGridNofificationsFromEnv() || | ||
tryCreateBrevoNotificationsFromEnv() || | ||
createConsoleNotificationService() | ||
|
||
export const createNullNotificationService = (): NotificationService => ({ | ||
pincodeRequested: async () => undefined, | ||
advertWasReserved: async () => undefined, | ||
advertReservationWasCancelled: async () => undefined, | ||
advertWasCollected: async () => undefined | ||
pincodeRequested: async () => undefined, | ||
advertWasReserved: async () => undefined, | ||
advertReservationWasCancelled: async () => undefined, | ||
advertWasCollected: async () => undefined, | ||
}) |