Адрасаванне і прыём SMS у Node.js за дапамою Twilio Webhooks і Express
Створыце маленькі сервер Express, який адправляе тэксты через Twilio, прымае адпаведзі за дапамою webhook, які ўвідны ў сеть через ngrok, і автаматычна адпавядае на яны за дапамою TwiML.
Крыніцы: **Build a Two-Way SMS with Node.js and Twilio (Full Code Included)**
Большасць інструкцый з SMS заканчваюцца тады, калі паведамленне паказваецца з вашага сервера. Найболей корыстныя — это тые, якія стосуюцца прыему паведамленняў: фіксацыя таго, што корыстнік адпаведзеў, чытанне тексту і адпаведзь. Гэты цыкл ўтварае аснову для процесаў OTP, ботаў падтрымкі і напамінанняў пра запланаваныя зустрэчы, якія падтверджуюцца адзінам словам. Пасля завершэння гэтага карысавання у вас будзе сервер Express, які надае паведамленні на тэлефон і реагуе кожны раз, калі тэлефон адпавядае.
Прыямыя патрабаванні
- Акаунт у Twilio. На момент напісання безплатны прыемлівач включае адпрыяж у розмерзе прыблізна $15, што цалкам дастаткова для експерыментаў.
- Postman або будзь-які іншы HTTP-кліент.
- Node.js, установлены на вашам комп’ютеры.
- ngrok, які дае Twilio публічную адресу, якая перадае трафік на ваш ноутбук.
Мінімальны сервер Express
Створыце папку з файлам server.js. Сервер налажоўвае звязак з localhost па порту 3000, увімкнюе парсаванне тэла запыту у формате JSON і URL-кодаванні, а таксама выдае маршрут для перагляду стану пад /api/v1/. Парсаванне у формате URL-кодавання мае важлівэ значэнне: Twilio прыносіць уваходзячыя запыты у формате POST з кодаваннем типу form, таму без яго req.body пазней будзе порожнім.
const express = require("express");
const bodyParser = require("body-parser");
const hostname = "127.0.0.1";
const port = 3000;
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const baseUrl = "/api/v1/";
app.get(`${baseUrl}`, (req, res) => {
res.status(200).json({ message: "Hello World" });
});
app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Установіце неабходныя залежнасці:
npm init -y
npm install express body-parser
Запускніце node server.js і ачыніце http://127.0.0.1:3000/api/v1/; адпаведны адказ „Hello World“ параджуе, што всё працюе правільна. У версіях Express 4.16+ таксама ўключаныя функціі express.json() і express.urlencoded(), таму у новых проектах викорыстанне body-parser є неабяжным.
Актываўанне доступу да localhost за дапамогою ngrok
Twilio работае на публічнай інтэрнет-сети, а ваш сервер — на прыватным апаратах, таму Twilio не можа яго безпасэродна прабавіцца. ngrok стварае тунель і дае вам публічны HTTPS-адрэс, які пераказвае трафік на локальны порт. Раней Heroku быў безплатным варыянтом для гэтага, але яго безплатны ўровень больш не існуе.
З’явіце та автентыфікуйце ngrok за дапамою інструкцый ngrok, а пасля дадзіце скрыпт у package.json:
"scripts": {
"ngrok": "ngrok http http://127.0.0.1:3000/"
}
Закінчыце працю сервера ў аднай тэрмінале, а пасля запусціце тунель у другай:
npm run ngrok
ngrok выводзіць адрэс у формате https://abcd-1234.ngrok-free.app. Залейце гэты тэрмінал ачытым.
Увага: у безплатнай версіи ствароўваны URL зазвычай меняецца ў кожны раз, калі ngrok перазапускаецца. Калі работаючы webhook раптам перестае працаваць, верагодная прычына — застарэлы URL у консолі Twilio, таму апдейтаваць я трэба пасля кожнага перазапуску.
Настройка Twilio
У панелі кансоłu скопіюйте SID свайго абанку і токен аутэнтыфікацыі у файл .env. Цей токен ўважаецца секрэтным: ніколі не дадзейте яго да паведамленняў, а таксама дадзіце файл .env у список .gitignore.
ACCOUNT_SID_TWILIO=your_account_sid
AUTH_TOKEN_TWILIO=your_auth_token
У бокавай навігацыі можна прыкрепіць продукты; тут значэнне маюць толькі Месажы і Номеры тэлефонаў.
Атрыманне номера тэлефона
- Ачыніце раздел Номеры тэлефонаў, а потым — Купіць номер.
- Выберыце будзь-які доступны номер; номеры з США зазвычай ўсё дашчэцей.
- Кошты выкарыстоўваецца з тэстовага балансу, а номер прадстаўляецца сярод вашых актываўных номераў.
Стварэнне службы месажаў
- У разделе Месажы створыце новую Службу месажаў.
- На кроку Пул адправнікаў дадзіце свой номер.
/api/v1/sms. Гэты шлях будуе створаны нижэй.Зберагучы Messaging Service SID і ваш номер у файле .env:
FROM_TWILIO=+1XXXXXXXXXX
MESSAGING_SERVICE_SID_TWILIO=your_messaging_service_sid
Падключэнне SDK Twilio да Node
Зінсталюйце SDK асоўна з dotenv, які чытае данні з файла .env і запішвае іх у process.env:
npm install twilio dotenv
Размістыце гэты код на самай верхней часткі файла server.js. Порядак мае значэнне: кліент чытае аутантыфікацыйныя данні пад час стварэння, таму якщо dotenv будзе чытана пазней, оба значэння будуць undefined, і кожны вызов завершыцца непаводлівасцю аутантыфікаціі.
require("dotenv").config();
const client = require("twilio")(
process.env.ACCOUNT_SID_TWILIO,
process.env.AUTH_TOKEN_TWILIO
);
Адправа текставага поведамлення
Этый маршрут вызвае client.messages.create() і прадаёць рэзультат у формате JSON. Блок try/catch вяртае памылкі Twilio, такія як некоректны номер, адвокацу, замест таго каб процес зламаўся.
app.post(`${baseUrl}sendSms`, async (req, res) => {
try {
await client.messages.create({
body: "Hello",
from: process.env.FROM_TWILIO,
messagingServiceSid: process.env.MESSAGING_SERVICE_SID_TWILIO,
to: "+92XXXXXXXXXX", // whoever you're texting
});
res.status(200).json({ message: "Text sent successfully" });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
Значэнне поль:
body: тэкст паведамлення.from: ваш номер у Twilio.messagingServiceSid: спаявае паведамленне з сервісам і пулом адправнікаў.to: аблекач у формате E.164 (+1...,+92...).
Выклікайце POST /api/v1/sendSms з Postman, і тэлефон должен прыняць „Hello“. У рэальным кодзе чытайце значэння to і body з запыту і пераканаўваеце іх, а не вводзіце як сталявыя значэння.
Тэстовыя абанкі можаюць надсылать тэкставаныя паведамленні толькі на номеры, якія былі паверыжаны ў консолі Twilio. Якщо запит успех, але нічога не прыходзіць, пераканайцеся, што адресат правыльны, або апградуйце пакет.
Прыем адпаведзей через webhook
Калі хтось надсылае тэкставанае паведамленне на ваш номер у Twilio, Twilio надсылае яго на webhook, настроены ў Службе перадачы паведамленняў. Ваш сервер яго прыме і адпаведзіць за дапамойкай TwiML — XML-формата Twilio для апісання наступных дзеянь. З'ядучы гэты калекцыя разам з іншымі неабходнымі элементамі:
const MessagingResponse = require("twilio").twiml.MessagingResponse;
Потым дадзіце слухача. Класычная памылка — несупаданне шляху: маршрут должен быць такім жа, як і шлях, уведзены ў консолі, тут /api/v1/sms. Обробнік запісвае req.body.Body і вяртае порожні дакумент TwiML у формате text/xml, што означае, што адпаведзі не будзе.
app.post(`${baseUrl}sms`, (req, res) => {
// Fires every time someone replies to your number
const twiml = new MessagingResponse();
console.log("INCOMING ----->", req.body.Body);
res.writeHead(200, { "Content-Type": "text/xml" });
res.end(twiml.toString());
});
Указайце свой номер у Twilio, і прымэтка паказаецца ў тэрмінале; цыкл завершаецца. У пакете таксама ўключаны параметр From, які паказвае номер адправальніка, і які вам патрэбен калі трэба стежыць за размовамі па адзінам корыстніку.
Паколькі канец-тэп яўляецца публічным, кожны, хто знайдзе URL, можа адправіць фальшывыя прымэткі. Twilio падпісвае кожны webhook вашым Auth Token у заголовку X-Twilio-Signature, а Node SDK мае інструменты для пераканання. Увімкніце іх пры розгортанні паza местныя тэсты.
Автаматычна адпаведзь
Сервер праслухоўвае, але не робіць нічога. Даданне прымэткі ў адпаведзь у формате TwiML ператварае яе на бота, які рэагуе на ключовыя словы. Разместіце гэта ў працоўніку /sms пасля стварэння twiml; гэта код зменшыць і пераканае текст, прычым выберучы адпаведзь:
const incoming = req.body.Body.trim().toLowerCase();
if (incoming === "hi") {
twiml.message("Hey there! How can I help?");
} else {
twiml.message("Hmm, I didn't catch that.");
}
Twilio адрасуе вярнутую адпаведзь падаўшаму, таму не трэба додатковага вызову messages.create().
Полны сервер
Усё ў аднам файле, пры чым функцыя автадзвянка залишылася закоментаваная:
require("dotenv").config();
const express = require("express");
const bodyParser = require("body-parser");
const MessagingResponse = require("twilio").twiml.MessagingResponse;
const client = require("twilio")(
process.env.ACCOUNT_SID_TWILIO,
process.env.AUTH_TOKEN_TWILIO
);
const hostname = "127.0.0.1";
const port = 3000;
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const baseUrl = "/api/v1/";
// Health check
app.get(`${baseUrl}`, (req, res) => {
res.status(200).json({ message: "Hello World" });
});
// Goal 1: Send an SMS
app.post(`${baseUrl}sendSms`, async (req, res) => {
try {
await client.messages.create({
body: "Hello",
from: process.env.FROM_TWILIO,
messagingServiceSid: process.env.MESSAGING_SERVICE_SID_TWILIO,
to: "+92XXXXXXXXXX", // whoever you're texting
});
res.status(200).json({ message: "Text sent successfully" });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
// Goal 2: Receive replies (this endpoint must match your Twilio webhook)
app.post(`${baseUrl}sms`, (req, res) => {
const twiml = new MessagingResponse();
console.log("INCOMING ----->", req.body.Body);
// Optional auto-reply:
// const incoming = req.body.Body.trim().toLowerCase();
// if (incoming === "hi") {
// twiml.message("Hey there! How can I help?");
// } else {
// twiml.message("Hmm, I didn't catch that.");
// }
res.writeHead(200, { "Content-Type": "text/xml" });
res.end(twiml.toString());
});
app.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Галоўныя выводы
- Вызначэнне SMS — це адны вызов SDK; прыйманне SMS адбываецца через webhook, таму сервер павінен быць доступны і розумець TwiML.
- Twilio адправляе даныя у формате form-encoded, таму викорыстоўваецца парсер для URL-кодавання.
- Шлях webhook у консолі і маршрут у Express павінны збігацца, а перзапуск бесплатнага тунелю значыць новы URL.
- Беззвучныя неудачы тэста часта є наследкам обмежэнняў па перавераных номерах, а не багу.
- Перад практычным выкарыстоўваннем трэба пераканацца ў правядзімасці падпісаў і адмахнуцца ад жорсткая заданых значэнняў.
Здесь вы можете зберагаць співарозмовы, развиваць бота на адпаведных ключоўых словах чыста дадаць можлівасць заходу праз OTP. Па большым прыкладам, якія стосуюцца вызоваў праз калбэкі і перапрыбуткаў, адзірніце шасць шаблонаў інтэграцыі для надзеямага з’ѐеднання служб Node.js.