部署在Firebase Functions的NestJS如何发送表单数据至关联Gmail?
可行方案说明
针对你的需求,有几种可行方案,并非必须依赖第三方SMTP服务,下面逐一说明:
方案1:Nodemailer + Gmail 原生SMTP(无需第三方服务)
这是最直接的实现方式,用Nodemailer配合Gmail自身的SMTP服务器发送邮件,提供两种认证方式:
方式A:应用专用密码(适合开启2FA的谷歌账户)
步骤:- 开启谷歌账户的两步验证
- 在谷歌账户安全设置中生成应用专用密码
- 安装依赖:
npm install nodemailer - 在NestJS中创建邮件服务:
import { Injectable } from '@nestjs/common'; import * as nodemailer from 'nodemailer'; @Injectable() export class MailService { private transporter; constructor() { this.transporter = nodemailer.createTransport({ service: 'gmail', auth: { user: '你的管理员Gmail邮箱', pass: '生成的应用专用密码', }, }); } async sendContactForm(formData: any) { const mailOptions = { from: formData.userEmail, // 也可固定为你的邮箱,在邮件内容中注明用户信息 to: '你的管理员Gmail邮箱', subject: `新联系表单提交:${formData.subject}`, text: `用户姓名:${formData.name}\n用户邮箱:${formData.userEmail}\n留言内容:${formData.message}`, }; return this.transporter.sendMail(mailOptions); } } - 在API控制器中注入该服务,验证表单数据后调用
sendContactForm方法即可
方式B:OAuth2认证(生产环境推荐,更安全)
这种方式无需暴露密码,需在谷歌云控制台配置OAuth2凭据:- 登录谷歌云控制台,创建项目并启用Gmail API
- 创建OAuth 2.0客户端ID,设置授权回调地址(本地开发用
http://localhost:3000,生产环境用你的Firebase Functions域名) - 获取客户端ID、客户端密钥、刷新令牌
- 配置Nodemailer transporter:
this.transporter = nodemailer.createTransport({ service: 'gmail', auth: { type: 'OAuth2', user: '你的管理员Gmail邮箱', clientId: '你的客户端ID', clientSecret: '你的客户端密钥', refreshToken: '你的刷新令牌', }, });
方案2:使用Firebase Trigger Email 扩展(无需维护邮件发送逻辑)
该方案利用Firebase官方扩展,只需在NestJS中往Firestore写入数据,扩展会自动触发邮件发送,无需自己处理邮件底层逻辑:
- 步骤:
- 在Firebase控制台的扩展市场搜索「Trigger Email」并安装
- 配置扩展:指定发件邮箱(你的管理员Gmail)、Firestore触发集合(比如
contactRequests),并授权扩展访问Gmail - 安装Firebase Admin SDK依赖:
npm install firebase-admin - 初始化Admin SDK(Firebase Functions环境下自动使用默认凭据,无需手动配置密钥):
import * as admin from 'firebase-admin'; if (!admin.apps.length) { admin.initializeApp(); } const firestore = admin.firestore();- 验证表单后,往指定集合写入文档:
扩展会自动读取文档并发送邮件,发送完成后还会更新文档状态(成功/失败)async sendContactForm(formData: any) { return firestore.collection('contactRequests').add({ to: '你的管理员Gmail邮箱', message: { subject: `新联系表单提交:${formData.subject}`, text: `用户姓名:${formData.name}\n用户邮箱:${formData.userEmail}\n留言内容:${formData.message}`, }, }); }
方案3:直接调用Gmail API
如果需要更灵活的邮件控制(比如添加附件、自定义HTML格式),可以直接调用Gmail API:
- 步骤:
- 在谷歌云控制台启用Gmail API,创建服务账号密钥并下载JSON密钥文件
- 安装谷歌API客户端依赖:
npm install googleapis - 在NestJS中配置并调用API:
import { google } from 'googleapis'; import * as fs from 'fs'; async sendContactForm(formData: any) { const auth = new google.auth.GoogleAuth({ keyFile: './service-account-key.json', // 你的服务账号密钥文件路径 scopes: ['https://www.googleapis.com/auth/gmail.send'], }); const gmail = google.gmail({ version: 'v1', auth }); // 构造邮件内容,需符合RFC 2822格式 const emailContent = `To: 你的管理员Gmail邮箱
Subject: 新联系表单提交:${formData.subject}
用户姓名:${formData.name}
用户邮箱:${formData.userEmail}
留言内容:${formData.message}`;
// 对邮件内容进行base64编码(适配Gmail API要求) const encodedMessage = Buffer.from(emailContent) .toString('base64') .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=+$/, ''); return gmail.users.messages.send({ userId: 'me', requestBody: { raw: encodedMessage, }, }); } ```
注意:需在你的谷歌账户中,将服务账号邮箱添加为授权用户,否则无法发送邮件
方案对比
- Nodemailer+Gmail SMTP:开发成本低,配置简单,适合快速上线;OAuth2方式足够安全,满足多数生产场景需求
- Firebase Trigger Email:无需维护邮件发送逻辑,扩展自动处理重试、日志等,适合不想关注邮件底层实现的场景
- Gmail API:功能最强大,支持复杂定制化需求,但配置稍繁琐,适合有特殊邮件格式/功能要求的场景
内容的提问来源于stack exchange,提问作者user14451038
相关产品推荐
相关产品推荐

