Skip to content

Commit

Permalink
feat(viewer): 🐛 Fix multiple cc bcc email
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Apr 12, 2022
1 parent b6ba40e commit 7b8169c
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 5 deletions.
14 changes: 9 additions & 5 deletions apps/viewer/pages/api/integrations/email.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import prisma from 'libs/prisma'
import { SendEmailOptions, SmtpCredentialsData } from 'models'
import { NextApiRequest, NextApiResponse } from 'next'
import { createTransport } from 'nodemailer'
import { createTransport, getTestMessageUrl } from 'nodemailer'
import { decrypt, initMiddleware } from 'utils'

import Cors from 'cors'
Expand Down Expand Up @@ -47,15 +47,19 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
})
const info = await transporter.sendMail({
from: `"${from.name}" <${from.email}>`,
cc: cc?.join(''),
bcc: bcc?.join(''),
to: recipients.join(', '),
cc,
bcc,
to: recipients,
replyTo,
subject,
text: body,
})

res.status(200).send({ message: 'Email sent!', info })
res.status(200).send({
message: 'Email sent!',
info,
previewUrl: getTestMessageUrl(info),
})
}
}

Expand Down
122 changes: 122 additions & 0 deletions apps/viewer/playwright/fixtures/typebots/sendEmail.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"id": "cl1rxxg6l334509lhv44f8qnx",
"createdAt": "2022-04-09T14:16:43.053Z",
"updatedAt": "2022-04-12T14:34:44.287Z",
"icon": null,
"name": "My typebot",
"ownerId": "ckzmhmiey001009mnzt5nkxu8",
"publishedTypebotId": null,
"folderId": null,
"blocks": [
{
"id": "cl1rxxg6k000009lhd0mgfy5i",
"steps": [
{
"id": "cl1rxxg6k000109lh2is0gfua",
"type": "start",
"label": "Start",
"blockId": "cl1rxxg6k000009lhd0mgfy5i",
"outgoingEdgeId": "cl1w8rhzs000f2e694836a1k3"
}
],
"title": "Start",
"graphCoordinates": { "x": 0, "y": 0 }
},
{
"id": "cl1w8repd000b2e69fwiqsd00",
"graphCoordinates": { "x": 364, "y": -2 },
"title": "Group #1",
"steps": [
{
"id": "cl1w8repg000c2e699jqwrepg",
"blockId": "cl1w8repd000b2e69fwiqsd00",
"type": "choice input",
"options": { "buttonLabel": "Send", "isMultipleChoice": false },
"items": [
{
"id": "cl1w8repg000d2e69d8xnkqeq",
"stepId": "cl1w8repg000c2e699jqwrepg",
"type": 0,
"content": "Send email",
"outgoingEdgeId": "cl1w8rkoo000i2e69hs60pk0q"
}
]
}
]
},
{
"id": "cl1w8rjaf000g2e69cqd2bwvk",
"graphCoordinates": { "x": 715, "y": -10 },
"title": "Group #2",
"steps": [
{
"id": "cl1w8rjai000h2e695uvoimq7",
"blockId": "cl1w8rjaf000g2e69cqd2bwvk",
"type": "Email",
"options": {
"credentialsId": "send-email-credentials",
"recipients": ["baptiste.arnaud95@gmail.com"],
"replyTo": "contact@baptiste-arnaud.fr",
"cc": ["test1@gmail.com", "test2@gmail.com"],
"bcc": ["test3@gmail.com", "test4@gmail.com"],
"subject": "Hey!",
"body": "Test email"
}
}
]
}
],
"variables": [
{ "id": "vcl1rxxovn000z2e69y6t9dxge", "name": "Score" },
{ "id": "vcl1rylq5v00042e69tdml6hi3", "name": "Age" }
],
"edges": [
{
"from": {
"blockId": "cl1rxxg6k000009lhd0mgfy5i",
"stepId": "cl1rxxg6k000109lh2is0gfua"
},
"to": { "blockId": "cl1w8repd000b2e69fwiqsd00" },
"id": "cl1w8rhzs000f2e694836a1k3"
},
{
"from": {
"blockId": "cl1w8repd000b2e69fwiqsd00",
"stepId": "cl1w8repg000c2e699jqwrepg",
"itemId": "cl1w8repg000d2e69d8xnkqeq"
},
"to": { "blockId": "cl1w8rjaf000g2e69cqd2bwvk" },
"id": "cl1w8rkoo000i2e69hs60pk0q"
}
],
"theme": {
"chat": {
"inputs": {
"color": "#303235",
"backgroundColor": "#FFFFFF",
"placeholderColor": "#9095A0"
},
"buttons": { "color": "#FFFFFF", "backgroundColor": "#0042DA" },
"hostAvatar": {
"url": "https://avatars.githubusercontent.com/u/16015833?v=4",
"isEnabled": true
},
"hostBubbles": { "color": "#303235", "backgroundColor": "#F7F8FF" },
"guestBubbles": { "color": "#FFFFFF", "backgroundColor": "#FF8E21" }
},
"general": { "font": "Open Sans", "background": { "type": "None" } }
},
"settings": {
"general": {
"isBrandingEnabled": true,
"isInputPrefillEnabled": true,
"isNewResultOnRefreshEnabled": false
},
"metadata": {
"description": "Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form."
},
"typingEmulation": { "speed": 300, "enabled": true, "maxDelay": 1.5 }
},
"publicId": null,
"customDomain": null
}
20 changes: 20 additions & 0 deletions apps/viewer/playwright/services/database.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {
CredentialsType,
defaultSettings,
defaultTheme,
PublicTypebot,
SmtpCredentialsData,
Step,
Typebot,
} from 'models'
import { PrismaClient } from 'db'
import { readFileSync } from 'fs'
import { encrypt } from 'utils'

const prisma = new PrismaClient()

Expand Down Expand Up @@ -184,3 +187,20 @@ const createAnswers = () => {
],
})
}

export const createSmtpCredentials = (
id: string,
smtpData: SmtpCredentialsData
) => {
const { encryptedData, iv } = encrypt(smtpData)
return prisma.credentials.create({
data: {
id,
data: encryptedData,
iv,
name: smtpData.from.email as string,
type: CredentialsType.SMTP,
ownerId: 'proUser',
},
})
}
45 changes: 45 additions & 0 deletions apps/viewer/playwright/tests/sendEmail.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import test, { expect } from '@playwright/test'
import {
createSmtpCredentials,
importTypebotInDatabase,
} from '../services/database'
import cuid from 'cuid'
import path from 'path'
import { typebotViewer } from '../services/selectorUtils'
import { SmtpCredentialsData } from 'models'

const mockSmtpCredentials: SmtpCredentialsData = {
from: {
email: 'tobin.tillman65@ethereal.email',
name: 'John Smith',
},
host: 'smtp.ethereal.email',
port: 587,
isTlsEnabled: false,
username: 'tobin.tillman65@ethereal.email',
password: 'Ty9BcwCBrK6w8AG2hx',
}

test('should send an email', async ({ page }) => {
const typebotId = cuid()
const credentialsId = 'send-email-credentials'
await createSmtpCredentials(credentialsId, mockSmtpCredentials)
await importTypebotInDatabase(
path.join(__dirname, '../fixtures/typebots/sendEmail.json'),
{ id: typebotId, publicId: `${typebotId}-public` }
)
await page.goto(`/${typebotId}-public`)
await typebotViewer(page).locator('text=Send email').click()
const response = await page.waitForResponse((resp) =>
resp.request().url().includes(`/api/integrations/email`)
)
const { previewUrl } = await response.json()
await page.goto(previewUrl)
await expect(page.locator('text="Hey!"')).toBeVisible()
await expect(page.locator('text="John Smith"')).toBeVisible()
await expect(page.locator('text="<test1@gmail.com>" >> nth=0')).toBeVisible()
await expect(page.locator('text="<test2@gmail.com>" >> nth=0')).toBeVisible()
await expect(
page.locator('text="<baptiste.arnaud95@gmail.com>" >> nth=0')
).toBeVisible()
})

4 comments on commit 7b8169c

@vercel
Copy link

@vercel vercel bot commented on 7b8169c Apr 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

builder-v2 – ./apps/builder

builder-v2-typebot-io.vercel.app
app.typebot.io
builder-v2-git-main-typebot-io.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 7b8169c Apr 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 7b8169c Apr 12, 2022

@vercel
Copy link

@vercel vercel bot commented on 7b8169c Apr 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.