如何用Nest.js Nodemailer发送Azure Blob存储中的文件作为邮件附件?
使用Nest.js + Nodemailer发送带Azure Blob存储附件的邮件
要把Azure Blob存储中的文件作为邮件附件,有两种常用实现方式,以下是具体步骤和代码示例:
前提准备
先安装Azure Blob存储的SDK包:
npm install @azure/storage-blob
方案一:生成SAS URL作为附件路径
通过生成Blob的共享访问签名(SAS)URL,直接作为Nodemailer附件的path参数,Nodemailer会自动从该URL下载文件作为附件。
实现代码
- 封装生成Blob SAS URL的函数:
import { BlobServiceClient, generateBlobSASQueryParameters, BlobSASPermissions } from '@azure/storage-blob'; // 从环境变量读取Azure配置 const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING; const CONTAINER_NAME = process.env.AZURE_BLOB_CONTAINER_NAME; async function getBlobSasUrl(blobName: string): Promise<string> { const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING); const containerClient = blobServiceClient.getContainerClient(CONTAINER_NAME); const blobClient = containerClient.getBlobClient(blobName); // 配置SAS权限与过期时间(示例为1小时后过期) const sasOptions = { blobName: blobName, containerName: CONTAINER_NAME, permissions: BlobSASPermissions.parse('r'), // 仅读权限 expiresOn: new Date(new Date().getTime() + 3600 * 1000), }; const sasToken = generateBlobSASQueryParameters(sasOptions, blobServiceClient.credential).toString(); return `${blobClient.url}?${sasToken}`; }
- 修改邮件发送代码:
// 获取Blob的SAS URL const blobSasUrl = await getBlobSasUrl('HealthForm.pdf'); this.emailService.sendEmail({ to: 'example@gmail.com', subject: 'Health Reports', template: 'health-forms', attachments: [ { name: 'HealthForm.pdf', path: blobSasUrl // 直接使用SAS URL } ] });
方案二:读取Blob文件流作为附件内容
直接从Azure Blob下载文件流,作为Nodemailer附件的content参数,这种方式无需暴露公共URL。
实现代码
- 封装获取Blob流的函数:
import { BlobServiceClient } from '@azure/storage-blob'; const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING; const CONTAINER_NAME = process.env.AZURE_BLOB_CONTAINER_NAME; async function getBlobStream(blobName: string): Promise<NodeJS.ReadableStream> { const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING); const containerClient = blobServiceClient.getContainerClient(CONTAINER_NAME); const blobClient = containerClient.getBlobClient(blobName); const downloadResponse = await blobClient.download(); return downloadResponse.readableStreamBody; }
- 修改邮件发送代码:
// 获取Blob文件流 const blobStream = await getBlobStream('HealthForm.pdf'); this.emailService.sendEmail({ to: 'example@gmail.com', subject: 'Health Reports', template: 'health-forms', attachments: [ { name: 'HealthForm.pdf', content: blobStream // 使用文件流作为附件内容 } ] });
注意事项
- 确保Azure存储账户的连接字符串、容器名称配置在环境变量中,避免硬编码敏感信息。
- 生成SAS URL时,根据需求设置合适的过期时间和权限,降低安全风险。
- 大文件建议使用流的方式,避免一次性加载整个文件占用过多内存。
内容的提问来源于stack exchange,提问作者Code The World
相关产品推荐
相关产品推荐

