无法实现发送确认邮件功能

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

我使用表单通过 emailjs 验证电子邮件,将电子邮件值发送到 next.js API。在 API route.js 中,我创建并散列令牌,将其存储在数据库中并创建确认链接(到目前为止,console.logs 告诉我一切正常),然后在 sendEmail 中(我以另一种形式使用它,它有效)我收到的功能:“电子邮件发送失败:未定义 投资组合3d-nextjs-app-1 |发送电子邮件失败: 错误:发送电子邮件失败 投资组合3d-nextjs-app-1 | 在 sendEmail (webpack-内部:". 另一个信息是我使用 Docker 映像来运行我的项目。 有人可以给我建议如何解决这个问题吗?

'use client';
import React from 'react';
import { useForm } from 'react-hook-form';
import { Toaster, toast } from 'sonner';
import { MailCheck, MailX } from 'lucide-react';

export default function EmailConfirmationForm() {
    const { register, handleSubmit, formState: { errors }, reset } = useForm();

    // Send confirmation email
    const handleSendConfirmationEmail = async (email) => {
        try {
            const response = await fetch(`/api/sendConfirmationEmail?email=${email}`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ email }),
            });
            if (!response.ok) throw new Error('Failed to send confirmation email');
            toast.success('Confirmation email sent!', {
                duration: 5000,
                icon: <MailCheck />,
                style: {
                    backgroundColor: '#1B1B1B',
                    border: 'none',
                },
            });
            return true;
        } catch (error) {
            toast.error('Failed to send confirmation email.', {
                duration: 5000,
                icon: <MailX />,
                style: {
                    backgroundColor: '#1B1B1B',
                    border: 'none',
                },
            });
            return false;
        }
    };

    const onSubmit = async (data) => {

        try {
            await handleSendConfirmationEmail(data.email);

            reset(); 
        } catch (error) {
            console.error('Failed to send confirmation email:', error);
        }
    };

    return (
        <>
            <Toaster position="bottom-left" richColors />
            <form onSubmit={handleSubmit(onSubmit)} className="max-w-md w-full flex flex-col items-center justify-center space-y-4">

                {/* Email input */}
                <label htmlFor="email" className="self-start">Email Confirmation</label>
                <input
                    id="email"
                    type="email"
                    placeholder="Email Confirmation"
                    {...register("email", {
                        required: 'This field is required',
                        pattern: { value: /^\S+@\S+$/i, message: 'Invalid email format' }
                    })}
                    className="w-full p-2 rounded-md shadow-lg text-foreground focus:outline-none focus:ring-2 focus:ring-accent/50 custom-bg"
                    aria-label="Email"
                />
                {errors.email && <span className="inline-block self-start text-red-500">{errors.email.message}</span>}

                <input
                    value="Cast your message!"
                    className="px-10 py-4 rounded-md shadow-lg bg-background border border-accent/30 hover:shadow-glass-sm backdrop-blur-sm text-foreground focus:outline-none focus:ring-2 focus:ring-accent/50 cursor-pointer capitalize"
                    type="submit"
                />
            </form>
        </>
    );
}
import { NextResponse } from 'next/server';
import { sendEmail } from '@/app/../../service/service.email';
import redisClient, { connectRedis } from '@/app/../../service/redisClient';
import { generateToken, hashToken } from '@/app/../../service/tokenService';
import { rateLimiter } from '@/app/../../service/rateLimiter';

export async function POST(req) {
    const { searchParams } = new URL(req.url);
    const email = searchParams.get('email');
    const ip = req.headers.get('x-forwarded-for') || req.socket.remoteAddress || req.ip;

    // if (!rateLimiter(ip)) {
    //     return NextResponse.json({ message: 'Too many requests, please try again later.' }, { status: 429 });
    // }

    await connectRedis();

    const token = generateToken();
    const hashedToken = await hashToken(token);

    const expiresAt = Date.now() + 3600 * 1000;

    try {
        await redisClient.setEx(`confirm_tokens:${hashedToken}`, 3600, JSON.stringify({ email, expiresAt }));
        const storedToken = await redisClient.get(`confirm_tokens:${hashedToken}`);
        console.log('Token stored in Redis:', storedToken); // Log to verify storage
    } catch (redisError) {
        console.error('Error saving token in Redis:', redisError);
        return NextResponse.json({ message: 'Error saving confirmation token to Redis.' }, { status: 500 });
    }

    const confirmationLink = `${process.env.NEXT_PUBLIC_APP_URL}/api/confirmEmail?token=${token}&email=${email}`;
    console.log(`Confirmation link: ${confirmationLink}`);
    try {
        const templateParams = {
            to: email,
            from_name: 'Email Confirmation',
            reply_to: email,
            message: `Please confirm your email by clicking the link: ${confirmationLink}`,
        };

        await sendEmail(templateParams);

        return NextResponse.json({ message: 'Confirmation email sent!' }, { status: 200 });
    } catch (error) {
        console.error('Failed to send email:', error);
        return NextResponse.json({ message: 'Failed to send confirmation email.' }, { status: 500 });
    }
}
import emailjs from '@emailjs/browser';

export const sendEmail = async (params) => {
    try {
        const response = await emailjs.send(
            process.env.NEXT_PUBLIC_SERVICE_ID,
            process.env.NEXT_PUBLIC_TEMPLATE_ID,
            params,
            {
                publicKey: process.env.NEXT_PUBLIC_PUBLIC_KEY,
                limitRate: {
                    throttle: 5000,
                },
            }
        );
        console.log('Email sent successfully:', response);
        return response;  
    } catch (error) {
        console.error('Email send failed:', error.text);
        if (error.response) {
            console.error('Error response from email service:', error.response);
        }
        throw new Error(error.text || 'Failed to send email');
    }
};

javascript reactjs api email
1个回答
0
投票

我认为您正在服务器端“@emailjs/browser”上使用此节点包。虽然这仅用于客户端。 请在服务器端代码上使用此包https://www.npmjs.com/package/@emailjs/nodejs

© www.soinside.com 2019 - 2024. All rights reserved.