phonepe #31

Merged
allentj merged 12 commits from phonepe into dev 2025-05-20 08:22:03 +00:00
4 changed files with 67 additions and 32 deletions
Showing only changes of commit f62dfdfad2 - Show all commits

View File

@ -11,14 +11,14 @@
"@aws-sdk/client-ses": "^3.798.0",
"@types/node-fetch": "^2.6.12",
"aws-sdk": "^2.1692.0",
"axios": "^1.8.4",
"axios": "^1.9.0",
"cors": "^2.8.5",
"firebase-admin": "^12.6.0",
"firebase-functions": "^6.0.1",
"form-data": "^4.0.1",
"functions": "file:",
"html-to-text": "^9.0.5",
"long": "^4.0.0",
"long": "^5.3.2",
"mailgun.js": "^10.4.0",
"node-fetch": "^2.7.0",
"pdfjs-dist": "^5.0.375",
@ -1373,12 +1373,6 @@
"node": ">=6"
}
},
"node_modules/@grpc/proto-loader/node_modules/long": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"optional": true
},
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@ -2755,6 +2749,7 @@
"integrity": "sha512-eQs9RsucA/LNjnMoJvWG/nXa7Pot/RbBzilF/QRIU/xRl+0ApxrSUFsV5lmf01SvSlqMzJ7Zwxe440wmz2SJGA==",
"deprecated": "This is a stub types definition. long provides its own type definitions, so you do not need this installed.",
"dev": true,
"license": "MIT",
"dependencies": {
"long": "*"
}
@ -3051,6 +3046,7 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
"integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@ -6059,9 +6055,10 @@
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
"node_modules/long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
"license": "Apache-2.0"
},
"node_modules/lru-cache": {
"version": "5.1.1",
@ -6687,11 +6684,6 @@
"node": ">=12.0.0"
}
},
"node_modules/protobufjs/node_modules/long": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",

View File

@ -18,14 +18,14 @@
"@aws-sdk/client-ses": "^3.798.0",
"@types/node-fetch": "^2.6.12",
"aws-sdk": "^2.1692.0",
"axios": "^1.8.4",
"axios": "^1.9.0",
"cors": "^2.8.5",
"firebase-admin": "^12.6.0",
"firebase-functions": "^6.0.1",
"form-data": "^4.0.1",
"functions": "file:",
"html-to-text": "^9.0.5",
"long": "^4.0.0",
"long": "^5.3.2",
"mailgun.js": "^10.4.0",
"node-fetch": "^2.7.0",
"pdfjs-dist": "^5.0.375",

View File

@ -6,6 +6,7 @@ import { SESClient } from "@aws-sdk/client-ses";
import { SendEmailCommand, SendRawEmailCommand } from "@aws-sdk/client-ses";
import { HttpsError } from "firebase-functions/v2/https";
import * as mime from 'mime-types';
import axios from 'axios';
const logger = getLogger();
const corsHandler = getCorsHandler();
@ -18,6 +19,8 @@ interface EmailRequest {
from: string;
replyTo?: string;
attachments?: Attachment[];
fileUrl?: string;
fileName?: string;
}
interface Attachment {
@ -121,31 +124,71 @@ async function sendEmailWithAttachments(data: EmailRequest, recipients: string[]
return { messageId: result.MessageId };
}
async function downloadFileFromUrl(url: string): Promise<Buffer> {
try {
const response = await axios.get(url, { responseType: 'arraybuffer' });
return Buffer.from(response.data);
} catch (error) {
logger.error(`Error downloading file from URL: ${error}`);
throw new Error(`Failed to download file: ${error}`);
}
}
export const sendEmailSES = onRequest({
region: 'asia-south1'
}, (request: Request, response) => {
return corsHandler(request, response, async () => {
const toAddress = request.body.toAddress;
const subject = request.body.subject;
const message = request.body.message;
const data: EmailRequest = {
to: toAddress,
subject: subject,
html: message,
text: stripHtml(message),
from: process.env.SES_FROM_EMAIL || 'support@fitlien.com',
replyTo: process.env.SES_REPLY_TO_EMAIL || 'support@fitlien.com',
attachments: request.body.attachments as Attachment[] || []
};
try {
const toAddress = request.body.toAddress;
const subject = request.body.subject;
const message = request.body.message;
// Initialize data with basic fields
const data: EmailRequest = {
to: toAddress,
html: message,
subject: subject,
text: stripHtml(message),
from: process.env.SES_FROM_EMAIL || 'support@fitlien.com',
replyTo: process.env.SES_REPLY_TO_EMAIL || 'support@fitlien.com',
attachments: request.body.attachments as Attachment[] || []
};
// Handle file URL if provided
if (request.body.fileUrl && request.body.fileName) {
logger.info(`Downloading attachment from URL: ${request.body.fileUrl}`);
try {
const fileContent = await downloadFileFromUrl(request.body.fileUrl);
// If attachments array doesn't exist, create it
if (!data.attachments) {
data.attachments = [];
}
// Add the downloaded file as an attachment
data.attachments.push({
filename: request.body.fileName,
content: fileContent,
contentType: mime.lookup(request.body.fileName) || 'application/octet-stream'
});
logger.info(`Successfully downloaded attachment: ${request.body.fileName}`);
} catch (downloadError) {
logger.error(`Failed to download attachment: ${downloadError}`);
throw new Error(`Failed to process attachment: ${downloadError}`);
}
}
if (!data.to || !data.subject || !data.html || !data.from) {
throw new HttpsError(
'invalid-argument',
'Missing required email fields'
);
}
logger.info(`Sending Email '${data.subject}' to '${data.to}' from '${data.from}'`);
const recipients = Array.isArray(data.to) ? data.to : [data.to];
if (data.attachments && data.attachments.length > 0) {
const messageResult = await sendEmailWithAttachments(data, recipients);
response.status(200).json(messageResult);