Node.js中如何从Firebase Storage取文件并通过Mailgun发邮件?代码遇阻
在Node.js中用Firebase Storage + Mailgun发送带附件的邮件
核心疑问解答:能不能直接从Firebase Storage附加文件?
不行哦,Mailgun的附件不支持直接使用Firebase Storage的gs://路径——它只认本地文件路径、Buffer数据或是可读流。所以我们得先把Firebase Storage里的文件内容取出来,再传给Mailgun。
正确实现步骤
1. 安装必要依赖
首先确保你安装了所需的包:
npm install firebase-admin mailgun-js temp
(temp用来创建临时文件,如果你选择用Buffer方式发送,可以不用这个包)
2. 初始化Firebase Admin和Mailgun
先配置好Firebase Admin的服务账号(你可以从Firebase控制台下载JSON密钥文件),再初始化Mailgun:
const admin = require('firebase-admin'); const mailgun = require('mailgun-js'); const temp = require('temp'); const path = require('path'); const fs = require('fs'); // 初始化Firebase Admin const serviceAccount = require('./path-to-your-service-account-key.json'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), storageBucket: 'i-m-here-c01f6.appspot.com' // 替换成你的存储桶名称 }); // 初始化Mailgun const api_key = 'key-acf9f881e32c85b3c0dad34358507a95'; const DOMAIN = 'sandbox76c6f74ddab14862816390c16f37a272.mailgun.org'; const mg = mailgun({apiKey: api_key, domain: DOMAIN});
3. 方法一:下载到临时文件再发送
这种方法适合处理较大的文件,避免占用过多内存:
async function sendEmailWithAttachment(leaderId) { // 获取Firebase Storage文件引用 const bucket = admin.storage().bucket(); const fileRef = bucket.file(`Groups/${leaderId}/group_image.jpg`); // 创建临时文件 temp.track(); // 自动清理临时文件 const tempFile = temp.path({suffix: '.jpg'}); try { // 下载文件到临时路径 await fileRef.download({destination: tempFile}); // 准备邮件数据 const data = { from: 'Excited User <your-email@example.com>', to: 'recipient@example.com', subject: '带有Firebase Storage附件的邮件', text: '这是测试邮件,附件来自Firebase Storage', attachment: tempFile // 直接用临时文件路径 }; // 发送邮件 await mg.messages().send(data); console.log('邮件发送成功!'); } catch (error) { console.error('发送失败:', error); } finally { // 手动兜底清理临时文件(如果temp.track()没生效的话) if (fs.existsSync(tempFile)) { fs.unlinkSync(tempFile); } } } // 调用函数,传入你的leaderId sendEmailWithAttachment('your-leader-id-here');
4. 方法二:用Buffer直接发送(适合小文件)
如果文件不大,直接把文件内容转成Buffer传给Mailgun更高效:
async function sendEmailWithBufferAttachment(leaderId) { const bucket = admin.storage().bucket(); const fileRef = bucket.file(`Groups/${leaderId}/group_image.jpg`); try { // 获取文件Buffer数据 const [fileContent] = await fileRef.download(); // 准备邮件数据,附件用Buffer const data = { from: 'Excited User <your-email@example.com>', to: 'recipient@example.com', subject: '带有Firebase Storage附件的邮件', text: '这是测试邮件,附件来自Firebase Storage', attachment: { filename: 'group_image.jpg', data: fileContent } }; await mg.messages().send(data); console.log('邮件发送成功!'); } catch (error) { console.error('发送失败:', error); } } // 调用函数,传入你的leaderId sendEmailWithBufferAttachment('your-leader-id-here');
你原来代码的问题
- 重复声明了
var mailgun变量,导致后面的初始化覆盖了前面的引用 - 直接使用
gs://路径作为附件,Mailgun无法识别这个云端路径,必须先下载到本地或转成Buffer才能使用
内容的提问来源于stack exchange,提问作者Mustafa Alawami
相关产品推荐
相关产品推荐

