AWS Simple Email Service + Nodemailer = 在开发和生产中没有错误——在开发中即时交付——但在生产中没有任何交付?

如何解决AWS Simple Email Service + Nodemailer = 在开发和生产中没有错误——在开发中即时交付——但在生产中没有任何交付?

我一直无法确定在 Nextjs 中使用 SES + Nodemailer 发送电子邮件的生产和开发之间可能存在的脱节。但是,我似乎无法确定发生了什么,因为我的 SES 控制台中没有反弹,也没有错误记录到开发控制台或生产中的实时无服务器功能日志。可以在 here

找到该存储库

任何见解将不胜感激。

客户端表单,@components/Portals/nodemail.tsx
import { Input,Button,Textarea,Logo,ModalBackdrop } from '@components/UI';
import { useState,SyntheticEvent,FC,useEffect,useCallback } from 'react';
import { useUI } from '@components/context';
import css from './contact-us.module.css';
import cn from 'classnames';
import { validEmail } from '@lib/validate-email';

const SendEmail: FC = () => {
    const { setModalView } = useUI();
    const [inputE1,setInputE1] = useState('');
    const [inputE2,setInputE2] = useState('');
    const [inputE3,setInputE3] = useState('');
    const [inputE4,setInputE4] = useState('');
    // const inputText = useRef<HTMLTextAreaElement>(null);
    const [dirty,setDirty] = useState(false);
    const [message,setMessage] = useState('');
    const [disabled,setDisabled] = useState(false);
    const [loading,setLoading] = useState(false);
    const userSend = async (e: SyntheticEvent<EventTarget>) => {
        e.preventDefault();
        // const prod = `drisdell.org/api/nodemailer`;
        // const dev = '/api/nodemailer';
        if (!dirty && !disabled) {
            setDirty(true);
            handleValidation();
        }
        setLoading(true);
        setMessage('');
        let res = await fetch('/api/nodemailer',{
            body: JSON.stringify({
                text: inputE3,subject: inputE4,name: inputE2,email: inputE1
            }),headers: {
                Accept: 'application/json,text/plain,*/*','Content-Type': 'application/json'
            },method: 'POST'
        });

        const { error,data } = await res.json();

        if (error) {
            setMessage(error);
            return;
        }
        setLoading(false);
        setInputE1('');
        setInputE2('');
        setInputE3('');
        setInputE4('');
        setMessage(
            'Success ? email sent! We will get back to you within several business days' +
                `${data}`
        );
        await setModalView('SUCCESS_VIEW');
    };

    const handleValidation = useCallback(() => {
        if (dirty) {
            setDisabled(!validEmail(inputE1) || !inputE2 || !inputE3 || !inputE4);
        }
    },[inputE1,inputE2,inputE3,inputE4,dirty]);

    useEffect(() => {
        handleValidation();
    },[handleValidation]);

    return (
        <form
            onSubmit={userSend}
            className={cn('w-100 flex flex-col justify-between')}
        >
            <div className='flex justify-center pb-4 '>
                <Logo className='h-20 w-20 md:h-40 md:w-40 rounded-full' />
            </div>
            <div className='relative max-w-xl mx-auto'>
                <ModalBackdrop />
                {message && (
                    <div className='text-white border border-white p-2 mb-2 rounded-2xl'>
                        {message}
                    </div>
                )}
                <label htmlFor='email'>{'Email Address'}</label>
                <Input
                    id='from-input'
                    name='from'
                    placeholder='user@example.net'
                    onChange={setInputE1}
                    required={true}
                    type='email'
                    className='mb-2 bg-primary-9 text-primary-0 font-medium focus:outline-none rounded-md'
                />
                <label htmlFor='name'>{'Full Name'}</label>
                <Input
                    id='name-input'
                    name='name'
                    placeholder='first &amp; last names'
                    onChange={setInputE2}
                    required={true}
                    type='text'
                    className='mb-2 bg-primary-9 text-primary-0 font-medium focus:outline-none rounded-md'
                />
                <label htmlFor='subject'>{'Subject'}</label>
                <Input
                    id='subject-input'
                    name='subject'
                    placeholder='Email subject...'
                    onChange={setInputE4}
                    required={true}
                    type='text'
                    className='mb-2 bg-primary-9 text-primary-0 font-medium focus:outline-none rounded-md'
                />
                <label htmlFor='text'>{'Body'}</label>
                <Textarea
                    id='text-textarea'
                    name='text'
                    placeholder='Email body...'
                    onChange={setInputE3}
                    required={true}
                    minLength={5}
                    cols={1}
                    className='mb-2 bg-primary-9 text-primary-0 font-medium focus:outline-none rounded-md'
                />
                <div className='w-auto px-8 flex flex-col'>
                    <Button
                        type='submit'
                        variant='slim'
                        loading={loading}
                        disabled={disabled}
                        className={cn(
                            css.root,'my-4 w-auto max-w-sm bg-primary-7 text-primary-0 hover:bg-primary-9 rounded-md duration-150 transition-colors'
                        )}
                    >
                        {'SUBMIT EMAIL'}
                    </Button>
                </div>
                <span className='pt-1 text-center text-sm'>
                    <span className='text-primary-9'>Interested in a Career?</span>
                    &nbsp;
                    <a
                        className='text-primary-9 font-bold hover:underline cursor-pointer'
                        onClick={() => setModalView('SUBMIT_RESUME_VIEW')}
                    >
                        Submit a Resume
                    </a>
                </span>
            </div>
        </form>
    );
};

export default SendEmail;
pages/api/nodemailer.ts
import nodemailer,{ SentMessageInfo } from 'nodemailer';
import { NextApiRequest,NextApiResponse } from 'next';
import secrets from 'aws';
import Mail from 'nodemailer/lib/mailer';
const {
    SMTP_SENDER_ADDRESS,SMTP_RECIPIENT_ADDRESS,SMTP_PASSWORD,SMTP_USERNAME,SMTP_BCC_ADDRESS
} = secrets;
const senderAddress = SMTP_SENDER_ADDRESS;
const toAddress = SMTP_RECIPIENT_ADDRESS;
const ccAddress = SMTP_SENDER_ADDRESS;
const bccAddress = SMTP_BCC_ADDRESS;
const smtpUsername = SMTP_USERNAME;
const smtpPassword = SMTP_PASSWORD;

export default async (req: NextApiRequest,res: NextApiResponse) => {
    const { text,subject,name,email } = req.body;
    try {
        const body_subject = `Contact Us Submission Event - ${subject}`;
        const body_text = `Contact Us Form Submission via AWS SES & Nodemailer
    ---------------------------------------------------------
    ${text}
    `;
        const body_html = `<html>
    <head></head>
    <body>
        <h1>${subject}</h1>
        \n
        <h2>Name: ${name}</p>
        \n
        <h2>email: ${email}</h2>
        \n
        <p>${text}</p>
    </body>
    </html>`;
        let transporter = nodemailer.createTransport({
            host: 'email-smtp.us-east-2.amazonaws.com',port: 465,secure: true,auth: {
                user: smtpUsername,pass: smtpPassword
            }
        });
        let mailOptions: Mail.Options = {
            sender: senderAddress,from: `${senderAddress}`,to: toAddress,cc: ccAddress,bcc: bccAddress,subject: body_subject,text: body_text,html: body_html
        };

        let response: SentMessageInfo = transporter.sendMail(
            mailOptions,(info,err) => {
                if (!err)
                    console.log(
                        '\n info.message: ',info?.message,'\n info.stack: ',info?.stack,'\n info.name: ',info?.name
                    );
                console.log(err);
                return info;
            }
        );
        if (response === typeof Error) {
            return res.status(400).json({
                error:
                    'There was an internal error ⚙... \n Shoot me an email at [Mary.Drisdell@drisdellconsulting.com]'
            });
        }
        return res.status(200).json({ error: '',data: response ?? '' });
    } catch (error) {
        return res.status(500).json({ error: error.message || error.toString() });
    }
};
Vercel Dev CLI
  • 在进行故障排除时,我遇到了 vercel dev 命令,该命令可在本地使用下一个框架在 vercel 环境中测试 api 路由。也就是说,我一直在使用这个新的开发脚本,它几乎可以立即交付到目标地址,而没有任何错误......

    image

Vercel 实时无服务器功能日志用于 /api/nodemailer 路由发送一封从未送达但也从未退回的电子邮件 ?

image

有什么想法吗?我已经尝试了几乎所有的方法,包括四重检查我在生产中的环境秘密。与 SES 的主域相关联的 DNS 记录匹配,我配置的 unlimited AWS SES Access Programmatic IAM 策略也是如此。任何帮助将不胜感激,因为我从上周末开始每天都在解决这个问题。

您可以发送电子邮件的现场制作站点是 here

image

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-