如何将与twilio API集成的reactJS应用程序上传到在本地主机上运行良好的vercel

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

我一直在开发一个项目,用户填写一个表格,其中包括他的手机号码,然后我们使用 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 上部署后遇到的控制台错误:

reactjs node.js axios twilio vercel
1个回答
0
投票

我想说您收到此错误是因为您在 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 上找到完整的源代码。

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