11import { ContactFormSchema , type ContactFormValues } from "./schema" ;
22
33interface Env {
4- GITHUB_ISSUE_TOKEN : string ;
5- GITHUB_ISSUE_REPO : string ;
4+ RESEND_API_KEY : string ;
5+ RESEND_FROM : string ;
6+ CONTACT_TO_EMAIL : string ;
67 ALLOWED_ORIGINS : string ;
78}
89
9- interface GithubIssuePayload {
10- title : string ;
11- body : string ;
12- labels ?: string [ ] ;
10+ interface ResendEmailPayload {
11+ from : string ;
12+ to : string [ ] ;
13+ subject : string ;
14+ reply_to ?: string ;
15+ text : string ;
1316}
1417
1518function corsHeaders ( origin : string | null , allowList : string [ ] ) : HeadersInit {
@@ -34,43 +37,38 @@ function jsonResponse(
3437 } ) ;
3538}
3639
37- function buildIssueTitle ( message : string , email : string ) : string {
40+ function buildEmailSubject ( message : string , email : string ) : string {
3841 const oneLine = message . replace ( / \s + / g, " " ) . trim ( ) ;
3942 const snippet = oneLine . slice ( 0 , 60 ) ;
4043 const truncated = oneLine . length > 60 ? `${ snippet } …` : snippet ;
4144 return `[Contact] ${ truncated || email } ` ;
4245}
4346
44- function buildIssueBody (
47+ function buildEmailText (
4548 data : Pick < ContactFormValues , "email" | "message" > ,
4649) : string {
4750 return [
48- `** From:** ${ data . email } ` ,
49- `** Received:** ${ new Date ( ) . toISOString ( ) } ` ,
51+ `From: ${ data . email } ` ,
52+ `Received: ${ new Date ( ) . toISOString ( ) } ` ,
5053 "" ,
5154 "---" ,
5255 "" ,
5356 data . message ,
5457 ] . join ( "\n" ) ;
5558}
5659
57- async function createGithubIssue (
58- env : Env ,
59- payload : GithubIssuePayload ,
60+ async function sendResendEmail (
61+ apiKey : string ,
62+ payload : ResendEmailPayload ,
6063) : Promise < { ok : true } | { ok : false ; status : number ; error : string } > {
61- const res = await fetch (
62- `https://api.github.com/repos/${ env . GITHUB_ISSUE_REPO } /issues` ,
63- {
64- method : "POST" ,
65- headers : {
66- Authorization : `Bearer ${ env . GITHUB_ISSUE_TOKEN } ` ,
67- Accept : "application/vnd.github+json" ,
68- "X-GitHub-Api-Version" : "2022-11-28" ,
69- "User-Agent" : "firstfluke-contact-worker" ,
70- } ,
71- body : JSON . stringify ( payload ) ,
64+ const res = await fetch ( "https://api.resend.com/emails" , {
65+ method : "POST" ,
66+ headers : {
67+ Authorization : `Bearer ${ apiKey } ` ,
68+ "Content-Type" : "application/json" ,
7269 } ,
73- ) ;
70+ body : JSON . stringify ( payload ) ,
71+ } ) ;
7472 if ( ! res . ok ) {
7573 const error = await res . text ( ) ;
7674 return { ok : false , status : res . status , error } ;
@@ -119,27 +117,26 @@ export default {
119117 return jsonResponse ( { ok : true } , 200 , cors ) ;
120118 }
121119
122- if ( ! env . GITHUB_ISSUE_TOKEN || ! env . GITHUB_ISSUE_REPO ) {
123- // TODO(oma-deferred): set GITHUB_ISSUE_TOKEN and GITHUB_ISSUE_REPO via `wrangler secret put`.
124- console . info (
125- "[contact] GitHub credentials missing. Payload acknowledged:" ,
126- {
127- email : parsed . data . email ,
128- messageLength : parsed . data . message . length ,
129- } ,
130- ) ;
120+ if ( ! env . RESEND_API_KEY || ! env . RESEND_FROM || ! env . CONTACT_TO_EMAIL ) {
121+ // TODO(oma-deferred): set RESEND_API_KEY, RESEND_FROM, CONTACT_TO_EMAIL via `wrangler secret put` / `[vars]`.
122+ console . info ( "[contact] Resend config missing. Payload acknowledged:" , {
123+ email : parsed . data . email ,
124+ messageLength : parsed . data . message . length ,
125+ } ) ;
131126 return jsonResponse ( { ok : true } , 200 , cors ) ;
132127 }
133128
134- const result = await createGithubIssue ( env , {
135- title : buildIssueTitle ( parsed . data . message , parsed . data . email ) ,
136- body : buildIssueBody ( parsed . data ) ,
137- labels : [ "contact" ] ,
129+ const result = await sendResendEmail ( env . RESEND_API_KEY , {
130+ from : env . RESEND_FROM ,
131+ to : [ env . CONTACT_TO_EMAIL ] ,
132+ subject : buildEmailSubject ( parsed . data . message , parsed . data . email ) ,
133+ reply_to : parsed . data . email ,
134+ text : buildEmailText ( parsed . data ) ,
138135 } ) ;
139136
140137 if ( ! result . ok ) {
141138 console . error (
142- "[contact] github issue create failed:" ,
139+ "[contact] resend send failed:" ,
143140 result . status ,
144141 result . error ,
145142 ) ;
0 commit comments