1- import Mail from '@ioc:Adonis/Addons/Mail'
2- import type { MailMessage , MailsMessages } from '@ioc:Adonis/Addons/Mail'
1+ import Mail , { BaseMailer } from '@ioc:Adonis/Addons/Mail'
2+ import type { MessageContract } from '@ioc:Adonis/Addons/Mail'
3+ import Env from '@ioc:Adonis/Core/Env'
34import View from '@ioc:Adonis/Core/View'
45import mjml from 'mjml'
6+ import Mailjet from 'node-mailjet'
7+ import type { LibraryResponse } from 'node-mailjet'
8+ import Logger from '@ioc:Adonis/Core/Logger'
59import appInfos from 'Config/app-infos'
10+ import type { RequestData } from 'node-mailjet/declarations/request/Request'
611
7- export default class MailService {
8- protected static replyTo = {
12+ type MailReplayTo = {
13+ email : string
14+ name : string
15+ }
16+
17+ interface BaseMailPayload {
18+ payload ?: Record < string , unknown >
19+ subject ?: string
20+ viewPath ?: string
21+ }
22+
23+ interface MailPayload extends BaseMailPayload {
24+ email : string
25+ }
26+
27+ interface MailManyPayload extends BaseMailPayload {
28+ emails : string [ ]
29+ }
30+
31+ export default class MailService extends BaseMailer {
32+ protected static replyTo : MailReplayTo = {
933 email : appInfos . emails . support ,
1034 name : `${ appInfos . name } Team` ,
1135 }
@@ -15,70 +39,80 @@ export default class MailService {
1539 payload,
1640 subject,
1741 viewPath = 'emails/test-email' ,
18- } : {
19- email : string
20- payload ?: Record < string , unknown >
21- subject ?: string
22- viewPath ?: string
23- } ) : Promise < void > {
24- const mail : MailMessage = {
25- viewPath,
26- from : appInfos . emails . noReply ,
27- to : email ,
28- subject : subject ,
29- replyTo : this . replyTo ,
30- payload,
31- }
42+ } : MailPayload ) : Promise < void > {
43+ const html : string = this . getHtml ( viewPath , payload )
3244
33- const html = this . getHtml ( mail . viewPath , mail . payload )
34- await Mail . sendLater ( ( message ) => {
35- message
36- . from ( mail . from )
37- . to ( mail . to )
38- . subject ( mail . subject || '' )
39- . replyTo ( mail . replyTo . email || mail . to , mail . replyTo . name )
40- . html ( html )
41- } )
45+ const isProduction : boolean = Env . get ( 'NODE_ENV' ) === 'production'
46+
47+ if ( isProduction ) {
48+ // Use Mailjet in production
49+ this . sendMailWithMailjet ( { email, payload, subject, viewPath } )
50+ } else {
51+ // Use the classic operation of Adonis Mail in development
52+ await Mail . sendLater ( ( message : MessageContract ) : void => {
53+ message
54+ . from ( appInfos . emails . noReply )
55+ . to ( email )
56+ . subject ( subject || '' )
57+ . replyTo ( this . replyTo . email , this . replyTo . name )
58+ . html ( html )
59+ } )
60+ }
4261 }
4362
4463 public static async sendMany ( {
4564 emails,
4665 payload,
4766 subject,
4867 viewPath = 'emails/test-email' ,
49- } : {
50- emails : string [ ]
51- payload ?: Record < string , unknown >
52- subject ?: string
53- viewPath ?: string
54- } ) {
55- const mails : MailsMessages = {
56- viewPath,
57- from : appInfos . emails . noReply ,
58- to : emails ,
59- subject : subject ,
60- replyTo : {
61- email : appInfos . emails . support ,
62- name : `${ appInfos . name } Team` ,
63- } ,
64- payload,
68+ } : MailManyPayload ) : Promise < void > {
69+ const uniqueEmails : string [ ] = [ ...new Set ( emails ) ]
70+
71+ for ( const email of uniqueEmails ) {
72+ await this . send ( { email, payload, subject, viewPath } )
6573 }
74+ }
6675
67- const receivers : string [ ] = [ ]
68- const html = this . getHtml ( mails . viewPath , mails . payload )
69- mails . to . map ( async ( mail ) => {
70- if ( receivers . includes ( mail ) ) return
71- receivers . push ( mail )
76+ public static sendMailWithMailjet ( {
77+ email,
78+ payload,
79+ subject,
80+ viewPath = 'emails/test-email' ,
81+ } : MailPayload ) : void {
82+ const html : string = this . getHtml ( viewPath , payload )
7283
73- await Mail . sendLater ( ( message ) => {
74- message
75- . from ( mails . from )
76- . to ( mail )
77- . subject ( mails . subject || '' )
78- . replyTo ( mails . replyTo . email || mail , mails . replyTo . name )
79- . html ( html )
80- } )
84+ const mailjet : Mailjet = new Mailjet ( {
85+ apiKey : Env . get ( 'MAILJET_API_KEY' ) ,
86+ apiSecret : Env . get ( 'MAILJET_API_SECRET_KEY' ) ,
8187 } )
88+
89+ const request : Promise < LibraryResponse < RequestData > > = mailjet
90+ . post ( 'send' , { version : 'v3.1' } )
91+ . request ( {
92+ Messages : [
93+ {
94+ From : {
95+ Email : appInfos . emails . noReply ,
96+ Name : this . replyTo . name ,
97+ } ,
98+ To : [ { Email : email } ] ,
99+ Subject : subject ,
100+ HTMLPart : html ,
101+ ReplyTo : {
102+ Email : this . replyTo . email ,
103+ Name : this . replyTo . name ,
104+ } ,
105+ } ,
106+ ] ,
107+ } )
108+
109+ request
110+ . then ( ( result : LibraryResponse < RequestData > ) : void => {
111+ Logger . info ( 'Mail sent successfully with Mailjet:' , JSON . stringify ( result . body ) )
112+ } )
113+ . catch ( ( error ) : void => {
114+ Logger . error ( 'Error sending mail with Mailjet:' , JSON . stringify ( error . statusCode ) )
115+ } )
82116 }
83117
84118 protected static getHtml ( viewPath : string , payload ?: Record < string , unknown > ) : string {
0 commit comments