Skip to content

Commit

Permalink
feat: send getting started email on signup (#1877)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
Co-authored-by: Johannes <johannes@formbricks.com>
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com>
  • Loading branch information
4 people committed Jan 22, 2024
1 parent 5ab55bb commit 64ddcb6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 12 deletions.
10 changes: 9 additions & 1 deletion apps/web/app/api/v1/users/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { NextResponse } from "next/server";

import { prisma } from "@formbricks/database";
import { EMAIL_VERIFICATION_DISABLED, INVITE_DISABLED, SIGNUP_ENABLED } from "@formbricks/lib/constants";
import { sendInviteAcceptedEmail, sendVerificationEmail } from "@formbricks/lib/emails/emails";
import {
sendGettingStartedEmail,
sendInviteAcceptedEmail,
sendVerificationEmail,
} from "@formbricks/lib/emails/emails";
import { env } from "@formbricks/lib/env.mjs";
import { deleteInvite } from "@formbricks/lib/invite/service";
import { verifyInviteToken } from "@formbricks/lib/jwt";
Expand Down Expand Up @@ -50,6 +54,8 @@ export async function POST(request: Request) {

if (!EMAIL_VERIFICATION_DISABLED) {
await sendVerificationEmail(user);
} else {
await sendGettingStartedEmail(user);
}

await sendInviteAcceptedEmail(invite.creator.name, user.name, invite.creator.email);
Expand Down Expand Up @@ -81,6 +87,8 @@ export async function POST(request: Request) {
// send verification email amd return user
if (!EMAIL_VERIFICATION_DISABLED) {
await sendVerificationEmail(user);
} else {
await sendGettingStartedEmail(user);
}
return NextResponse.json(user);
} catch (e) {
Expand Down
3 changes: 3 additions & 0 deletions packages/lib/authOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { prisma } from "@formbricks/database";
import { createAccount } from "./account/service";
import { verifyPassword } from "./auth/util";
import { EMAIL_VERIFICATION_DISABLED } from "./constants";
import { sendGettingStartedEmail } from "./emails/emails";
import { env } from "./env.mjs";
import { verifyToken } from "./jwt";
import { createMembership } from "./membership/service";
Expand Down Expand Up @@ -113,6 +114,7 @@ export const authOptions: NextAuthOptions = {
}

user = await updateUser(user.id, { emailVerified: new Date() });
await sendGettingStartedEmail(user);

return user;
},
Expand Down Expand Up @@ -221,6 +223,7 @@ export const authOptions: NextAuthOptions = {
identityProvider: provider,
identityProviderAccountId: account.providerAccountId,
});
await sendGettingStartedEmail(userProfile);
// Default team assignment if env variable is set
if (env.DEFAULT_TEAM_ID && env.DEFAULT_TEAM_ID.length > 0) {
// check if team exists
Expand Down
8 changes: 4 additions & 4 deletions packages/lib/emails/email-template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const withEmailTemplate = (content: string) =>
font-family: "Poppins", "Helvetica Neue", "Segoe UI", Helvetica,
sans-serif;
font-size: 15px;
font-weight: 300;
font-weight: 500;
line-height: 26px;
margin: 0;
color: #1e293b;
Expand Down Expand Up @@ -143,7 +143,7 @@ export const withEmailTemplate = (content: string) =>
"
>
<div class="gutter" style="padding: 30px">
<a href="https://formbricks.com" target="_blank">
<a href="https://formbricks.com?utm_source=email_header&utm_medium=email" target="_blank">
<img
src="https://s3.eu-central-1.amazonaws.com/listmonk-formbricks/Formbricks-Light-transparent.png"
alt="Formbricks Logo"
Expand Down Expand Up @@ -201,14 +201,14 @@ export const withEmailTemplate = (content: string) =>
Formbricks ${new Date().getFullYear()}. All rights reserved.<br />
<a
style="text-decoration: none"
href="https://formbricks.com/imprint"
href="https://formbricks.com/imprint?utm_source=email_footer&utm_medium=email"
target="_blank"
>Imprint</a
>
|
<a
style="text-decoration: none"
href="https://formbricks.com/privacy-policy"
href="https://formbricks.com/privacy-policy?utm_source=email_footer&utm_medium=email"
target="_blank"
>Privacy Policy</a
>
Expand Down
45 changes: 39 additions & 6 deletions packages/lib/emails/emails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ interface TEmailUser {
email: string;
}

interface TEmailUserWithName extends TEmailUser {
name: string | null;
}

export interface LinkSurveyEmailData {
surveyId: string;
email: string;
Expand Down Expand Up @@ -78,18 +82,47 @@ export const sendVerificationEmail = async (user: TEmailUser) => {
)}`;
await sendEmail({
to: user.email,
subject: "Welcome to Formbricks 🤍",
html: withEmailTemplate(`<h1>Welcome!</h1>
To start using Formbricks please verify your email by clicking the button below:<br/><br/>
<a class="button" href="${verifyLink}">Confirm email</a><br/>
<br/>
subject: "Please verify your email to use Formbricks",
html: withEmailTemplate(`<h1>Almost there!</h1>
To start using Formbricks please verify your email below:<br/><br/>
<a class="button" href="${verifyLink}">Verify email</a><br/><br/>
You can also click on this link:<br/>
<a href="${verifyLink}" style="word-break: break-all; color: #1e293b;">${verifyLink}</a><br/><br/>
<strong>The link is valid for 24h.</strong><br/><br/>If it has expired please request a new token here:
<a href="${verificationRequestLink}">Request new verification</a><br/>
<br/>
Your Formbricks Team`),
});
};

export const sendGettingStartedEmail = async (user: TEmailUserWithName) => {
await sendEmail({
to: user.email,
subject: "Get started with Formbricks 🤸",
html: withEmailTemplate(`
<h1 style="text-align: center; line-height: 1.2; padding-top: 16px; padding-bottom:8px;">Turn customer insights into irresistable experiences</h1>
<a href="https://app.formbricks.com?utm_source=drip_campaign&utm_medium=email&utm_campaign=first_drip_mail&utm_content=top_image"><img src="https://formbricks-cdn.s3.eu-central-1.amazonaws.com/getting-started-with-formbricks-v5.png" alt="Formbricks can do it all" /></a>
<h3 style="text-align:center;">Welcome to Formbricks! 🤗</h3>
<p style="text-align:center;">We're the fastest growing Experience Management platform! Gracefully collect feedback without survey fatigue. Are you ready?</p>
<div style="text-align:center; margin-bottom:72px;">
<a class="button" href="https://app.formbricks.com?utm_source=drip_campaign&utm_medium=email&utm_campaign=first_drip_mail&utm_content=first_button">Create your survey</a><br/>
</div>
<a href="https://app.formbricks.com?utm_source=drip_campaign&utm_medium=email&utm_campaign=first_drip_mail&utm_content=second_image"><img style="border-radius:16px; box-shadow: 10px 10px 57px -21px rgba(71,85,105,0.58);" src="https://formbricks-cdn.s3.eu-central-1.amazonaws.com/getting-started-header-v4.png" alt="Formbricks can do it all"></a>
<h2 style="margin-top:32px;">Collect feedback everywhere!</h2>
<p>Formbricks is very versatile. Run:</p>
<ul>
<li><b>Website Surveys</b> like HotJar Ask</li>
<li><b>In-App Surveys</b> like Sprig</li>
<li><b>Link Surveys</b> like Typeform</li>
<li><b>Headless Surveys</b> via API</li>
</ul>
<p>All on one, open source platform ✅</p>
<a class="button" style="margin-bottom:12px; margin-top:0px;" href="https://app.formbricks.com?utm_source=drip_campaign&utm_medium=email&utm_campaign=first_drip_mail&utm_content=second_button">Create your survey</a><br/>
<p style="margin-bottom:0px; margin-top:40px; text-align:center;"><b>Life is short, craft something irresistable!</b><br/>The Formbricks Team 🤍</p>
`),
});
};

export const sendForgotPasswordEmail = async (user: TEmailUser) => {
const token = createToken(user.id, user.email, {
expiresIn: "1d",
Expand Down Expand Up @@ -187,7 +220,7 @@ export const sendResponseFinishedEmail = async (
<a class="button" href="${WEBAPP_URL}/environments/${environmentId}/surveys/${
survey.id
}/responses?utm_source=emailnotification&utm_medium=email&utm_content=ViewResponsesCTA">View all responses</a>
}/responses?utm_source=email_notification&utm_medium=email&utm_content=view_responses_CTA">View all responses</a>
<div class="tooltip">
<p class='brandcolor'><strong>Start a conversation 💡</strong></p>
Expand Down
1 change: 0 additions & 1 deletion packages/lib/membership/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ export const createMembership = async (
data: Partial<TMembership>
): Promise<TMembership> => {
validateInputs([teamId, ZString], [userId, ZString], [data, ZMembership.partial()]);
console.log("createMembership", teamId, userId, data);

try {
const membership = await prisma.membership.create({
Expand Down

1 comment on commit 64ddcb6

@vercel
Copy link

@vercel vercel bot commented on 64ddcb6 Jan 22, 2024

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.