Skip to content

Commit abfb7e1

Browse files
feat: sender email with sendgrid
1 parent f792ec6 commit abfb7e1

File tree

10 files changed

+249
-33
lines changed

10 files changed

+249
-33
lines changed

‎.env.example‎

Lines changed: 0 additions & 15 deletions
This file was deleted.

‎docker-compose.yaml‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# https://waha.devlike.pro/docs/how-to/install/
2+
services:
3+
waha:
4+
restart: always
5+
# https://waha.devlike.pro/docs/how-to/engines/#docker-images
6+
# https://portal.devlike.pro/docker-image
7+
image: devlikeapro/waha-plus
8+
# WAHA Core
9+
# image: devlikeapro/waha:latest
10+
11+
ports:
12+
- '127.0.0.1:3000:3000/tcp'
13+
14+
volumes:
15+
# Store sessions in the .sessions folder (comment it if you're using MongoDB)
16+
- './sessions:/app/.sessions'
17+
18+
# Save media files
19+
# https://waha.devlike.pro/docs/how-to/storages/#save-media-files-between-the-container-restarts
20+
- './.media:/app/.media'
21+
22+
env_file:
23+
- .env
24+
25+
# NOTE: Only if you're using PostgreSQL to save sessions
26+
# https://waha.devlike.pro/docs/how-to/storages/#media---postgresql
27+
# postgres:
28+
# image: postgres:17
29+
# restart: always
30+
# environment:
31+
# POSTGRES_USER: postgres
32+
# POSTGRES_PASSWORD: postgres
33+
# POSTGRES_DB: postgres
34+
# ports:
35+
# - "5432:5432"
36+
# volumes:
37+
# - pg_data:/var/lib/postgresql/data
38+
# command:
39+
# - postgres
40+
# - "-c"
41+
# - "max_connections=3000"
42+
43+
# NOTE: Only if you're using MongoDB
44+
# https://waha.devlike.pro/docs/how-to/storages/#sessions---mongodb
45+
# Uncomment this block if you're using MongoDB
46+
# mongodb:
47+
# image: mongo
48+
# container_name: mongodb
49+
# ports:
50+
# - '127.0.0.1:27017:27017/tcp'
51+
# volumes:
52+
# - mongodb_data:/data/db
53+
# environment:
54+
# - MONGO_INITDB_ROOT_USERNAME=mongouser
55+
# - MONGO_INITDB_ROOT_PASSWORD=mongopassword
56+
57+
# NOTE: Only if you're using S3 to save media files
58+
# https://waha.devlike.pro/docs/how-to/storages/#media---s3
59+
# Uncomment this block if you're using AWS S3
60+
# minio:
61+
# image: quay.io/minio/minio
62+
# container_name: minio
63+
# restart: always
64+
# ports:
65+
# - '127.0.0.1:9000:9000'
66+
# - '127.0.0.1:9001:9001'
67+
# environment:
68+
# MINIO_REGION: 'eu-west-2'
69+
# MINIO_ROOT_USER: 'minioadmin'
70+
# MINIO_ROOT_PASSWORD: 'minioadmin'
71+
# volumes:
72+
# - minio_data:/data
73+
# command: server /data --console-address ":9001"
74+
75+
volumes:
76+
mongodb_data: {}
77+
minio_data: {}
78+
pg_data: {}

‎package-lock.json‎

Lines changed: 39 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@langchain/core": "^0.3.55",
2424
"@langchain/langgraph": "^0.2.71",
2525
"@langchain/openai": "^0.5.10",
26+
"@sendgrid/mail": "^8.1.5",
2627
"axios": "^1.9.0",
2728
"chromadb": "^2.4.3",
2829
"dotenv": "^16.5.0",

‎public/assets/socialMediaFan.png‎

306 KB
Loading

‎src/controllers/dashboard/authController.ts‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { Request, Response } from "express";
22
import User from "../../models/User";
33
import Verification from "../../models/Verification";
44
import jwt from "jsonwebtoken";
5-
import { sendVerifyCode } from "../../utils/mailgun";
5+
import { sendVerifyCode } from "../../utils/sendgrid";
6+
import dotenv from "dotenv";
7+
dotenv.config();
68
export default class AuthController {
79
static async requestCode(req: Request, res: Response): Promise<void> {
810
const { email } = req.body;
@@ -28,7 +30,8 @@ export default class AuthController {
2830
used: false,
2931
});
3032

31-
sendVerifyCode(email, code);
33+
const result = await sendVerifyCode(email, code);
34+
console.log("Email sent:", result);
3235
res.status(200).json({ message: "Code generated", code });
3336
} catch (error) {
3437
console.error(error);
@@ -88,6 +91,7 @@ export default class AuthController {
8891
}
8992
);
9093

94+
console.log("masuk sini, 2");
9195
res.status(200).json({
9296
message: "Verification success",
9397
user: {
@@ -98,6 +102,7 @@ export default class AuthController {
98102
token,
99103
});
100104
} catch (error) {
105+
console.log(error);
101106
console.error(error);
102107
res.status(500).json({ message: "Internal server error" });
103108
}

‎src/index.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ dotenv.config();
1616
const app = express();
1717

1818
connectMongo();
19+
app.use("/public", express.static("public"));
1920
// Use Express built-in middleware instead of body-parser
2021
app.use(express.json());
2122

‎src/types/image.d.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module "*.png" {
2+
const value: string;
3+
export default value;
4+
}

‎src/utils/mailgun.ts‎

Lines changed: 0 additions & 15 deletions
This file was deleted.

‎src/utils/sendgrid.ts‎

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import sgMail from "@sendgrid/mail";
2+
const imageUrl = "http://localhost:3000/public/assets/socialMediaFan.png";
3+
sgMail.setApiKey(process.env.SENDGRID_API_KEY!);
4+
5+
export async function sendVerifyCode(
6+
email: string,
7+
code: string
8+
): Promise<void> {
9+
const htmlTemplate = `
10+
<!DOCTYPE html>
11+
<html lang="en">
12+
<head>
13+
<meta charset="UTF-8">
14+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
15+
<title>Verify Your Email</title>
16+
<!--[if mso]>
17+
<style type="text/css">
18+
table {border-collapse:collapse;border-spacing:0;margin:0;}
19+
div, td {padding:0;}
20+
div {margin:0 !important;}
21+
</style>
22+
<noscript>
23+
<xml>
24+
<o:OfficeDocumentSettings>
25+
<o:PixelsPerInch>96</o:PixelsPerInch>
26+
</o:OfficeDocumentSettings>
27+
</xml>
28+
</noscript>
29+
<![endif]-->
30+
</head>
31+
<body style="margin:0;padding:0;word-spacing:normal;background-color:#f7f7f7;">
32+
<div role="article" aria-roledescription="email" lang="en" style="text-size-adjust:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;background-color:#f7f7f7;">
33+
<table role="presentation" style="width:100%;border:none;border-spacing:0;">
34+
<tr>
35+
<td align="center" style="padding:0;">
36+
<!--[if mso]>
37+
<table role="presentation" align="center" style="width:600px;">
38+
<tr>
39+
<td>
40+
<![endif]-->
41+
<table role="presentation" style="width:94%;max-width:600px;border:none;border-spacing:0;text-align:left;font-family:Arial,sans-serif;font-size:16px;line-height:22px;color:#363636;">
42+
<!-- Logo/Header -->
43+
<tr>
44+
<td style="padding:40px 30px 30px 30px;text-align:center;font-size:24px;font-weight:bold;">
45+
<a href="https://olaai.space" style="text-decoration:none;">
46+
<img src=${imageUrl} width="150" alt="Logo" style="width:150px;max-width:80%;height:auto;border:none;text-decoration:none;color:#ffffff;">
47+
</a>
48+
</td>
49+
</tr>
50+
<!-- Main Content Area -->
51+
<tr>
52+
<td style="padding:30px;background-color:#ffffff;border-radius:8px;box-shadow:0 4px 6px rgba(0,0,0,0.1);">
53+
<h1 style="margin-top:0;margin-bottom:16px;font-size:26px;line-height:32px;font-weight:bold;letter-spacing:-0.02em;text-align:center;color:#333333;">Verify Your Email</h1>
54+
<p style="margin:0;font-size:16px;line-height:24px;text-align:center;color:#555555;">Thanks for signing up! Please use the verification code below to complete your registration.</p>
55+
<!-- Verification Code Box -->
56+
<div style="margin:30px 0;padding:25px 20px;background-color:#f8f9fa;border-radius:6px;text-align:center;border-left:4px solid #0066FF;">
57+
<p style="margin:0 0 10px 0;font-size:14px;line-height:20px;color:#666666;text-transform:uppercase;letter-spacing:1px;">Your verification code</p>
58+
<p style="margin:0;font-size:32px;line-height:40px;font-weight:bold;letter-spacing:5px;color:#333333;font-family:monospace;">${code}</p>
59+
</div>
60+
<p style="margin:0 0 20px 0;font-size:16px;line-height:24px;color:#555555;">This code will expire in 10 minutes. If you didn't request this verification, you can safely ignore this email.</p>
61+
<!-- Action Button -->
62+
<p style="margin:0;text-align:center;">
63+
<a href="https://yourcompany.com/verify" style="background:#0066FF;text-decoration:none;padding:12px 30px;color:white;border-radius:4px;display:inline-block;mso-padding-alt:0;text-underline-color:#0066FF;">
64+
<!--[if mso]><i style="letter-spacing:25px;mso-font-width:-100%;mso-text-raise:20pt">&nbsp;</i><![endif]-->
65+
<span style="mso-text-raise:10pt;font-weight:bold;">Verify Email Address</span>
66+
<!--[if mso]><i style="letter-spacing:25px;mso-font-width:-100%">&nbsp;</i><![endif]-->
67+
</a>
68+
</p>
69+
</td>
70+
</tr>
71+
<!-- Additional Info -->
72+
<tr>
73+
<td style="padding:30px;background-color:#ffffff;border-radius:8px;box-shadow:0 4px 6px rgba(0,0,0,0.1);margin-top:20px;text-align:center;">
74+
<p style="margin:0 0 15px 0;font-size:16px;line-height:24px;color:#555555;">Having trouble? Contact our support team for assistance.</p>
75+
<img src="https://via.placeholder.com/540x200/E9F2FF/0066FF?text=Welcome+to+Our+Service" width="540" alt="Welcome Banner" style="width:100%;height:auto;border:none;border-radius:4px;text-decoration:none;color:#ffffff;">
76+
</td>
77+
</tr>
78+
<!-- Footer -->
79+
<tr>
80+
<td style="padding:30px;text-align:center;font-size:14px;color:#777777;">
81+
<p style="margin:0 0 8px 0;">Your Company Name, Inc.</p>
82+
<p style="margin:0 0 8px 0;">123 Street Address, City, Country</p>
83+
<p style="margin:0;">This email was sent to ${email}</p>
84+
</td>
85+
</tr>
86+
</table>
87+
<!--[if mso]>
88+
</td>
89+
</tr>
90+
</table>
91+
<![endif]-->
92+
</td>
93+
</tr>
94+
</table>
95+
</div>
96+
</body>
97+
</html>
98+
`;
99+
100+
const msg = {
101+
to: email,
102+
from: "imamasyari700@gmail.com",
103+
subject: "Your Verification Code",
104+
text: `Your verification code is: ${code}`,
105+
html: htmlTemplate,
106+
};
107+
108+
try {
109+
console.log("Sending email to:", email);
110+
const result = await sgMail.send(msg);
111+
console.log(`Verification code sent to ${email}`, result);
112+
} catch (error: any) {
113+
console.error("Error sending email:", error);
114+
if (error.response) {
115+
console.error("SendGrid response error:", error.response.body);
116+
}
117+
throw new Error("Failed to send verification code");
118+
}
119+
}

0 commit comments

Comments
 (0)