-
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.
[MS-754] feat: Imporove logging. WIP logic for sending emails
- Loading branch information
1 parent
6ba5e8d
commit f30002c
Showing
12 changed files
with
165 additions
and
66 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
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 |
---|---|---|
@@ -1,11 +1,35 @@ | ||
// TODO: Mails sender serverless | ||
import { type Context, type SQSBatchResponse, type SQSEvent } from "aws-lambda"; | ||
import { | ||
type Context, | ||
type SQSBatchResponse, | ||
type SQSEvent, | ||
type SQSRecord, | ||
} from "aws-lambda"; | ||
|
||
import { CONFIG } from "@/config"; | ||
import { EmailParsePayloadError } from "@/lib/emails/errors"; | ||
import { getEmailProvider } from "@/providers/email"; | ||
import { logger } from "@/providers/logger"; | ||
import { getLogger } from "@/providers/logger"; | ||
import { OrderCreatedEmail } from "@/templates/OrderCreatedEmail"; | ||
|
||
import { OrderCreatedEmail } from "./templates/OrderCreatedEmail"; | ||
import { type WebhookEventTypeAsyncEnum } from "./graphql/schema"; | ||
import { type SerializedPayload } from "./lib/emails/events/helpers"; | ||
import { getJSONFormatHeader } from "./lib/saleor/apps/utils"; | ||
|
||
export const logger = getLogger("emails-sender"); | ||
|
||
const parseRecord = (record: SQSRecord) => { | ||
try { | ||
// FIXME: Proxy events has invalid format? Test with real data & localstack. | ||
const data = JSON.parse((record as any).Body); | ||
return data as SerializedPayload; | ||
} catch (error) { | ||
logger.error("Failed to parse record payload.", { record, error }); | ||
|
||
throw new EmailParsePayloadError("Failed to parse record payload.", { | ||
cause: { source: error as Error }, | ||
}); | ||
} | ||
}; | ||
|
||
export const handler = async (event: SQSEvent, context: Context) => { | ||
const failures: string[] = []; | ||
|
@@ -16,23 +40,46 @@ export const handler = async (event: SQSEvent, context: Context) => { | |
/** | ||
* Process event | ||
*/ | ||
logger.info({ message: "Processing record", record }); | ||
logger.debug("Processing record", { record }); | ||
|
||
const sender = getEmailProvider({ | ||
fromEmail: `piotr.grundas+${CONFIG.NAME}@mirumee.com`, | ||
from: CONFIG.RELEASE, | ||
toEmail: "[email protected]", | ||
}); | ||
const { format, payload } = parseRecord(record); | ||
|
||
const html = await sender.render({ | ||
props: {}, | ||
template: OrderCreatedEmail, | ||
}); | ||
if (format === getJSONFormatHeader({ name: CONFIG.NAME })) { | ||
const TEMPLATES_MAP: { | ||
[key in Lowercase<WebhookEventTypeAsyncEnum>]?: any; | ||
} = { | ||
order_created: OrderCreatedEmail, | ||
}; | ||
const template = TEMPLATES_MAP[payload.event]; | ||
|
||
await sender.send({ | ||
html, | ||
subject: "Order created", | ||
}); | ||
if (!template) { | ||
return logger.warn("Received payload with unhandled template.", { | ||
format, | ||
payload, | ||
}); | ||
} | ||
|
||
const sender = getEmailProvider({ | ||
fromEmail: `piotr.grundas+${CONFIG.NAME}@mirumee.com`, | ||
from: CONFIG.RELEASE, | ||
toEmail: "[email protected]", | ||
}); | ||
|
||
const html = await sender.render({ | ||
props: {}, | ||
template: OrderCreatedEmail, | ||
}); | ||
|
||
await sender.send({ | ||
html, | ||
subject: "Order created", | ||
}); | ||
} else { | ||
return logger.warn("Received payload with unsupported format.", { | ||
format, | ||
payload, | ||
}); | ||
} | ||
} | ||
|
||
if (failures.length) { | ||
|
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,5 @@ | ||
import { BaseError } from "@/lib/errors"; | ||
|
||
export class EmailSendError extends BaseError {} | ||
|
||
export class EmailParsePayloadError extends BaseError {} |
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,21 @@ | ||
import { type FastifyRequest } from "fastify"; | ||
|
||
import { CONFIG } from "@/config"; | ||
import { type WebhookEventTypeAsyncEnum } from "@/graphql/schema"; | ||
import { getJSONFormatHeader } from "@/lib/saleor/apps/utils"; | ||
|
||
export const serializePayload = ({ | ||
data, | ||
event, | ||
}: { | ||
data: FastifyRequest["body"]; | ||
event: Lowercase<WebhookEventTypeAsyncEnum>; | ||
}) => ({ | ||
format: getJSONFormatHeader({ name: CONFIG.NAME }), | ||
payload: { | ||
event, | ||
data, | ||
}, | ||
}); | ||
|
||
export type SerializedPayload = ReturnType<typeof serializePayload>; |
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
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 |
---|---|---|
@@ -1,7 +1,8 @@ | ||
import { CONFIG } from "@/config"; | ||
import { createLogger } from "@/lib/plugins/winstonLoggingPlugin"; | ||
|
||
export const logger = createLogger({ | ||
environment: CONFIG.ENVIRONMENT, | ||
service: CONFIG.RELEASE, | ||
}); | ||
export const getLogger = (service: "emails-sender" | "events-receiver") => | ||
createLogger({ | ||
environment: CONFIG.ENVIRONMENT, | ||
service: `${CONFIG.NAME}/${service}@${CONFIG.VERSION}`, | ||
}); |
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