| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  | import * as plugins from './mailgun.plugins.js'; | 
					
						
							|  |  |  | import * as interfaces from './interfaces/index.js'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export interface IMailgunAccountContructorOptions { | 
					
						
							|  |  |  |   apiToken: string; | 
					
						
							|  |  |  |   region: 'eu' | 'us'; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-10-23 20:00:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class MailgunAccount { | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |   public apiBaseUrl: string; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   public options: IMailgunAccountContructorOptions; | 
					
						
							| 
									
										
										
										
											2019-10-23 20:00:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |   public smartSmtps: { [domain: string]: plugins.smartsmtp.Smartsmtp } = {}; | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |   constructor(optionsArg: IMailgunAccountContructorOptions) { | 
					
						
							|  |  |  |     this.options = optionsArg; | 
					
						
							|  |  |  |     this.apiBaseUrl = | 
					
						
							|  |  |  |       this.options.region === 'eu' | 
					
						
							|  |  |  |         ? 'https://api.eu.mailgun.net/v3' | 
					
						
							| 
									
										
										
										
											2025-10-17 08:48:22 +00:00
										 |  |  |         : 'https://api.mailgun.net/v3'; | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * allows adding smtp credentials | 
					
						
							|  |  |  |    * Format: [domain]|[username]|[password] | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |   public async addSmtpCredentials(credentials: string) { | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |     const credentialArray = credentials.split('|'); | 
					
						
							|  |  |  |     if (credentialArray.length !== 3) { | 
					
						
							|  |  |  |       throw new Error('credentials are in the wrong format'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |     this.smartSmtps[credentialArray[0]] = | 
					
						
							|  |  |  |       await plugins.smartsmtp.Smartsmtp.createSmartsmtpWithRelay({ | 
					
						
							|  |  |  |         smtpServer: 'smtp.eu.mailgun.org', | 
					
						
							|  |  |  |         smtpUser: credentialArray[1], | 
					
						
							|  |  |  |         smtpPassword: credentialArray[2], | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |   public async getRequest(routeArg: string, binaryArg: boolean = false) { | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  |     let requestUrl = routeArg; | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |     const needsBaseUrlPrefix = !routeArg.startsWith('https://'); | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |     if (needsBaseUrlPrefix) { | 
					
						
							|  |  |  |       requestUrl = `${this.apiBaseUrl}${routeArg}`; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |     console.log(requestUrl); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     const response = await plugins.smartrequest.SmartRequest.create() | 
					
						
							|  |  |  |       .url(requestUrl) | 
					
						
							|  |  |  |       .headers({ | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |         Authorization: `Basic ${plugins.smartstring.base64.encode(`api:${this.options.apiToken}`)}`, | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |         'Content-Type': 'application/json', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |       }) | 
					
						
							|  |  |  |       .options({ keepAlive: false }) | 
					
						
							|  |  |  |       .get(); | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  |     return response; | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-10-23 20:00:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |   public async postFormData( | 
					
						
							|  |  |  |     routeArg: string, | 
					
						
							|  |  |  |     formFields: plugins.smartrequest.FormField[], | 
					
						
							|  |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |     const requestUrl = `${this.apiBaseUrl}${routeArg}`; | 
					
						
							|  |  |  |     console.log(requestUrl); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     const response = await plugins.smartrequest.SmartRequest.create() | 
					
						
							|  |  |  |       .url(requestUrl) | 
					
						
							|  |  |  |       .headers({ | 
					
						
							|  |  |  |         Authorization: `Basic ${plugins.smartstring.base64.encode( | 
					
						
							|  |  |  |           `api:${this.options.apiToken}`, | 
					
						
							|  |  |  |         )}`,
 | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |       .options({ keepAlive: false }) | 
					
						
							|  |  |  |       .formData(formFields) | 
					
						
							|  |  |  |       .post(); | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  |     return response; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-10-23 20:00:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * sends a SmartMail | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  |   public async sendSmartMail( | 
					
						
							|  |  |  |     smartmailArg: plugins.smartmail.Smartmail<interfaces.IMailgunMessage>, | 
					
						
							|  |  |  |     toArg: string, | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     dataArg = {}, | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  |   ) { | 
					
						
							| 
									
										
										
										
											2020-04-26 23:24:03 +00:00
										 |  |  |     const domain = smartmailArg.options.from.split('@')[1].replace('>', ''); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     const formFields: plugins.smartrequest.FormField[] = [ | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  |       { | 
					
						
							|  |  |  |         name: 'from', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         value: smartmailArg.options.from, | 
					
						
							| 
									
										
										
										
											2019-10-27 22:53:21 +01:00
										 |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         name: 'to', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         value: toArg, | 
					
						
							| 
									
										
										
										
											2019-10-27 22:53:21 +01:00
										 |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         name: 'subject', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         value: smartmailArg.getSubject(dataArg), | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2020-08-11 14:47:25 +00:00
										 |  |  |         name: 'html', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         value: smartmailArg.getBody(dataArg), | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |       }, | 
					
						
							|  |  |  |     ]; | 
					
						
							| 
									
										
										
										
											2019-10-27 22:53:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |     console.log(smartmailArg.attachments); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-27 22:53:21 +01:00
										 |  |  |     for (const attachment of smartmailArg.attachments) { | 
					
						
							|  |  |  |       formFields.push({ | 
					
						
							|  |  |  |         name: 'attachment', | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         value: attachment.contentBuffer, | 
					
						
							|  |  |  |         filename: attachment.parsedPath.base, | 
					
						
							| 
									
										
										
										
											2019-10-28 15:55:04 +01:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2019-10-27 22:53:21 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |     if (smartmailArg.getBody(dataArg)) { | 
					
						
							|  |  |  |       console.log('All requirements for API met'); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |       const response = await this.postFormData( | 
					
						
							|  |  |  |         `/${domain}/messages`, | 
					
						
							|  |  |  |         formFields, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       if (response.status === 200) { | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |         console.log( | 
					
						
							|  |  |  |           `Sent mail with subject ${smartmailArg.getSubject( | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |             dataArg, | 
					
						
							|  |  |  |           )} to ${toArg} using the mailgun API`,
 | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |         ); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         return await response.json(); | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |       } else { | 
					
						
							| 
									
										
										
										
											2025-10-17 08:48:22 +00:00
										 |  |  |         let errorMessage = `HTTP ${response.status}: ${response.statusText}`; | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           // Get response body as text first
 | 
					
						
							|  |  |  |           const errorText = await response.text(); | 
					
						
							|  |  |  |           console.log(errorText); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           // Try to parse as JSON
 | 
					
						
							|  |  |  |           try { | 
					
						
							|  |  |  |             const errorBody = JSON.parse(errorText); | 
					
						
							|  |  |  |             errorMessage = errorBody.message || JSON.stringify(errorBody); | 
					
						
							|  |  |  |           } catch { | 
					
						
							|  |  |  |             // Not JSON, use plain text
 | 
					
						
							|  |  |  |             errorMessage = errorText || errorMessage; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } catch { | 
					
						
							|  |  |  |           // Couldn't read body at all
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         throw new Error(`could not send email: ${errorMessage}`); | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-10-28 16:15:16 +01:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |       console.log( | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         'An empty body was provided. This does not work via the API, but using SMTP instead.', | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2020-08-13 00:32:05 +00:00
										 |  |  |       const wantedSmartsmtp = this.smartSmtps[domain]; | 
					
						
							|  |  |  |       if (!wantedSmartsmtp) { | 
					
						
							|  |  |  |         console.log('did not find appropriate smtp credentials'); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |       await wantedSmartsmtp.sendSmartMail(smartmailArg, toArg); | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |       console.log( | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |         `Sent mail with subject "${smartmailArg.getSubject( | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |           dataArg, | 
					
						
							|  |  |  |         )}" to "${toArg}" using an smtp transport over Mailgun.`,
 | 
					
						
							| 
									
										
										
										
											2020-08-13 01:37:26 +00:00
										 |  |  |       ); | 
					
						
							| 
									
										
										
										
											2019-10-28 16:15:16 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-10-23 20:00:04 +02:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   public async retrieveSmartMailFromMessageUrl(messageUrlArg: string) { | 
					
						
							| 
									
										
										
										
											2022-08-07 16:31:56 +02:00
										 |  |  |     console.log(`retrieving message for ${messageUrlArg}`); | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  |     const response = await this.getRequest(messageUrlArg); | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     if (response.status === 404) { | 
					
						
							|  |  |  |       const body: any = await response.json(); | 
					
						
							|  |  |  |       console.log(body.message); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:04:28 +00:00
										 |  |  |       return null; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     const responseBody: interfaces.IMailgunMessage = await response.json(); | 
					
						
							|  |  |  |     const smartmail = | 
					
						
							|  |  |  |       new plugins.smartmail.Smartmail<interfaces.IMailgunMessage>({ | 
					
						
							|  |  |  |         from: responseBody.From, | 
					
						
							|  |  |  |         body: responseBody['body-html'], | 
					
						
							|  |  |  |         subject: responseBody.Subject, | 
					
						
							|  |  |  |         creationObjectRef: responseBody, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // lets care about attachments
 | 
					
						
							| 
									
										
										
										
											2020-01-21 10:04:28 +00:00
										 |  |  |     if (responseBody.attachments && responseBody.attachments instanceof Array) { | 
					
						
							|  |  |  |       for (const attachmentInfo of responseBody.attachments) { | 
					
						
							|  |  |  |         const attachmentName = attachmentInfo.name; | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |         const attachmentContents = await this.getRequest( | 
					
						
							|  |  |  |           attachmentInfo.url, | 
					
						
							|  |  |  |           true, | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         const arrayBuffer = await attachmentContents.arrayBuffer(); | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  |         smartmail.addAttachment( | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |           new plugins.smartfile.SmartFile({ | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  |             path: `./${attachmentName}`, | 
					
						
							|  |  |  |             base: `./${attachmentName}`, | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |             contentBuffer: Buffer.from(arrayBuffer), | 
					
						
							|  |  |  |           }), | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  |         ); | 
					
						
							| 
									
										
										
										
											2020-01-21 10:04:28 +00:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-13 08:09:37 +00:00
										 |  |  |     return smartmail; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-06-18 22:00:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  |   public async retrieveSmartMailFromNotifyPayload(notifyPayloadArg: any) { | 
					
						
							| 
									
										
										
										
											2025-10-13 20:20:24 +00:00
										 |  |  |     return await this.retrieveSmartMailFromMessageUrl( | 
					
						
							|  |  |  |       notifyPayloadArg['message-url'], | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2020-01-11 19:01:59 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-10-26 23:55:50 +02:00
										 |  |  | } |