2
0

🧑‍💻 (emails) Add decent emails management

Use mjml-react to generate emails. Put all emails in a independent package.
This commit is contained in:
Baptiste Arnaud
2022-10-01 07:00:05 +02:00
parent e1f2d49342
commit 1654de3c1f
50 changed files with 4811 additions and 4048 deletions

View File

@ -1,37 +0,0 @@
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="Helvetica Neue, Helvetica, Helvetica, Arial, sans-serif" font-size="16px" padding="0" line-height="23px"></mj-all>
<mj-section background-color="#ffffff" padding-bottom="20px"></mj-section>
<mj-text padding="10px 40px"></mj-text>
</mj-attributes>
<mj-style inline="inline">
.footer-link {
color: #A0AEC0
}
</mj-style>
</mj-head>
<mj-body background-color="#ffffff">
<mj-wrapper border="1px solid #E2E8F0">
<mj-section padding-bottom="0px">
<mj-column width="100%">
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/invitation-banner.png" alt="header image" padding="0px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>You have been invited by ${hostEmail} to collaborate on his typebot <strong>${typebotName}</strong></mj-text>
<mj-text>From now on you will see this typebot in your dashboard under the his workspace "${workspaceName}" 👍</mj-text>
<mj-text>Make sure to log in as ${guestEmail}</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#0042da" color="white" href="${url}" font-weight="500" border-radius="5px">Go to typebot</mj-button>
</mj-column>
</mj-section>
</mj-wrapper>
</mj-body>
</mjml>

File diff suppressed because one or more lines are too long

View File

@ -1,97 +0,0 @@
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="Helvetica Neue, Helvetica, Helvetica, Arial, sans-serif" font-size="16px" padding="0" line-height="23px"></mj-all>
<mj-section background-color="#ffffff" padding-bottom="20px"></mj-section>
<mj-text padding="10px 40px"></mj-text>
</mj-attributes>
<mj-style inline="inline">
.footer-link {
color: #A0AEC0
}
</mj-style>
</mj-head>
<mj-body background-color="#ffffff">
<mj-wrapper border="1px solid #E2E8F0">
<mj-section padding-bottom="0px">
<mj-column width="100%">
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/typebot2-banner.png" alt="header image" padding="0px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>Hey 👋</mj-text>
<mj-text>Im super excited to announce that Typebot 2.0 is finally available after 3 months of deep work. </mj-text>
<mj-text>It comes with a brand new building experience and it has been implemented from the ground up with “Freedom” in mind, allowing you to create truly customized conversational applications.</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/newsletter-builder.gif"></mj-image>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-text>Typebot 2.0 also comes with new advanced features, including:</mj-text>
<mj-text>- Data fetching from a Google Sheet</mj-text>
<mj-text>- Custom emails</mj-text>
<mj-text>- Custom CSS</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-text>Typebot still allows you to create unique conversational experiences for your user. This leads to:</mj-text>
<mj-text>😍 An increase in customer satisfaction and retention.</mj-text>
<mj-text>🚀 A 3x conversion increase on average on your lead qualification forms.</mj-text>
<mj-text font-weight="bold">And it still comes with a generous unlimited free plan 💙</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#0042da" color="white" href="https://app.typebot.io/register" font-weight="500" border-radius="5px">Try it out</mj-button>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>Im inviting you to join our Facebook community where youll get updates on the product.</mj-text>
<mj-text>Its also a place where we share our metrics and forms templates 💪</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#ffffff" color="#0042da" border="1px solid #0042da" href="https://app.typebot.io/register" font-weight="500" border-radius="5px">Join the community</mj-button>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-image width="500px" src="https://typebot.s3.eu-west-3.amazonaws.com/assets/facebook-post2.jpeg" border-radius="5px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>If you have any question, just hit "reply"! I'm super approachable 😁. Look, here is a selfie 👇</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/selfie-newsletter.jpeg" width="300px" border-radius="5px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text padding-bottom="0px">Baptiste,</mj-text>
<mj-text padding-top="0px">Founder of Typebot.</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-text font-size="13px" text-decoration="underline">
<a class="footer-link" href="%unsubscribe_url%" color="#fffff">Unsubscribe from all future emails</a>
</mj-text>
</mj-column>
</mj-section>
</mj-wrapper>
</mj-body>
</mjml>

View File

@ -1,50 +0,0 @@
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="Helvetica Neue, Helvetica, Helvetica, Arial, sans-serif" font-size="16px" padding="0" line-height="23px"></mj-all>
<mj-section background-color="#ffffff" padding-bottom="20px"></mj-section>
<mj-text padding="10px 40px"></mj-text>
</mj-attributes>
<mj-style inline="inline">
.footer-link {
color: #A0AEC0
}
</mj-style>
</mj-head>
<mj-body background-color="#ffffff">
<mj-wrapper border="1px solid #E2E8F0">
<mj-section padding-bottom="0px">
<mj-column width="100%">
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/typebot2-banner.png" alt="header image" padding="0px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>You receive this email because you are the owner of a {{PLAN}} plan on Typebot. Which means you can keep all your perks on Typebot 2.0 as well 😍</mj-text>
<mj-text>All you have to do is to Create your new account by clicking on the button below.</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#0042da" color="white" href="https://app.typebot.io/register" font-weight="500" border-radius="5px">Create my account</mj-button>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>Your plan should automatically be applied. If you have any issue, hit reply 😃</mj-text>
<mj-text>I'm eagerly waiting for your feedback! Let's make this tool amazing.</mj-text>
<mj-text padding-bottom="0px">Baptiste,</mj-text>
<mj-text padding-top="0px">Founder of Typebot.</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-text font-size="13px" text-decoration="underline">
<a class="footer-link" href="%unsubscribe_url%" color="#fffff">Unsubscribe from all future emails</a>
</mj-text>
</mj-column>
</mj-section>
</mj-wrapper>
</mj-body>
</mjml>

View File

@ -1,37 +0,0 @@
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="Helvetica Neue, Helvetica, Helvetica, Arial, sans-serif" font-size="16px" padding="0" line-height="23px"></mj-all>
<mj-section background-color="#ffffff" padding-bottom="20px"></mj-section>
<mj-text padding="10px 40px"></mj-text>
</mj-attributes>
<mj-style inline="inline">
.footer-link {
color: #A0AEC0
}
</mj-style>
</mj-head>
<mj-body background-color="#ffffff">
<mj-wrapper border="1px solid #E2E8F0">
<mj-section padding-bottom="0px">
<mj-column width="100%">
<mj-image src="https://typebot.s3.eu-west-3.amazonaws.com/assets/invitation-banner.png" alt="header image" padding="0px"></mj-image>
</mj-column>
</mj-section>
<mj-section padding-top="20px">
<mj-column>
<mj-text>You have been invited by ${hostEmail} to collaborate on his workspace "${workspaceName}" as a team member.</mj-text>
<mj-text>From now on you will have access to this workspace in your dashboard 👍</mj-text>
<mj-text>Make sure to log in as ${guestEmail}</mj-text>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-button background-color="#0042da" color="white" href="${url}" font-weight="500" border-radius="5px">Go the workspace</mj-button>
</mj-column>
</mj-section>
</mj-wrapper>
</mj-body>
</mjml>

View File

@ -1,536 +0,0 @@
type Props = {
workspaceName: string
url: string,
hostEmail: string,
guestEmail: string
}
export const workspaceMemberInvitationEmail = ({workspaceName, url, hostEmail, guestEmail}: Props) => `<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
>
<head>
<title></title>
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style type="text/css">
#outlook a {
padding: 0;
}
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
p {
display: block;
margin: 13px 0;
}
</style>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<!--[if lte mso 11]>
<style type="text/css">
.mj-outlook-group-fix {
width: 100% !important;
}
</style>
<![endif]-->
<style type="text/css">
@media only screen and (min-width: 480px) {
.mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
}
</style>
<style media="screen and (min-width:480px)">
.moz-text-html .mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
</style>
<style type="text/css">
@media only screen and (max-width: 480px) {
table.mj-full-width-mobile {
width: 100% !important;
}
td.mj-full-width-mobile {
width: auto !important;
}
}
</style>
</head>
<body style="word-spacing: normal; background-color: #ffffff">
<div style="background-color: #ffffff">
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div style="margin: 0px auto; max-width: 600px">
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="width: 100%"
>
<tbody>
<tr>
<td
style="
border: 1px solid #e2e8f0;
direction: ltr;
font-size: 0px;
padding: 0;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:598px;" width="598" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 598px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 0;
padding-bottom: 0px;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:598px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td style="vertical-align: top; padding: 0">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td style="width: 598px">
<img
alt="header image"
height="auto"
src="https://typebot.s3.eu-west-3.amazonaws.com/assets/invitation-banner.png"
style="
border: 0;
display: block;
outline: none;
text-decoration: none;
height: auto;
width: 100%;
font-size: 16px;
"
width="598"
/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:598px;" width="598" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 598px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 0;
padding-bottom: 20px;
padding-top: 20px;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:598px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td style="vertical-align: top; padding: 0">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 40px;
word-break: break-word;
"
>
<div
style="
font-family: Helvetica Neue,
Helvetica, Helvetica, Arial,
sans-serif;
font-size: 16px;
line-height: 23px;
text-align: left;
color: #000000;
"
>
You have been invited by
${hostEmail} to collaborate on his
workspace "${workspaceName}" as a
team member.
</div>
</td>
</tr>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 40px;
word-break: break-word;
"
>
<div
style="
font-family: Helvetica Neue,
Helvetica, Helvetica, Arial,
sans-serif;
font-size: 16px;
line-height: 23px;
text-align: left;
color: #000000;
"
>
From now on you will have access
to this workspace in your
dashboard üëç
</div>
</td>
</tr>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 40px;
word-break: break-word;
"
>
<div
style="
font-family: Helvetica Neue,
Helvetica, Helvetica, Arial,
sans-serif;
font-size: 16px;
line-height: 23px;
text-align: left;
color: #000000;
"
>
Make sure to log in as
${guestEmail}
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table></td></tr><tr><td class="" width="600px" ><table align="center" border="0" cellpadding="0" cellspacing="0" class="" role="presentation" style="width:598px;" width="598" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 598px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #ffffff;
background-color: #ffffff;
width: 100%;
"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 0;
padding-bottom: 20px;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:598px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td style="vertical-align: top; padding: 0">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
width="100%"
>
<tbody>
<tr>
<td
align="center"
vertical-align="middle"
style="
font-size: 0px;
padding: 0;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: separate;
line-height: 100%;
"
>
<tbody>
<tr>
<td
align="center"
bgcolor="#0042da"
role="presentation"
style="
border: none;
border-radius: 5px;
cursor: auto;
mso-padding-alt: 10px 25px;
background: #0042da;
"
valign="middle"
>
<a
href="${url}"
style="
display: inline-block;
background: #0042da;
color: white;
font-family: Helvetica
Neue,
Helvetica, Helvetica,
Arial, sans-serif;
font-size: 16px;
font-weight: 500;
line-height: 23px;
margin: 0;
text-decoration: none;
text-transform: none;
padding: 10px 25px;
mso-padding-alt: 0px;
border-radius: 5px;
"
target="_blank"
>Go the workspace</a
>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</div>
</body>
</html>
`

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const { withSentryConfig } = require('@sentry/nextjs')
const path = require('path')
const withTM = require('next-transpile-modules')(['utils', 'models'])
const withTM = require('next-transpile-modules')(['utils', 'models', 'emails'])
/** @type {import('next').NextConfig} */
const nextConfig = {

View File

@ -62,7 +62,7 @@
"minio": "7.0.32",
"next": "12.3.0",
"next-auth": "4.10.3",
"nodemailer": "^6.7.8",
"nodemailer": "^6.8.0",
"nprogress": "^0.2.0",
"papaparse": "^5.3.2",
"prettier": "2.7.1",
@ -80,7 +80,9 @@
"swr": "^1.3.0",
"tinycolor2": "^1.4.2",
"typebot-js": "workspace:*",
"use-debounce": "8.0.4"
"use-debounce": "8.0.4",
"emails": "workspace:*",
"@faire/mjml-react": "^2.1.4"
},
"devDependencies": {
"@babel/core": "7.19.0",

View File

@ -1,37 +1,22 @@
/* eslint-disable @next/next/no-sync-scripts */
import Document, {
Html,
Head,
Main,
NextScript,
DocumentContext,
} from 'next/document'
import { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
static async getInitialProps(ctx: DocumentContext) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}
const Document = () => (
<Html>
<Head>
<link rel="icon" type="image/png" href="/favicon.png" />
<link
href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Open+Sans:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<meta name="google" content="notranslate" />
<script src="/__env.js" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
render() {
return (
<Html>
<Head>
<link rel="icon" type="image/png" href="/favicon.png" />
<link
href="https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600;700&family=Open+Sans:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<meta name="google" content="notranslate" />
<script src="/__env.js" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument
export default Document

View File

@ -87,8 +87,8 @@ export function CustomAdapter(p: PrismaClient): Adapter {
},
updateUser: (data) => p.user.update({ where: { id: data.id }, data }),
deleteUser: (id) => p.user.delete({ where: { id } }),
linkAccount: (data) => {
return p.account.create({
linkAccount: async (data) => {
await p.account.create({
data: {
userId: data.userId,
type: data.type,
@ -105,10 +105,11 @@ export function CustomAdapter(p: PrismaClient): Adapter {
oauth_token: data.oauth_token as string,
refresh_token_expires_in: data.refresh_token_expires_in as number,
},
}) as any
})
},
unlinkAccount: async (provider_providerAccountId) => {
await p.account.delete({ where: { provider_providerAccountId } })
},
unlinkAccount: (provider_providerAccountId) =>
p.account.delete({ where: { provider_providerAccountId } }) as any,
async getSessionAndUser(sessionToken) {
const userAndSession = await p.session.findUnique({
where: { sessionToken },

View File

@ -1,11 +1,9 @@
import { withSentry } from '@sentry/nextjs'
import { invitationToCollaborate } from 'assets/emails/invitationToCollaborate'
import { CollaborationType, WorkspaceRole } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
import { canReadTypebot, canWriteTypebot } from 'services/api/dbRules'
import {
sendEmailNotification,
badRequest,
forbidden,
methodNotAllowed,
@ -13,6 +11,7 @@ import {
} from 'utils/api'
import { getAuthenticatedUser } from 'services/api/utils'
import { env } from 'utils'
import { sendGuestInvitationEmail } from 'emails'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
@ -68,16 +67,13 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
data: { email: email.toLowerCase().trim(), type, typebotId },
})
if (env('E2E_TEST') !== 'true')
await sendEmailNotification({
await sendGuestInvitationEmail({
to: email,
subject: "You've been invited to collaborate 🤝",
html: invitationToCollaborate({
hostEmail: user.email ?? '',
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${typebot.workspaceId}`,
guestEmail: email.toLowerCase(),
typebotName: typebot.name,
workspaceName: typebot.workspace?.name ?? '',
}),
hostEmail: user.email ?? '',
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${typebot.workspaceId}`,
guestEmail: email.toLowerCase(),
typebotName: typebot.name,
workspaceName: typebot.workspace?.name ?? '',
})
return res.send({
message: 'success',

View File

@ -1,16 +1,11 @@
import { withSentry } from '@sentry/nextjs'
import { workspaceMemberInvitationEmail } from 'assets/emails/workspaceMemberInvitation'
import { Workspace, WorkspaceInvitation, WorkspaceRole } from 'db'
import prisma from 'libs/prisma'
import { NextApiRequest, NextApiResponse } from 'next'
import {
sendEmailNotification,
forbidden,
methodNotAllowed,
notAuthenticated,
} from 'utils/api'
import { forbidden, methodNotAllowed, notAuthenticated } from 'utils/api'
import { getAuthenticatedUser } from 'services/api/utils'
import { env, seatsLimit } from 'utils'
import { sendWorkspaceMemberInvitationEmail } from 'emails'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const user = await getAuthenticatedUser(req)
@ -39,15 +34,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
},
})
if (env('E2E_TEST') !== 'true')
await sendEmailNotification({
await sendWorkspaceMemberInvitationEmail({
to: data.email,
subject: "You've been invited to collaborate 🤝",
html: workspaceMemberInvitationEmail({
workspaceName: workspace.name,
guestEmail: data.email,
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspace.id}`,
hostEmail: user.email ?? '',
}),
workspaceName: workspace.name,
guestEmail: data.email,
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspace.id}`,
hostEmail: user.email ?? '',
})
return res.send({
member: {
@ -61,15 +53,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
} else {
const invitation = await prisma.workspaceInvitation.create({ data })
if (env('E2E_TEST') !== 'true')
await sendEmailNotification({
await sendWorkspaceMemberInvitationEmail({
to: data.email,
subject: "You've been invited to collaborate 🤝",
html: workspaceMemberInvitationEmail({
workspaceName: workspace.name,
guestEmail: data.email,
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspace.id}`,
hostEmail: user.email ?? '',
}),
workspaceName: workspace.name,
guestEmail: data.email,
url: `${process.env.NEXTAUTH_URL}/typebots?workspaceId=${workspace.id}`,
hostEmail: user.email ?? '',
})
return res.send({ invitation })
}