11import { definePlugin } from "emdash" ;
22import type { PluginContext , PluginDescriptor , RouteContext } from "emdash" ;
3+ import { Lettermint } from "lettermint" ;
34
45interface EmailDeliverEvent {
56 message : {
@@ -12,19 +13,24 @@ interface EmailDeliverEvent {
1213}
1314
1415/**
15- * Delivers an email via the Lettermint API .
16+ * Helper to read plugin settings from KV .
1617 */
17- async function deliverHandler ( event : EmailDeliverEvent , ctx : PluginContext ) {
18- const entries = await ctx . kv . list ( "settings:" ) ;
19- const settings = new Map < string , string > ( ) ;
18+ async function getSettings ( kv : PluginContext [ "kv" ] ) {
19+ const entries = await kv . list ( "settings:" ) ;
20+ const settings : Record < string , string > = { } ;
2021 for ( const { key, value } of entries ) {
21- if ( typeof value === "string" ) {
22- settings . set ( key . replace ( "settings:" , "" ) , value ) ;
23- }
22+ const k = key . replace ( "settings:" , "" ) ;
23+ settings [ k ] = typeof value === "string" ? value : String ( value ) ;
2424 }
25+ return settings ;
26+ }
2527
26- const apiToken = settings . get ( "apiToken" ) ;
27- const fromAddress = settings . get ( "fromAddress" ) ;
28+ /**
29+ * Delivers an email via the Lettermint SDK.
30+ */
31+ async function deliverHandler ( event : EmailDeliverEvent , ctx : PluginContext ) {
32+ const settings = await getSettings ( ctx . kv ) ;
33+ const { apiToken, fromAddress } = settings ;
2834
2935 if ( ! apiToken ) {
3036 ctx . log . error ( "Lettermint API token not configured" ) ;
@@ -36,39 +42,26 @@ async function deliverHandler(event: EmailDeliverEvent, ctx: PluginContext) {
3642 return ;
3743 }
3844
39- const body : Record < string , string > = {
40- from : fromAddress ,
41- to : event . message . to ,
42- subject : event . message . subject ,
43- text : event . message . text ,
44- } ;
45-
46- if ( event . message . html ) {
47- body . html = event . message . html ;
48- }
45+ const client = new Lettermint ( { apiToken } ) ;
4946
50- const response = await ctx . http ?. fetch ( "https://api.lettermint.co/v1/email/send" , {
51- method : "POST" ,
52- headers : {
53- "Authorization" : `Bearer ${ apiToken } ` ,
54- "Content-Type" : "application/json" ,
55- } ,
56- body : JSON . stringify ( body ) ,
57- } ) ;
47+ let email = client . email
48+ . from ( fromAddress )
49+ . to ( event . message . to )
50+ . subject ( event . message . subject )
51+ . text ( event . message . text ) ;
5852
59- if ( ! response || ! response . ok ) {
60- ctx . log . error ( `Lettermint delivery failed: ${ response ?. status ?? "no response" } ` ) ;
61- return ;
53+ if ( event . message . html ) {
54+ email = email . html ( event . message . html ) ;
6255 }
6356
64- const result = await response . json ( ) ;
65- ctx . log . info ( `Email delivered via Lettermint: ${ result . message_id } ` ) ;
57+ const response = await email . send ( ) ;
58+ ctx . log . info ( `Email delivered via Lettermint: ${ response . message_id } ` ) ;
6659}
6760
6861export function lettermintPlugin ( ) : PluginDescriptor {
6962 return {
7063 id : "lettermint" ,
71- version : "0.2.1 " ,
64+ version : "0.3.0 " ,
7265 format : "native" ,
7366 entrypoint : new URL ( "./index.ts" , import . meta. url ) . pathname ,
7467 adminEntry : new URL ( "./admin.tsx" , import . meta. url ) . pathname ,
@@ -82,9 +75,8 @@ export function lettermintPlugin(): PluginDescriptor {
8275export function createPlugin ( ) {
8376 return definePlugin ( {
8477 id : "lettermint" ,
85- version : "0.2.1" ,
86- capabilities : [ "email:provide" , "network:fetch" ] ,
87- allowedHosts : [ "api.lettermint.co" ] ,
78+ version : "0.3.0" ,
79+ capabilities : [ "email:provide" ] ,
8880
8981 hooks : {
9082 "email:deliver" : {
@@ -96,12 +88,7 @@ export function createPlugin() {
9688 routes : {
9789 "settings" : {
9890 handler : async ( ctx : RouteContext ) => {
99- const entries = await ctx . kv . list ( "settings:" ) ;
100- const settings : Record < string , string > = { } ;
101- for ( const { key, value } of entries ) {
102- const k = key . replace ( "settings:" , "" ) ;
103- settings [ k ] = typeof value === "string" ? value : String ( value ) ;
104- }
91+ const settings = await getSettings ( ctx . kv ) ;
10592 return { settings } ;
10693 } ,
10794 } ,
@@ -116,40 +103,27 @@ export function createPlugin() {
116103 } ,
117104 "test" : {
118105 handler : async ( ctx : RouteContext ) => {
119- const entries = await ctx . kv . list ( "settings:" ) ;
120- const settings : Record < string , string > = { } ;
121- for ( const { key, value } of entries ) {
122- const k = key . replace ( "settings:" , "" ) ;
123- settings [ k ] = typeof value === "string" ? value : String ( value ) ;
124- }
125-
126- const apiToken = settings . apiToken ;
127- const fromAddress = settings . fromAddress ;
106+ const settings = await getSettings ( ctx . kv ) ;
107+ const { apiToken, fromAddress } = settings ;
128108
129109 if ( ! apiToken || ! fromAddress ) {
130110 return { ok : false , error : "Please configure your API token and from address first." } ;
131111 }
132112
133- const response = await ctx . http ?. fetch ( "https://api.lettermint.co/v1/email/send" , {
134- method : "POST" ,
135- headers : {
136- "Authorization" : `Bearer ${ apiToken } ` ,
137- "Content-Type" : "application/json" ,
138- } ,
139- body : JSON . stringify ( {
140- from : fromAddress ,
141- to : fromAddress ,
142- subject : "Lettermint test email from EmDash" ,
143- text : "If you're reading this, your Lettermint email integration is working!" ,
144- } ) ,
145- } ) ;
146-
147- if ( ! response || ! response . ok ) {
148- const status = response ?. status ?? "no response" ;
149- return { ok : false , error : `Lettermint API returned ${ status } .` } ;
113+ try {
114+ const client = new Lettermint ( { apiToken } ) ;
115+ await client . email
116+ . from ( fromAddress )
117+ . to ( fromAddress )
118+ . subject ( "Lettermint test email from EmDash" )
119+ . text ( "If you're reading this, your Lettermint email integration is working!" )
120+ . send ( ) ;
121+
122+ return { ok : true } ;
123+ } catch ( err ) {
124+ const message = err instanceof Error ? err . message : String ( err ) ;
125+ return { ok : false , error : `Lettermint error: ${ message } ` } ;
150126 }
151-
152- return { ok : true } ;
153127 } ,
154128 } ,
155129 } ,
0 commit comments