Skip to content

Commit

Permalink
feat(bot): ✨ Custom email body and HTML content
Browse files Browse the repository at this point in the history
  • Loading branch information
baptisteArno committed Jun 12, 2022
1 parent aeaaa5c commit 97980f4
Show file tree
Hide file tree
Showing 8 changed files with 358 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { Stack, useDisclosure, Text } from '@chakra-ui/react'
import {
Stack,
useDisclosure,
Text,
Flex,
HStack,
Switch,
} from '@chakra-ui/react'
import { CodeEditor } from 'components/shared/CodeEditor'
import { CredentialsDropdown } from 'components/shared/CredentialsDropdown'
import { SwitchWithLabel } from 'components/shared/SwitchWithLabel'
import { Input, Textarea } from 'components/shared/Textbox'
import { CredentialsType, SendEmailOptions } from 'models'
import React, { useState } from 'react'
Expand Down Expand Up @@ -66,6 +75,18 @@ export const SendEmailSettings = ({ options, onOptionsChange }: Props) => {
replyTo,
})

const handleIsCustomBodyChange = (isCustomBody: boolean) =>
onOptionsChange({
...options,
isCustomBody,
})

const handleIsBodyCodeChange = () =>
onOptionsChange({
...options,
isBodyCode: options.isBodyCode ? !options.isBodyCode : true,
})

return (
<Stack spacing={4}>
<Stack>
Expand Down Expand Up @@ -121,15 +142,42 @@ export const SendEmailSettings = ({ options, onOptionsChange }: Props) => {
defaultValue={options.subject ?? ''}
/>
</Stack>
<Stack>
<Text>Body: </Text>
<Textarea
data-testid="body-input"
minH="300px"
onChange={handleBodyChange}
defaultValue={options.body ?? ''}
/>
</Stack>
<SwitchWithLabel
id={'custom-body'}
label={'Custom content?'}
initialValue={options.isCustomBody ?? false}
onCheckChange={handleIsCustomBodyChange}
/>
{options.isCustomBody && (
<Stack>
<Flex justifyContent="space-between">
<Text>Content: </Text>
<HStack>
<Text fontSize="sm">Text</Text>
<Switch
size="sm"
isChecked={options.isBodyCode ?? false}
onChange={handleIsBodyCodeChange}
/>
<Text fontSize="sm">Code</Text>
</HStack>
</Flex>
{options.isBodyCode ? (
<CodeEditor
value={options.body ?? ''}
onChange={handleBodyChange}
lang="html"
/>
) : (
<Textarea
data-testid="body-input"
minH="300px"
onChange={handleBodyChange}
defaultValue={options.body ?? ''}
/>
)}
</Stack>
)}
<SmtpConfigModal
isOpen={isOpen}
onClose={onClose}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const GroupNode = ({ group, groupIndex }: Props) => {
useEffect(() => {
setIsConnecting(
connectingIds?.target?.groupId === group.id &&
isNotDefined(connectingIds.target?.groupId)
isNotDefined(connectingIds.target?.blockId)
)
}, [connectingIds, group.id])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ test.describe('Send email block', () => {
'email1@gmail.com, email2@gmail.com'
)
await page.fill('[data-testid="subject-input"]', 'Email subject')
await page.click('text="Custom body?"')
await page.fill('[data-testid="body-input"]', 'Here is my email')

await page.click('text=Preview')
Expand Down
188 changes: 188 additions & 0 deletions apps/viewer/assets/newLeadEmailContent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
const emailRegex =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/

const parseResult = (val?: string) =>
val && emailRegex.test(val) ? `<a href="mailto:${val}">${val}</a>` : val ?? ''

export const newLeadEmailContent = (
resultUrl: string,
answers: { [key: string]: string }
) => `
<!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">
</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="" 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="" 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" style 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;">Your typebot has collected a <strong>new lead!</strong> 🥳</div>
</td>
</tr>
${Object.keys(answers)
.map(
(key) => `<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;">${key}: ${parseResult(
answers[key]
)}</div>
</td>
</tr>`
)
.join('')}
</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="" 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" style 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%;">
<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="${resultUrl}" 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"> Check results </a>
</td>
</tr>
</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>
`
Loading

4 comments on commit 97980f4

@vercel
Copy link

@vercel vercel bot commented on 97980f4 Jun 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 97980f4 Jun 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 97980f4 Jun 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 97980f4 Jun 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

Please sign in to comment.