196 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import * as plugins from './mailgun.plugins.js';
 | |
| import * as interfaces from './interfaces/index.js';
 | |
| 
 | |
| export interface IMailgunAccountContructorOptions {
 | |
|   apiToken: string;
 | |
|   region: 'eu' | 'us';
 | |
| }
 | |
| 
 | |
| export class MailgunAccount {
 | |
|   public apiBaseUrl: string;
 | |
| 
 | |
|   public options: IMailgunAccountContructorOptions;
 | |
| 
 | |
|   public smartSmtps: { [domain: string]: plugins.smartsmtp.Smartsmtp } = {};
 | |
| 
 | |
|   constructor(optionsArg: IMailgunAccountContructorOptions) {
 | |
|     this.options = optionsArg;
 | |
|     this.apiBaseUrl =
 | |
|       this.options.region === 'eu'
 | |
|         ? 'https://api.eu.mailgun.net/v3'
 | |
|         : 'https://api..mailgun.net/v3';
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * allows adding smtp credentials
 | |
|    * Format: [domain]|[username]|[password]
 | |
|    */
 | |
|   public async addSmtpCredentials(credentials: string) {
 | |
|     const credentialArray = credentials.split('|');
 | |
|     if (credentialArray.length !== 3) {
 | |
|       throw new Error('credentials are in the wrong format');
 | |
|     }
 | |
|     this.smartSmtps[credentialArray[0]] =
 | |
|       await plugins.smartsmtp.Smartsmtp.createSmartsmtpWithRelay({
 | |
|         smtpServer: 'smtp.eu.mailgun.org',
 | |
|         smtpUser: credentialArray[1],
 | |
|         smtpPassword: credentialArray[2],
 | |
|       });
 | |
|   }
 | |
| 
 | |
|   public async getRequest(routeArg: string, binaryArg: boolean = false) {
 | |
|     let requestUrl = routeArg;
 | |
|     const needsBaseUrlPrefix = !routeArg.startsWith('https://');
 | |
|     if (needsBaseUrlPrefix) {
 | |
|       requestUrl = `${this.apiBaseUrl}${routeArg}`;
 | |
|     }
 | |
|     console.log(requestUrl);
 | |
|     const response = await plugins.smartrequest.SmartRequest.create()
 | |
|       .url(requestUrl)
 | |
|       .headers({
 | |
|         Authorization: `Basic ${plugins.smartstring.base64.encode(`api:${this.options.apiToken}`)}`,
 | |
|         'Content-Type': 'application/json',
 | |
|       })
 | |
|       .options({ keepAlive: false })
 | |
|       .get();
 | |
|     return response;
 | |
|   }
 | |
| 
 | |
|   public async postFormData(
 | |
|     routeArg: string,
 | |
|     formFields: plugins.smartrequest.FormField[],
 | |
|   ) {
 | |
|     const requestUrl = `${this.apiBaseUrl}${routeArg}`;
 | |
|     console.log(requestUrl);
 | |
|     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();
 | |
|     return response;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * sends a SmartMail
 | |
|    */
 | |
|   public async sendSmartMail(
 | |
|     smartmailArg: plugins.smartmail.Smartmail<interfaces.IMailgunMessage>,
 | |
|     toArg: string,
 | |
|     dataArg = {},
 | |
|   ) {
 | |
|     const domain = smartmailArg.options.from.split('@')[1].replace('>', '');
 | |
|     const formFields: plugins.smartrequest.FormField[] = [
 | |
|       {
 | |
|         name: 'from',
 | |
|         value: smartmailArg.options.from,
 | |
|       },
 | |
|       {
 | |
|         name: 'to',
 | |
|         value: toArg,
 | |
|       },
 | |
|       {
 | |
|         name: 'subject',
 | |
|         value: smartmailArg.getSubject(dataArg),
 | |
|       },
 | |
|       {
 | |
|         name: 'html',
 | |
|         value: smartmailArg.getBody(dataArg),
 | |
|       },
 | |
|     ];
 | |
| 
 | |
|     console.log(smartmailArg.attachments);
 | |
| 
 | |
|     for (const attachment of smartmailArg.attachments) {
 | |
|       formFields.push({
 | |
|         name: 'attachment',
 | |
|         value: attachment.contentBuffer,
 | |
|         filename: attachment.parsedPath.base,
 | |
|       });
 | |
|     }
 | |
| 
 | |
|     if (smartmailArg.getBody(dataArg)) {
 | |
|       console.log('All requirements for API met');
 | |
|       const response = await this.postFormData(
 | |
|         `/${domain}/messages`,
 | |
|         formFields,
 | |
|       );
 | |
|       if (response.status === 200) {
 | |
|         console.log(
 | |
|           `Sent mail with subject ${smartmailArg.getSubject(
 | |
|             dataArg,
 | |
|           )} to ${toArg} using the mailgun API`,
 | |
|         );
 | |
|         return await response.json();
 | |
|       } else {
 | |
|         console.log(await response.json());
 | |
|         throw new Error('could not send email');
 | |
|       }
 | |
|     } else {
 | |
|       console.log(
 | |
|         'An empty body was provided. This does not work via the API, but using SMTP instead.',
 | |
|       );
 | |
|       const wantedSmartsmtp = this.smartSmtps[domain];
 | |
|       if (!wantedSmartsmtp) {
 | |
|         console.log('did not find appropriate smtp credentials');
 | |
|         return;
 | |
|       }
 | |
|       await wantedSmartsmtp.sendSmartMail(smartmailArg, toArg);
 | |
|       console.log(
 | |
|         `Sent mail with subject "${smartmailArg.getSubject(
 | |
|           dataArg,
 | |
|         )}" to "${toArg}" using an smtp transport over Mailgun.`,
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   public async retrieveSmartMailFromMessageUrl(messageUrlArg: string) {
 | |
|     console.log(`retrieving message for ${messageUrlArg}`);
 | |
|     const response = await this.getRequest(messageUrlArg);
 | |
|     if (response.status === 404) {
 | |
|       const body: any = await response.json();
 | |
|       console.log(body.message);
 | |
|       return null;
 | |
|     }
 | |
|     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,
 | |
|       });
 | |
| 
 | |
|     // lets care about attachments
 | |
|     if (responseBody.attachments && responseBody.attachments instanceof Array) {
 | |
|       for (const attachmentInfo of responseBody.attachments) {
 | |
|         const attachmentName = attachmentInfo.name;
 | |
|         const attachmentContents = await this.getRequest(
 | |
|           attachmentInfo.url,
 | |
|           true,
 | |
|         );
 | |
|         const arrayBuffer = await attachmentContents.arrayBuffer();
 | |
|         smartmail.addAttachment(
 | |
|           new plugins.smartfile.SmartFile({
 | |
|             path: `./${attachmentName}`,
 | |
|             base: `./${attachmentName}`,
 | |
|             contentBuffer: Buffer.from(arrayBuffer),
 | |
|           }),
 | |
|         );
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return smartmail;
 | |
|   }
 | |
| 
 | |
|   public async retrieveSmartMailFromNotifyPayload(notifyPayloadArg: any) {
 | |
|     return await this.retrieveSmartMailFromMessageUrl(
 | |
|       notifyPayloadArg['message-url'],
 | |
|     );
 | |
|   }
 | |
| }
 |