使用 ReadableStreams 通过 Nodemailer 发送托管在 S3 中的电子邮件附件

问题描述 投票:0回答:1

我正在尝试使用 JS AWS SDK v3 使用 Nodemailer 发送包含 S3 中托管的附件的电子邮件。 Nodemailer 文档显示了使用读取文件生成的读取流发送附件的示例:

{   // stream as an attachment
    filename: 'text4.txt',
    content: fs.createReadStream('file.txt')
},

我可以在 S3 中为我的附件创建一个

ReadableStream
,如下所示:

const s3Stream = await s3Client
    .send(/* ... */)
    .then((response) => {
        // ...
        return response.Body.transformToWebStream() // returns Promise<ReadableStream>
    })
    .catch(/* ... */)

如果我尝试将

s3Stream
直接传递到 Nodemailer 附件的
content
字段,我会收到错误:
Type 'ReadableStream' is not assignable to type 'string | Readable | Buffer | undefined

Readable
类有一个静态方法
fromWeb
。调用
Readable.fromWeb(s3Stream)
会给出以下信息:

Argument of type 'ReadableStream' is not assignable to parameter of type 'ReadableStream<any>'.
  Type 'ReadableStream' is missing the following properties from type 'ReadableStream<any>': locked, cancel, getReader, pipeThrough, and 4 more.

Readable
对象有一个方法
wrap
:

new Readable().wrap(s3Stream)

尝试此操作会导致以下错误:

Argument of type 'ReadableStream' is not assignable to parameter of type 'NodeJS.ReadableStream'.
  Type 'ReadableStream' is missing the following properties from type 'ReadableStream': readable, read, setEncoding, pause, and 22 more.
node.js typescript amazon-s3 nodemailer
1个回答
0
投票

这是 S3 SDK 的一个已知问题(查看此 GitHub 问题 ),它显示

response.Body
作为浏览器 (
ReadableStream
) 和 Node.js (
Readable
) 类型的交集,而在运行时返回根据您运行它的平台确定值的类型。

因此,如果您确定您的代码只能在 Node.js 中运行,您只需进行类型转换:

import { Readable } from 'node:stream';

(res.Body as Readable)?.pipe(...);

或者更好的是添加一个类型保护以确保:

import { Readable } from 'node:stream';

if(isReadable(res.Body)) {
    res.Body.pipe(fs.createWriteStream('/Users/edgar/Projects/Petabox/scripts/file2.txt'));
} else {
    throw new TypeError('res.Body is not a readable stream');
}

function isReadable(value: unknown): value is Readable {
  return value instanceof Readable
}
© www.soinside.com 2019 - 2024. All rights reserved.