diff --git a/apps/contact/helpers/notion.ts b/apps/contact/helpers/notion.ts index 51fa3074..31a27f2d 100644 --- a/apps/contact/helpers/notion.ts +++ b/apps/contact/helpers/notion.ts @@ -1,5 +1,5 @@ import { Client, isFullPage } from "@notionhq/client"; -import { notifyContactCreated } from "./slack"; +import { notifyContactError, notifyContactCreated } from "./slack"; const { NOTION_TOKEN, MENTION_EMAILS, MENTION_IDS } = process.env; @@ -116,21 +116,36 @@ const createContact = async ( databaseID: string, source: string, ) => { - const response = await notion.pages.create( - createContactObject(id, email, name, content, databaseID, source), - ); + try { + const response = await notion.pages.create( + createContactObject(id, email, name, content, databaseID, source), + ); - if (response.id && isFullPage(response)) { + // isFullPage checks if the response is type PageObjectResponse => contains url + if (response.id && isFullPage(response)) { + return { + id: response.id, + url: response.url, + }; + // In case the page is created but the response is type PartialPageObjectResponse => doesn't contain url + } else if (response.id && !isFullPage(response)) { + // Notion allows navigation to the created page using only the id without '-' + // https://dev.to/adamcoster/change-a-url-without-breaking-existing-links-4m0d + const cleanId = response.id.replace(/-/g, ""); + const pageUrl = `https://www.notion.so/${cleanId}`; + return { + id: response.id, + url: pageUrl, + }; + } + return { + error: "Failed to create notion page", + }; + } catch (e) { return { - id: response.id, - url: response.url, + error: "Failed to create notion page", }; } - throw { - body: { - message: "Failed to create notion page", - }, - }; }; export const processContact = async (event: { @@ -152,7 +167,11 @@ export const processContact = async (event: { }; } - const { id: notionPageID, url } = await createContact( + const { + id: notionPageID, + url, + error: errorMessage, + } = await createContact( `Message from ${name} (${id})`, email, name, @@ -161,6 +180,17 @@ export const processContact = async (event: { source, ); - await notifyContactCreated(name, email, url); + if (errorMessage) { + await notifyContactError(name, email, message); + throw { + body: { + message: errorMessage, + }, + }; + } + + if (url) { + await notifyContactCreated(name, email, url); + } return notionPageID; }; diff --git a/apps/contact/helpers/slack.ts b/apps/contact/helpers/slack.ts index 8114d6d9..a1fcdffc 100644 --- a/apps/contact/helpers/slack.ts +++ b/apps/contact/helpers/slack.ts @@ -42,6 +42,35 @@ export const createPayload = (name: string, email: string, url: string) => ({ ], }); +export const createErrorPayload = ( + name: string, + email: string, + content: string, +) => ({ + channel: SLACK_CHANNEL, + blocks: [ + { + type: "header", + text: { + type: "plain_text", + text: "An error ocured while creating a contact", + emoji: true, + }, + }, + { + type: "section", + text: { + type: "mrkdwn", + text: `There was an error trying to create a contact for _${name}_ (_${email}_).`, + }, + }, + { + type: "section", + text: content, + }, + ], +}); + export const notifyContactCreated = async ( name: string, email: string, @@ -71,3 +100,33 @@ export const notifyContactCreated = async ( } } }; + +export const notifyContactError = async ( + name: string, + email: string, + content: string, +) => { + const payload = createErrorPayload(name, email, content); + const payloadStringify = JSON.stringify(payload); + + if (IS_OFFLINE) { + console.log(payload); + } else { + const result = await fetch("https://slack.com/api/chat.postMessage", { + method: "POST", + body: payloadStringify, + headers: { + "Content-Type": "application/json; charset=utf-8", + "Content-Length": payloadStringify.length.toString(), + Authorization: `Bearer ${SLACK_BOT_TOKEN}`, + Accept: "application/json", + }, + }); + if (result.status !== 200) { + throw { + body: "Could not send notification message to Slack", + statusCode: result.status, + }; + } + } +};