我一直在开发一个项目,用户填写一个表格,其中包括他的手机号码,然后我们使用 twilio API 将其传递到我们的 Express 服务器上进行消息传递。 我的项目在本地主机上运行良好,但当我将其上传到我的 github 存储库时显示错误,该存储库又连接到 vercel 进行部署。
这是我正在收集数据的页面的代码,我正在通过 axios 库通过函数handleSendSMS 处理请求:
import React, { useState } from "react";
import formBG from "../assets/formBG.jpg";
import PoliceData from "../components/data";
import { useSupabase } from "../context/SupabaseContext";
import { useToast } from "@chakra-ui/react";
import axios from 'axios';
const NewVisit = () => {
const { handleSubmit, individual } = useSupabase();
const [ phoneNumber, setPhoneNumber ] = useState('');
const [form, setForm] = useState({
name: "",
age: "",
mobile: "",
email: "",
pstation: individual || "",
});
const handleChange = (e) => {
const { name, value } = e.target;
if (name === 'mobile') {
setPhoneNumber(value);
}
setForm({ ...form, [name]: value });
};
const toast = useToast()
const handleSendSMS = async () => {
try {
const response = await axios.get('http://localhost:4000/send-text', {
params: {
recipient: phoneNumber
},
});
console.log('SMS Sent:', response.data);
} catch (error) {
console.error('Error sending SMS:', error.response?.data || error.message);
}
};
const handleFormSubmit = async (e) => {
e.preventDefault();
toast.promise(handleSubmit(form), {
success: { title: "Visit Marked", description: "Looks great" },
error: { title: "Error", description: "Something wrong" },
loading: { title: "Marking Your Visit", description: "Please wait" },
});
handleSendSMS();
setForm({
name: "",
age: "",
email: "",
mobile: "",
pstation: individual || "",
});
};
return (
<div className="flex flex-col justify-center items-center">
<div className="lg:w-[50%] w-[90%] mx-auto mt-28">
<form
className="mt-12 flex flex-col px-2 gap-8 lg:mb-10 bg-slate-50 rounded-md shadow-md shadow-[#5e5d5d]"
style={{
background: `url(${formBG})`,
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
}}
id="visitForm"
onSubmit={handleFormSubmit}
>
<label className="flex mt-4 flex-row justify-center items-center gap-[10%]">
<span className="w-[20%] font-bold">Full Name:</span>
<input
type="text"
required
name="name"
value={form.name}
onChange={handleChange}
className="bg-transparent border-[1px] border-black rounded-xl p-2"
/>
</label>
<label className="flex flex-row justify-center items-center gap-[10%]">
<span className="w-[20%] font-bold">Age:</span>
<input
type="number"
required
name="age"
value={form.age}
onChange={handleChange}
className="bg-transparent border-[1px] border-black rounded-xl p-2"
/>
</label>
<label className="flex flex-row justify-center items-center gap-[10%]">
<span className="w-[20%] font-bold">Mobile:</span>
<input
type="text"
required
name="mobile"
value={form.mobile}
onChange={handleChange}
className="bg-transparent border-[1px] border-black rounded-xl p-2"
/>
</label>
<label className="flex flex-row justify-center items-center gap-[10%]">
<span className="w-[20%] font-bold">Email:</span>
<input
type="text"
required
name="email"
value={form.email}
onChange={handleChange}
className="bg-transparent border-[1px] border-black rounded-xl p-2"
/>
</label>
<label className="flex flex-row justify-center items-center gap-[10%]">
<span className="w-[20%] font-bold">Police Station: </span>
<select
name="pstation"
form="visitForm"
value={individual}
onChange={handleChange}
disabled
className="bg-transparent border-[1px] border-black rounded-xl p-2"
>
{PoliceData.map((data) => (
<option key={data.id} value={data.name}>
{data.name}
</option>
))}
</select>
</label>
<div className="flex flex-row justify-center items-center m-5">
<button
type="submit"
className="bg-[#f7bc6a] w-[200px] p-2 rounded-xl duration-300 hover:bg-[#d5a96a]"
>
Submit
</button>
</div>
</form>
</div>
</div>
);
};
export default NewVisit;
我还为我的后端创建了一个 index.js 文件,该文件位于服务器命名目录中,该目录又与其他目录(例如 src 和 public)一起位于我的根文件夹中。我还在其目录中为服务器创建了一个单独的 package.json 文件。 这是上述index.js文件的代码:
const express = require('express');
const cors = require('cors');
const twilio = require('twilio');
const accSid = process.env.REACT_APP_TWILIO_ACCOUNT_SID;
const authToken = process.env.REACT_APP_TWILIO_AUTH_TOKEN;
const client = new twilio(accSid, authToken);
const app = express();
app.use(cors());
app.get('/', (req, res) => {
res.send('Welcome to the express server of hackathon project');
});
app.get('/send-text', (req, res) => {
const { recipient, polStation } = req.query;
console.log('SMS request received:', { recipient });
client.messages.create({
body: `Thank you for vising Police Station. \nYou are requested to kindly fill the feedback form by clicking on the url: https://feedback-system-police-private.vercel.app/myVisits after your visit. It is mandatory to fill the feedback form. \nRegards`,
to: recipient,
from: '+19287560963' // From Twilio
})
.then((message) => {
console.log(message.body);
res.send('SMS sent successfully');
console.log(recipient);
})
.catch((error) => {
console.error('Error sending SMS:', error);
res.status(500).send(`Error sending SMS: ${error.message}`);
console.log(recipient);
});
});
const port = process.env.PORT || 4000;
app.listen(port, () => console.log(`Running on port ${port}`));
下面是我在 vercel 上部署后遇到的控制台错误:
我想说您收到此错误是因为您在 Next.js 应用程序中硬编码了
axios.get('http://localhost:4000/send-text')
,然后部署到 Vercel。然而,Twilio 方面运行在本地 Express 服务器上,该服务器未与应用程序的其余部分一起部署。
您的浏览器不允许您请求在本地主机上运行的另一台服务器,因此会出现
ECONNREFUSED
错误。借助 Next.js,您已经在使用能够在 Vercel 上将 Twilio 相关代码作为服务器操作运行的框架。我建议您遵循这种方法。
import twilio from "twilio";
import { SubmitButton } from "./submit-button";
const client = twilio(process.env.ACCOUNT_SID, process.env.AUTH_TOKEN);
export default function Home() {
console.log("Access to second page");
async function send(data: any) {
"use server";
const recipe = await client.messages.create({
to: `whatsapp:${data.get("phone")}`,
from: process.env.TWILIO_SENDER,
body: data.get("message"),
contentSid: data.get("message") ? undefined : process.env.CONTENT_SID,
});
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
console.log(`Sent message ${recipe.sid}`);
await sleep(5000);
}
return (
<div className="flex flex-col items-center justify-center h-screen text-sm text-white font-medium ">
<div className="bg-slate-500 p-6 rounded shadow-lg w-10/12 h-10/12">
<h1 className="text-2xl m-2 mb-4">Send a WhatsApp</h1>
<form action={send}>
<div>
<label htmlFor="phone" className="block m-2">
Phone number
</label>
<input
type="tel"
id="phone"
name="phone"
className="rounded-lg w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 "
placeholder="+49 151 12341234"
pattern="^(\+49|0)(1\d{2}|(15|16|17|18|19)\d)(\s?\d{3,4}){2}$"
required
></input>
</div>
<label htmlFor="message" className="block m-2">
Your message
</label>
<textarea
id="message"
name="message"
className="rounded-lg w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400"
placeholder="Write your message here..."
></textarea>
<SubmitButton />
</form>
</div>
</div>
);
}
您可以在 GitHub 上找到完整的源代码。