1
+ import nodemailer from 'nodemailer' ;
2
+
3
+ import { catchErrors , reportError } from '../errors' ;
4
+ import { delay } from '@httptoolkit/util' ;
5
+ import { getCorsResponseHeaders } from '../cors' ;
6
+
7
+ const {
8
+ CONTACT_FORM_DESTINATION ,
9
+ SMTP_HOST ,
10
+ SMTP_PORT ,
11
+ SMTP_USERNAME ,
12
+ SMTP_PASSWORD
13
+ } = process . env ;
14
+
15
+ if ( ! CONTACT_FORM_DESTINATION ) throw new Error ( 'No contact form destination configured' ) ;
16
+
17
+ if ( ! SMTP_HOST ) throw new Error ( 'No SMTP host configured' ) ;
18
+ if ( ! SMTP_PORT ) throw new Error ( 'No SMTP port configured' ) ;
19
+ if ( ! SMTP_USERNAME ) throw new Error ( 'No SMTP user configured' ) ;
20
+ if ( ! SMTP_PASSWORD ) throw new Error ( 'No SMTP password configured' ) ;
21
+
22
+ const mailer = nodemailer . createTransport ( {
23
+ host : SMTP_HOST ,
24
+ port : Number ( SMTP_PORT ) ,
25
+ secure : true ,
26
+ auth : {
27
+ user : SMTP_USERNAME ,
28
+ pass : SMTP_PASSWORD
29
+ }
30
+ } ) ;
31
+
32
+ const THANK_YOU_PAGE = 'https://httptoolkit.com/contact-thank-you/'
33
+
34
+ export const handler = catchErrors ( async ( event ) => {
35
+ let headers = getCorsResponseHeaders ( event ) ;
36
+
37
+ if ( event . httpMethod === 'OPTIONS' ) {
38
+ return { statusCode : 200 , headers, body : '' } ;
39
+ } else if ( event . httpMethod !== 'POST' ) {
40
+ return { statusCode : 405 , headers, body : '' } ;
41
+ }
42
+
43
+ const formData = new URLSearchParams ( event . body || '' ) ;
44
+ const {
45
+ name,
46
+ email,
47
+ message,
48
+ phone : honeypot
49
+ } = Object . fromEntries ( formData ) ;
50
+
51
+ if ( honeypot ) {
52
+ // We can remove this later - just reporting each hit for now to check if it's working
53
+ reportError ( 'Contact form honeypot triggered' , {
54
+ extraMetadata : { name, email, message, honeypot }
55
+ } ) ;
56
+
57
+ // Pretend it did actually work so they don't try again:
58
+ await delay ( 1000 ) ;
59
+ return {
60
+ statusCode : 302 ,
61
+ headers : {
62
+ Location : THANK_YOU_PAGE
63
+ } ,
64
+ body : ''
65
+ } ;
66
+ }
67
+
68
+ const fields = [
69
+ [ 'Name' , name ] ,
70
+ [ 'Email' , email ] ,
71
+ [ 'Message' , message ]
72
+ ]
73
+
74
+ fields . forEach ( ( [ field , value ] ) => {
75
+ if ( ! value ) {
76
+ return {
77
+ statusCode : 400 ,
78
+ headers,
79
+ body : `${ field } is required`
80
+ } ;
81
+ }
82
+ } ) ;
83
+
84
+ await mailer . sendMail ( {
85
+ from :
'Contact form <[email protected] >' ,
86
+ to : CONTACT_FORM_DESTINATION ,
87
+ replyTo : email ,
88
+ subject : 'HTTP Toolkit contact form message' ,
89
+ html : `<html><style>p { margin-bottom: 10px; }</style><body>
90
+ ${
91
+ fields . map ( ( [ field , value ] ) => {
92
+ return `<p><strong>${ field } </strong>:<br/>${ value } </p>` ;
93
+ } ) . join ( '' )
94
+ } </body></html>`
95
+ } ) ;
96
+
97
+ return {
98
+ statusCode : 302 ,
99
+ headers : {
100
+ Location : THANK_YOU_PAGE
101
+ } ,
102
+ body : ''
103
+ } ;
104
+ } ) ;
0 commit comments