如何通过Azure Communication Services用JS实现隐私批量发邮件及邮箱导入
Azure Communication Services 批量邮件发送解决方案
1. 实现收件人不可见的核心思路
要让收件人看不到其他收件人,绝对不能在同一个邮件的to数组中添加多个收件人,必须为每个收件人单独创建并发送一封邮件。这样每封邮件的收件人列表里只有单个用户,自然不会泄露其他收件人的信息。
2. 从文本/Excel文件导入收件人
文本文件导入(每行一个邮箱)
用Node.js内置的fs模块读取文本文件,按行分割提取有效邮箱地址。
Excel文件导入
使用xlsx库解析Excel文件,指定工作表和邮箱所在列提取数据,需要先安装依赖:npm install xlsx
3. 单独发送每封邮件的实现
遍历导入的收件人列表,逐个构造邮件对象并调用EmailClient.send方法。为避免并发请求过多触发频率限制,采用串行发送方式(也可根据需求调整并发数)。
完整实现代码
const { EmailClient } = require("@azure/communication-email"); const fs = require("fs"); const xlsx = require("xlsx"); // ACS配置信息 const connectionString = "endpoint=https://callandsms.communication.azure.com/;accesskey=xxxxxxxxxxxxxxxxxxxxxxx"; const sender = "support@xxxxx.azurecomm.net"; const emailContent = { subject: "ACS 批量邮件测试", plainText: "这是一封批量发送的测试邮件,您是唯一收件人。\n\n 测试内容:Azure Communication Services 批量邮件功能", html: "<html><head><title>ACS 批量邮件测试</title></head><body><h1>ACS 批量邮件测试</h1><p>这是一封批量发送的测试邮件,您是唯一收件人。</p></body></html>", }; // 从文本文件读取收件人(每行一个邮箱) function getRecipientsFromTxt(filePath) { const content = fs.readFileSync(filePath, "utf-8"); return content.split("\n").filter(email => email.trim() !== ""); } // 从Excel文件读取收件人(假设邮箱在第一列,工作表名为Sheet1) function getRecipientsFromExcel(filePath) { const workbook = xlsx.readFile(filePath); const worksheet = workbook.Sheets["Sheet1"]; const data = xlsx.utils.sheet_to_json(worksheet, { header: ["email"] }); // 跳过表头(如果第一行是表头) return data.slice(1).map(item => item.email.trim()).filter(email => email !== ""); } // 检查邮件发送状态 async function checkEmailStatus(client, messageId) { let counter = 0; return new Promise((resolve) => { const statusInterval = setInterval(async () => { counter++; try { const response = await client.getSendStatus(messageId); console.log(`邮件 ${messageId} 状态: [${response.status}]`); if (response.status.toLowerCase() !== "queued" || counter > 12) { clearInterval(statusInterval); resolve(response.status); } } catch (e) { console.log(`检查邮件 ${messageId} 状态失败:`, e); clearInterval(statusInterval); resolve("error"); } }, 5000); }); } // 发送单封邮件 async function sendSingleEmail(client, recipientEmail) { try { const emailMessage = { sender: sender, content: emailContent, recipients: { to: [{ email: recipientEmail, displayName: recipientEmail.split("@")[0] }] }, }; const sendResult = await client.send(emailMessage); if (sendResult && sendResult.messageId) { console.log(`发送邮件到 ${recipientEmail} 成功,MessageId: ${sendResult.messageId}`); await checkEmailStatus(client, sendResult.messageId); return true; } else { console.error(`发送邮件到 ${recipientEmail} 失败:`, sendResult); return false; } } catch (e) { console.log(`发送邮件到 ${recipientEmail} 时出错:`, e); return false; } } // 批量发送主函数 async function main() { const client = new EmailClient(connectionString); // 选择导入方式:文本文件或Excel // const recipients = getRecipientsFromTxt("./recipients.txt"); const recipients = getRecipientsFromExcel("./recipients.xlsx"); if (recipients.length === 0) { console.log("未找到有效收件人"); return; } console.log(`开始发送 ${recipients.length} 封邮件...`); // 串行发送每封邮件,避免并发过高 for (const recipient of recipients) { await sendSingleEmail(client, recipient); // 可选:每发送一封延迟1秒,规避频率限制 await new Promise(resolve => setTimeout(resolve, 1000)); } console.log("批量发送任务完成"); } main();
代码关键说明
- 收件人隔离:
sendSingleEmail函数为每个收件人单独构造邮件,to数组仅包含单个用户,确保收件人看不到其他收件人信息。 - 文件导入逻辑:
- 文本文件:读取后按行分割,自动过滤空行和无效邮箱。
- Excel文件:解析指定工作表,提取第一列的邮箱地址,自动跳过表头行。
- 发送控制:采用
for...of循环串行发送,添加可选延迟避免触发ACS的请求频率限制。 - 状态监控:封装
checkEmailStatus函数,异步跟踪每封邮件的发送状态,直到状态稳定或超时(60秒)。
内容的提问来源于stack exchange,提问作者Abderrahmane Abidi
相关产品推荐
相关产品推荐

