feat(viewer): 🐛 Fix multiple cc bcc email
This commit is contained in:
@ -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'
|
||||
@ -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),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
122
apps/viewer/playwright/fixtures/typebots/sendEmail.json
Normal file
122
apps/viewer/playwright/fixtures/typebots/sendEmail.json
Normal file
@ -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
|
||||
}
|
@ -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()
|
||||
|
||||
@ -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
apps/viewer/playwright/tests/sendEmail.spec.ts
Normal file
45
apps/viewer/playwright/tests/sendEmail.spec.ts
Normal file
@ -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()
|
||||
})
|
Reference in New Issue
Block a user