aboutsummaryrefslogtreecommitdiff
path: root/src/integrations/email.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-12-15 20:17:22 -0800
committerElizabeth Hunt <me@liz.coffee>2025-12-15 20:19:43 -0800
commit2814d5520623efe5f48c26f639d3ed6cc5f0d8d2 (patch)
tree3fc1af65dac5ed55aceaab7574b22fea32cad86a /src/integrations/email.ts
parent2e41f030f02a336c2e9866d3d56b0494da5a622e (diff)
downloadposthook-2814d5520623efe5f48c26f639d3ed6cc5f0d8d2.tar.gz
posthook-2814d5520623efe5f48c26f639d3ed6cc5f0d8d2.zip
Add email integration
Diffstat (limited to 'src/integrations/email.ts')
-rw-r--r--src/integrations/email.ts69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/integrations/email.ts b/src/integrations/email.ts
new file mode 100644
index 0000000..aa4c36c
--- /dev/null
+++ b/src/integrations/email.ts
@@ -0,0 +1,69 @@
+import { Either, type IEither } from '@emprespresso/pengueno';
+import type { EmailConfig, StoredRequest } from '../types/index.js';
+import nodemailer from 'nodemailer';
+
+export async function sendEmailNotification(config: EmailConfig, request: StoredRequest): Promise<IEither<Error, void>> {
+ if (!config.enabled || !config.to || !config.from) {
+ return Either.right(<void>undefined);
+ }
+
+ return Either.fromFailableAsync(async () => {
+ // Create transporter based on configuration
+ const transporter = nodemailer.createTransport({
+ host: config.host || 'localhost',
+ port: config.port || 25,
+ secure: config.secure ?? false,
+ auth: config.username && config.password
+ ? {
+ user: config.username,
+ pass: config.password,
+ }
+ : undefined,
+ });
+
+ const subject = config.subject || `Webhook received: ${request.routeName}`;
+
+ // Build email body
+ let htmlBody = `
+ <h2>Webhook Notification</h2>
+ <p><strong>Route:</strong> ${request.routeName}</p>
+ <p><strong>Method:</strong> ${request.method}</p>
+ <p><strong>Timestamp:</strong> ${new Date(request.timestamp).toISOString()}</p>
+ <p><strong>UUID:</strong> ${request.uuid}</p>
+ `;
+
+ if (config.includeBody && request.body !== undefined) {
+ htmlBody += `
+ <h3>Request Body:</h3>
+ <pre>${JSON.stringify(request.body, null, 2)}</pre>
+ `;
+ }
+
+ if (config.includeHeaders && request.headers) {
+ htmlBody += `
+ <h3>Headers:</h3>
+ <pre>${JSON.stringify(request.headers, null, 2)}</pre>
+ `;
+ }
+
+ if (request.files && request.files.length > 0) {
+ htmlBody += `
+ <h3>Uploaded Files:</h3>
+ <ul>
+ ${request.files.map(f => `<li>${f.originalFilename} (${f.contentType}, ${f.size} bytes)</li>`).join('')}
+ </ul>
+ `;
+ }
+
+ const mailOptions = {
+ from: config.from,
+ to: config.to,
+ subject: subject,
+ html: htmlBody,
+ };
+
+ await transporter.sendMail(mailOptions);
+
+ return <void>undefined;
+ });
+}