notamitgamer

It's my profile man, there is ...
Log | Files | Refs | README

commit de0c4d11e0d980ec6a1647a1c64fbac6a707fb44
parent 3d0d5ef136d7080af3ad16b19bcc1b7191f1a33a
Author: Amit Dutta <amitdutta4255@gmail.com>
Date:   Sun, 22 Feb 2026 14:06:22 +0530

render

Diffstat:
Drouter | 1-
Aserver.js | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 97 insertions(+), 1 deletion(-)

diff --git a/router b/router @@ -1 +0,0 @@ -Subproject commit 51a740e8eeae845e2d118f55bf53982bf130a14f diff --git a/server.js b/server.js @@ -0,0 +1,96 @@ +const express = require('express'); +const { Resend } = require('resend'); +const { Webhook } = require('svix'); + +const app = express(); +const port = process.env.PORT || 3000; + +// Initialize Resend +const resend = new Resend(process.env.RESEND_API_KEY); +const webhookSecret = process.env.RESEND_WEBHOOK_SECRET; + +// We use express.text to get the raw string body needed for Svix verification +app.post('/api/incoming', express.text({ type: 'application/json' }), async (req, res) => { + try { + const rawBody = req.body; + const headers = { + 'svix-id': req.headers['svix-id'], + 'svix-timestamp': req.headers['svix-timestamp'], + 'svix-signature': req.headers['svix-signature'], + }; + + // 1. Verify Signature to prevent spam/abuse + const wh = new Webhook(webhookSecret); + let event; + + try { + event = wh.verify(rawBody, headers); + } catch (err) { + console.error('Webhook signature verification failed.', err.message); + return res.status(400).json({ error: 'Invalid signature' }); + } + + // 2. Ensure it's the right event + if (event.type !== 'email.received') { + return res.status(200).json({ message: 'Not an email event' }); + } + + // 3. Extract data + const emailData = event.data; + const originalSender = emailData.from; + const originalRecipient = emailData.to[0].toLowerCase(); // e.g., admin@amit.is-a.dev + const subject = emailData.subject || 'No Subject'; + + // 4. Quota Protection (The Bouncer) + const allowedString = process.env.ALLOWED_ALIASES || ''; + const allowedAliases = allowedString.split(',').map(alias => alias.trim().toLowerCase()); + + if (!allowedAliases.includes(originalRecipient)) { + console.log(`Blocked email to unapproved alias: ${originalRecipient}`); + // Return 200 OK so Resend doesn't retry + return res.status(200).json({ success: true, message: 'Alias ignored' }); + } + + // 5. Forwarding Setup + const personalGmail = process.env.PERSONAL_GMAIL; + const forwardingAddress = process.env.FORWARDING_BOT_ADDRESS; + + // 6. Send the forwarded email + const { data, error } = await resend.emails.send({ + from: `Dev Inbox <${forwardingAddress}>`, + to: [personalGmail], + replyTo: originalSender, + subject: `[${originalRecipient.split('@')[0]}] ${subject}`, + html: ` + <div style="background-color: #f3f4f6; padding: 12px; margin-bottom: 20px; border-radius: 6px; font-family: sans-serif; font-size: 14px; color: #374151;"> + <strong>From:</strong> ${originalSender}<br> + <strong>To:</strong> ${originalRecipient} + </div> + ${emailData.html || `<p>${emailData.text}</p>` || '<p>No content.</p>'} + `, + text: `From: ${originalSender}\nTo: ${originalRecipient}\n\n${emailData.text || 'No content.'}`, + }); + + if (error) { + console.error('Resend forward failed:', error); + return res.status(500).json({ error: error.message }); + } + + console.log(`Successfully forwarded email to ${personalGmail}`); + return res.status(200).json({ success: true, id: data?.id }); + + } catch (error) { + console.error('Server error:', error); + return res.status(500).json({ error: 'Internal Server Error' }); + } +}); + +// --- UPTIMEROBOT PING ROUTE --- +// Point UptimeRobot to https://your-render-url.onrender.com/ping +app.get('/ping', (req, res) => { + res.status(200).send('Server is awake!'); +}); + +app.listen(port, () => { + console.log(`Email router listening on port ${port}`); +});+ \ No newline at end of file
© notamitgamer • Site Built: 2026-07-21 13:58:23 UTC • git-mirror commit: 1037f62 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror