Compare commits
No commits in common. "f62dfdfad2b40332f80a943f63358b6e910d80b9" and "e8710074c41a1e047b7eaa5a81f3dd4efd8829a4" have entirely different histories.
f62dfdfad2
...
e8710074c4
24
functions/package-lock.json
generated
24
functions/package-lock.json
generated
@ -11,14 +11,14 @@
|
|||||||
"@aws-sdk/client-ses": "^3.798.0",
|
"@aws-sdk/client-ses": "^3.798.0",
|
||||||
"@types/node-fetch": "^2.6.12",
|
"@types/node-fetch": "^2.6.12",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.8.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"firebase-admin": "^12.6.0",
|
"firebase-admin": "^12.6.0",
|
||||||
"firebase-functions": "^6.0.1",
|
"firebase-functions": "^6.0.1",
|
||||||
"form-data": "^4.0.1",
|
"form-data": "^4.0.1",
|
||||||
"functions": "file:",
|
"functions": "file:",
|
||||||
"html-to-text": "^9.0.5",
|
"html-to-text": "^9.0.5",
|
||||||
"long": "^5.3.2",
|
"long": "^4.0.0",
|
||||||
"mailgun.js": "^10.4.0",
|
"mailgun.js": "^10.4.0",
|
||||||
"node-fetch": "^2.7.0",
|
"node-fetch": "^2.7.0",
|
||||||
"pdfjs-dist": "^5.0.375",
|
"pdfjs-dist": "^5.0.375",
|
||||||
@ -1373,6 +1373,12 @@
|
|||||||
"node": ">=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": {
|
"node_modules/@istanbuljs/load-nyc-config": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
|
||||||
@ -2749,7 +2755,6 @@
|
|||||||
"integrity": "sha512-eQs9RsucA/LNjnMoJvWG/nXa7Pot/RbBzilF/QRIU/xRl+0ApxrSUFsV5lmf01SvSlqMzJ7Zwxe440wmz2SJGA==",
|
"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.",
|
"deprecated": "This is a stub types definition. long provides its own type definitions, so you do not need this installed.",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"long": "*"
|
"long": "*"
|
||||||
}
|
}
|
||||||
@ -3046,7 +3051,6 @@
|
|||||||
"version": "1.9.0",
|
"version": "1.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz",
|
||||||
"integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
|
"integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.6",
|
"follow-redirects": "^1.15.6",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
@ -6055,10 +6059,9 @@
|
|||||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
||||||
},
|
},
|
||||||
"node_modules/long": {
|
"node_modules/long": {
|
||||||
"version": "5.3.2",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
|
||||||
"integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
|
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/lru-cache": {
|
"node_modules/lru-cache": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.1",
|
||||||
@ -6684,6 +6687,11 @@
|
|||||||
"node": ">=12.0.0"
|
"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": {
|
"node_modules/proxy-addr": {
|
||||||
"version": "2.0.7",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
|
||||||
|
|||||||
@ -18,14 +18,14 @@
|
|||||||
"@aws-sdk/client-ses": "^3.798.0",
|
"@aws-sdk/client-ses": "^3.798.0",
|
||||||
"@types/node-fetch": "^2.6.12",
|
"@types/node-fetch": "^2.6.12",
|
||||||
"aws-sdk": "^2.1692.0",
|
"aws-sdk": "^2.1692.0",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.8.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"firebase-admin": "^12.6.0",
|
"firebase-admin": "^12.6.0",
|
||||||
"firebase-functions": "^6.0.1",
|
"firebase-functions": "^6.0.1",
|
||||||
"form-data": "^4.0.1",
|
"form-data": "^4.0.1",
|
||||||
"functions": "file:",
|
"functions": "file:",
|
||||||
"html-to-text": "^9.0.5",
|
"html-to-text": "^9.0.5",
|
||||||
"long": "^5.3.2",
|
"long": "^4.0.0",
|
||||||
"mailgun.js": "^10.4.0",
|
"mailgun.js": "^10.4.0",
|
||||||
"node-fetch": "^2.7.0",
|
"node-fetch": "^2.7.0",
|
||||||
"pdfjs-dist": "^5.0.375",
|
"pdfjs-dist": "^5.0.375",
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { SESClient } from "@aws-sdk/client-ses";
|
|||||||
import { SendEmailCommand, SendRawEmailCommand } from "@aws-sdk/client-ses";
|
import { SendEmailCommand, SendRawEmailCommand } from "@aws-sdk/client-ses";
|
||||||
import { HttpsError } from "firebase-functions/v2/https";
|
import { HttpsError } from "firebase-functions/v2/https";
|
||||||
import * as mime from 'mime-types';
|
import * as mime from 'mime-types';
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
const logger = getLogger();
|
const logger = getLogger();
|
||||||
const corsHandler = getCorsHandler();
|
const corsHandler = getCorsHandler();
|
||||||
@ -19,8 +18,6 @@ interface EmailRequest {
|
|||||||
from: string;
|
from: string;
|
||||||
replyTo?: string;
|
replyTo?: string;
|
||||||
attachments?: Attachment[];
|
attachments?: Attachment[];
|
||||||
fileUrl?: string;
|
|
||||||
fileName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Attachment {
|
interface Attachment {
|
||||||
@ -124,71 +121,31 @@ async function sendEmailWithAttachments(data: EmailRequest, recipients: string[]
|
|||||||
return { messageId: result.MessageId };
|
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({
|
export const sendEmailSES = onRequest({
|
||||||
region: 'asia-south1'
|
region: 'asia-south1'
|
||||||
}, (request: Request, response) => {
|
}, (request: Request, response) => {
|
||||||
return corsHandler(request, response, async () => {
|
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 {
|
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) {
|
if (!data.to || !data.subject || !data.html || !data.from) {
|
||||||
throw new HttpsError(
|
throw new HttpsError(
|
||||||
'invalid-argument',
|
'invalid-argument',
|
||||||
'Missing required email fields'
|
'Missing required email fields'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Sending Email '${data.subject}' to '${data.to}' from '${data.from}'`);
|
logger.info(`Sending Email '${data.subject}' to '${data.to}' from '${data.from}'`);
|
||||||
const recipients = Array.isArray(data.to) ? data.to : [data.to];
|
const recipients = Array.isArray(data.to) ? data.to : [data.to];
|
||||||
|
|
||||||
if (data.attachments && data.attachments.length > 0) {
|
if (data.attachments && data.attachments.length > 0) {
|
||||||
const messageResult = await sendEmailWithAttachments(data, recipients);
|
const messageResult = await sendEmailWithAttachments(data, recipients);
|
||||||
response.status(200).json(messageResult);
|
response.status(200).json(messageResult);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user