如何使用 nodemailer 和 dreamhost 发送电子邮件(在 Node.js 服务器上)
How to send emails with nodemailer and dreamhost (on Node.js server)
我找不到任何特定于使用 nodemailer 从 dreamhost 发送电子邮件的有用帖子。我确实找到了一个 dreamhost article for sending emails via PHP,所以也许这可以帮助我们指明正确的方向...
无论哪种方式,这是我的 mailer.ts
文件:
import { createTransport, getTestMessageUrl } from "nodemailer";
import { frontendURL } from "./urls";
var transport = createTransport({
host: "smtp.dreamhost.com",
port: 465,
auth: {
user: encodeURIComponent(process.env.PROD_MAIL_USER),
pass: encodeURIComponent(process.env.PROD_MAIL_PASS),
},
secure: true,
});
function generateHTML(resetToken: string) {
return `
<div>
<h2>Hello from HaBits </h2>
<p>
Your <b>Password Reset Token</b> is here!
</p>
<h3>
<a href="${frontendURL}/reset?token=${resetToken}" style="color: #75B748">Reset your password.</a>
</h3>
<p>HaBits ✅</p>
</div>
`;
}
export interface MailResponse {
accepted?: string[] | null;
rejected?: null[] | null;
envelopeTime: number;
messageTime: number;
messageSize: number;
response: string;
envelope: Envelope;
messageId: string;
}
export interface Envelope {
from: string;
to?: string[] | null;
}
export async function sendPasswordResetEmail(
resetToken: string,
to: string
): Promise<void> {
// email the user a token
const info = await transport.sendMail({
to,
from: process.env.PROD_MAIL_USER,
subject: "✅ HaBits – password reset token",
html: generateHTML(resetToken),
});
}
生产中的错误响应:
{
"errors": [
{
"message": "Invalid login: 535 5.7.8 Error: authentication failed: ",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"sendUserPasswordResetLink"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"code": "EAUTH",
"response": "535 5.7.8 Error: authentication failed: ",
"responseCode": 535,
"command": "AUTH PLAIN",
"stacktrace": [
"Error: Invalid login: 535 5.7.8 Error: authentication failed: ",
" at SMTPConnection._formatError (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:784:19)",
" at SMTPConnection._actionAUTHComplete (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:1536:34)",
" at SMTPConnection.<anonymous> (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:540:26)",
" at SMTPConnection._processResponse (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:947:20)",
" at SMTPConnection._onData (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)",
" at TLSSocket.SMTPConnection._onSocketData (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:189:44)",
" at TLSSocket.emit (node:events:390:28)",
" at addChunk (node:internal/streams/readable:315:12)",
" at readableAddChunk (node:internal/streams/readable:289:9)",
" at TLSSocket.Readable.push (node:internal/streams/readable:228:10)",
" at TLSWrap.onStreamRead (node:internal/stream_base_commons:199:23)"
]
}
},
"name": "GraphQLError"
}
]
}
Dreamhost“支持”刚刚向我发送了关于 PHP 的文章,该文章建议使用 host: "ssl://smtp.dreamhost.com"
,但只是 returns 一个不太有用的“找不到地址”错误:
Error: getaddrinfo ENOTFOUND ssl://smtp.dreamhost.com
所以我非常有信心 nodemailer 配置是正确的 – 即。主机、端口、用户和密码
这是我自己的愚蠢错误♂️
这是用于在生产环境中发送电子邮件的 nodemailer 配置(假设您有一封由 dreamhost 托管的电子邮件):
import { createTransport, getTestMessageUrl } from "nodemailer";
var transport = createTransport({
host: "smtp.dreamhost.com",
port: 465,
auth: {
user: process.env.PROD_MAIL_USER, // your email address
pass: process.env.PROD_MAIL_PASS, // your webmail password
},
secure: true,
logger: true,
debug: true,
});
// ...
await transport.sendMail({ ... })
我的问题是 encodeURIComponent()
包裹着我的电子邮件和密码 – 所以电子邮件 hello@example.com
被传递为 hello%40example.com
。
上面的 logger
和 debugger
属性是可选的,但它们帮助我确定了服务器日志中的问题。
我找不到任何特定于使用 nodemailer 从 dreamhost 发送电子邮件的有用帖子。我确实找到了一个 dreamhost article for sending emails via PHP,所以也许这可以帮助我们指明正确的方向...
无论哪种方式,这是我的 mailer.ts
文件:
import { createTransport, getTestMessageUrl } from "nodemailer";
import { frontendURL } from "./urls";
var transport = createTransport({
host: "smtp.dreamhost.com",
port: 465,
auth: {
user: encodeURIComponent(process.env.PROD_MAIL_USER),
pass: encodeURIComponent(process.env.PROD_MAIL_PASS),
},
secure: true,
});
function generateHTML(resetToken: string) {
return `
<div>
<h2>Hello from HaBits </h2>
<p>
Your <b>Password Reset Token</b> is here!
</p>
<h3>
<a href="${frontendURL}/reset?token=${resetToken}" style="color: #75B748">Reset your password.</a>
</h3>
<p>HaBits ✅</p>
</div>
`;
}
export interface MailResponse {
accepted?: string[] | null;
rejected?: null[] | null;
envelopeTime: number;
messageTime: number;
messageSize: number;
response: string;
envelope: Envelope;
messageId: string;
}
export interface Envelope {
from: string;
to?: string[] | null;
}
export async function sendPasswordResetEmail(
resetToken: string,
to: string
): Promise<void> {
// email the user a token
const info = await transport.sendMail({
to,
from: process.env.PROD_MAIL_USER,
subject: "✅ HaBits – password reset token",
html: generateHTML(resetToken),
});
}
生产中的错误响应:
{
"errors": [
{
"message": "Invalid login: 535 5.7.8 Error: authentication failed: ",
"locations": [
{
"line": 2,
"column": 3
}
],
"path": [
"sendUserPasswordResetLink"
],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"code": "EAUTH",
"response": "535 5.7.8 Error: authentication failed: ",
"responseCode": 535,
"command": "AUTH PLAIN",
"stacktrace": [
"Error: Invalid login: 535 5.7.8 Error: authentication failed: ",
" at SMTPConnection._formatError (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:784:19)",
" at SMTPConnection._actionAUTHComplete (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:1536:34)",
" at SMTPConnection.<anonymous> (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:540:26)",
" at SMTPConnection._processResponse (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:947:20)",
" at SMTPConnection._onData (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:749:14)",
" at TLSSocket.SMTPConnection._onSocketData (/workspace/backend/node_modules/nodemailer/lib/smtp-connection/index.js:189:44)",
" at TLSSocket.emit (node:events:390:28)",
" at addChunk (node:internal/streams/readable:315:12)",
" at readableAddChunk (node:internal/streams/readable:289:9)",
" at TLSSocket.Readable.push (node:internal/streams/readable:228:10)",
" at TLSWrap.onStreamRead (node:internal/stream_base_commons:199:23)"
]
}
},
"name": "GraphQLError"
}
]
}
Dreamhost“支持”刚刚向我发送了关于 PHP 的文章,该文章建议使用 host: "ssl://smtp.dreamhost.com"
,但只是 returns 一个不太有用的“找不到地址”错误:
Error: getaddrinfo ENOTFOUND ssl://smtp.dreamhost.com
所以我非常有信心 nodemailer 配置是正确的 – 即。主机、端口、用户和密码
这是我自己的愚蠢错误♂️
这是用于在生产环境中发送电子邮件的 nodemailer 配置(假设您有一封由 dreamhost 托管的电子邮件):
import { createTransport, getTestMessageUrl } from "nodemailer";
var transport = createTransport({
host: "smtp.dreamhost.com",
port: 465,
auth: {
user: process.env.PROD_MAIL_USER, // your email address
pass: process.env.PROD_MAIL_PASS, // your webmail password
},
secure: true,
logger: true,
debug: true,
});
// ...
await transport.sendMail({ ... })
我的问题是 encodeURIComponent()
包裹着我的电子邮件和密码 – 所以电子邮件 hello@example.com
被传递为 hello%40example.com
。
上面的 logger
和 debugger
属性是可选的,但它们帮助我确定了服务器日志中的问题。