如何使用 Node.js 和 Express 发送和接收短信
本文最初发表于Nexmo 博客,但我想为 dev.to 社区添加更多内容。如果您不想跟着学习,只想尝试一下,我已将代码上传到 Glitch,并设置了一个 Nexmo 应用程序,其中包含几个不同国家的 Nexmo 电话号码,您可以发送短信至 +442038973497 或 +19373652539 并使用自动回复功能。如果您想让我设置您所在国家/地区的电话号码,请在 Twitter 上告诉我,我会提供该号码并更新此帖子,供其他人使用。
Nexmo 提供一些 API,可让您在世界任何地方收发大量短信。获得虚拟电话号码后,您可以使用这些 API 管理出站消息(“发送”)和入站消息(“接收”)。在本文中,您将学习如何使用Node.js和Express收发短信。
我们将首先使用 Node.js 和旧版SMS API(Nexmo 的第一个 API)发送一条短信,然后重写该代码,使用新的Messages API发送相同的短信。之后,我们将构建一个可以使用 Express 接收短信的 Webhook。本文将重点介绍短信的收发,但如果您想使用 Facebook Messenger、Viber 或 Whatsapp 收发短信,也可以使用 Messages API 来实现。
您可以扩展我们在此处构建的应用程序,以便回复传入的短信,或者包含更复杂的交互式元素,并让您能够构建满足短信需求的自动回复程序。
先决条件
在开始之前,请确保您已:
使用 SMS API 发送短信
SMS API 是第一个 Nexmo API,我们将使用它向您的电话号码发送短信。
安装 Node.js 依赖项
首先,初始化一个 NPM 包。否则,旧版本的 NPM 会报错,提示安装包时缺少package.json
first 命令。只需使用默认的 init 命令,然后安装nexmo
Node.js 包即可。
$ npm init
$ npm install nexmo
初始化依赖项
我们将创建一个新的 JavaScript 文件,我们将其命名为index.js
。
$ touch index.js
我们需要在您创建的文件中初始化我们之前安装的 Nexmo 节点库index.js
:
const Nexmo = require('nexmo')
const nexmo = new Nexmo({
apiKey: NEXMO_API_KEY,
apiSecret: NEXMO_API_SECRET
})
将其中的值替换为你的实际 API 密钥和密码。你可以在Nexmo 仪表盘的“入门”页面上找到它们。
发送短信
Nexmo 库提供了一个使用 SMS API 发送短信的方法,即nexmo.message.sendSms
。该方法接受 3 个字符串和一个对象作为参数:用于发送短信的 Nexmo 号码、用于接收短信的电话号码、短信文本以及短信编码选项。它还接受一个回调函数,该回调函数在 API 请求完成后调用。
响应数据包含一个数组,其中包含所有已发送的消息及其状态信息。大多数情况下,该数组中只有一个元素,但如果短信长度超过 160 个字符,则会将其拆分为多部分短信,然后数组中包含每个部分的数据。如果短信状态为 0,则表示短信发送成功;否则,该短信的错误数据位于error-text
短信的属性中。
因为我的文本中包含表情符号,所以我在选项对象中设置了类型unicode
,否则,该表情符号将作为在网络上发送?
。
let text = "👋Hello from Nexmo";
nexmo.message.sendSms("Nexmo", "TO_NUMBER", text, {
type: "unicode"
}, (err, responseData) => {
if (err) {
console.log(err);
} else {
if (responseData.messages[0]['status'] === "0") {
console.log("Message sent successfully.");
} else {
console.log(`Message failed with error: ${responseData.messages[0]['error-text']}`);
}
}
})
如果您的运营商网络支持字母数字发件人 ID,FROM
则可以是文本而不是电话号码(对于我的示例来说它是Nexmo
。如果您的网络不支持字母数字发件人 ID(例如在美国),它必须是电话号码。
根据您尝试发送短信的国家/地区,有些法规要求您必须拥有发送短信的电话号码,因此您必须购买一个 Nexmo 电话号码。您可以在Nexmo 仪表板或通过 CLI 进行购买:
$ nexmo number:buy --country_code US --confirm
您可以运行代码并使用以下方式接收短信:
$ node index.js
使用新消息 API 发送短信
Nexmo 有一个较新的 API,用于处理短信发送,称为 Messages API。它是一个多渠道 API,可以通过不同的渠道发送消息,例如短信、Facebook Messenger、Viber 和 Whatsapp。该 API 目前处于 Beta 阶段,因此如果我们想使用它发送相同的短信,我们需要安装 Nexmo 节点库的 Beta 版本。
$ npm install nexmo@beta
运行 ngrok
如果您以前没有使用过 ngrok,可以参考一篇博客文章了解如何使用它。如果您熟悉 ngrok,请http
在 3000 端口上运行它。
$ ngrok http 3000
ngrok 运行后,会返回一个随机 URL,稍后我们会用它作为 Webhook 的基础。我的 URL 如下http://5b5c1bd0.ngrok.io
:
创建消息应用程序
要与消息 API 交互,我们需要在 Nexmo 平台上创建一个消息应用程序来验证我们的请求。应用程序更像是容器,是用于在 Nexmo 平台上分组所有数据的元数据。我们将使用 Nexmo 仪表板创建一个应用程序,它需要一个名称、一个入站 URL 和一个状态 URL。
我们还会将密钥文件保存在磁盘上。应用程序在公钥/私钥系统上运行,因此当您创建应用程序时,会生成一个公钥并由 Nexmo 保存;同时,也会生成一个私钥(不由 Nexmo 保存),并在应用程序创建时返回给您。稍后我们将使用私钥来验证库调用。
使用您在上一步中获得的 ngrok URL,并填写相应的字段,/webhooks/status
并/webhooks/inbound
在相应的字段后附加 和 。当消息到达 Messages API 时,有关该消息的数据将发送到入站 URL。当您使用该 API 发送消息时,有关消息状态的数据将发送到状态 URL。
初始化依赖项
让我们替换之前创建的文件的内容。我们需要在index.js
您创建的文件中初始化之前安装的 Nexmo 节点库:
const Nexmo = require('nexmo')
const nexmo = new Nexmo({
apiKey: NEXMO_API_KEY,
apiSecret: NEXMO_API_SECRET,
applicationId: NEXMO_APPLICATION_ID,
privateKey: NEXMO_APPLICATION_PRIVATE_KEY_PATH
})
将其中的值替换为您的实际 API 密钥和秘密、您刚刚创建的应用程序的应用程序 ID 以及您保存的私钥的路径。
发送相同的短信
为了使用 Messages API 发送短信,我们将使用nexmo.channel.send
Nexmo 节点库 Beta 版中的方法。该方法接受对象作为参数,其中包含收件人、发件人和内容的信息。不同的渠道会有所不同,您需要查看其他渠道的API 文档。
对于短信,收件人和发件人的类型为sms
,并且对象也必须包含一个 number 属性。内容对象接受一个 text 类型和一个文本消息。回调函数返回一个错误和响应对象,我们将记录操作成功或失败的消息。
let text = "👋Hello from Nexmo";
nexmo.channel.send(
{ "type": "sms", "number": "TO_NUMBER" },
{ "type": "sms", "number": "Nexmo" },
{
"content": {
"type": "text",
"text": text
}
},
(err, responseData) => {
if (err) {
console.log("Message failed with error:", err);
} else {
console.log(`Message ${responseData.message_uuid} sent successfully.`);
}
}
);
您可以运行代码并使用以下方式接收短信:
$ node index.js
就这样,您使用两个不同的 Nexmo API 发送了同一条短信。您会注意到,Messages API 的用法更加繁琐,而这两个 API 只需一个方法即可完成同一件事。
接收短信
当 Nexmo 电话号码收到短信时,Nexmo 会将该消息传递给您在 Nexmo 仪表板中指定的 Webhook。要设置 Webhook URL,请转到Nexmo 仪表板中您电话号码旁边的小齿轮图标,并在“入站 Webhook URL”字段中填写YOUR_NGROK_URL/webhooks/inbound
。别忘了替换您实际的 ngrok URL。
创建Web服务器
我们将使用它来创建我们的 Web 服务器,express
因为它是最流行且易于使用的 Node.js 框架之一。我们还会查看入站 URL 的请求主体,因此我们需要从 npm 安装body-parser
它express
。
$ npm install express body-parser
让我们为此创建一个新文件,并将其命名为server.js
:
$ touch server.js
我们将创建一个基本的express
应用程序,它使用 JSON 解析器,bodyParser
并将选项设置urlencoded
为true
。让我们填写server.js
我们创建的文件。我们将使用端口 3000 作为服务器监听的端口,我们已经在端口 3000 上运行了 ngrok。
const app = require('express')()
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.listen(3000)
为入站 URL 创建 Webhook
对于入站 URL,我们将创建一个 post 处理程序/webhooks/inbound
,并将请求正文记录到控制台。由于 Nexmo 具有重试机制,如果 URL 没有响应,它将不断重新发送消息200 OK
,因此我们将返回一个200
状态。
app.post('/webhooks/inbound-message', (req, res) => {
console.log(req.body);
res.status(200).end();
});
您可以使用以下方式运行代码:
$ node server.js
试用
现在,从你的手机向你的 Nexmo 号码发送一条短信。你应该会在运行代码的终端窗口中看到这条消息。它看起来类似于:
我希望它有效,并且您刚刚学会了如何使用 Nexmo API 和 Node.js 发送和接收短信。
自动回复器
自动回复器是发送和接收短信的最常见用例之一。我想进一步扩展这个示例,所以让我们用你刚刚学到的知识来构建一个短信自动回复器。如果你将目前学到的两点结合起来,在入站 Webhook 中,你就拥有了一个短信自动回复器,它会回复所有收到的短信。
app.post('/webhooks/inbound', (req, res) => {
console.log(req.body);
nexmo.channel.send(
{ "type": "sms", "number": req.body.msisdn },
{ "type": "sms", "number": req.body.to },
{
"content": {
"type": "text",
"text": text
}
},
(err, responseData) => {
if (err) {
console.log("Message failed with error:", err);
} else {
console.log(`Message ${responseData.message_uuid} sent successfully.`);
}
}
);
res.status(200).end();
});
因为我很喜欢 NumbersAPI,所以我想把它也用在自动回复器上。我想修改自动回复器,让它检查收到的短信内容是否是数字,然后从 Numbers API 获取关于该数字的信息。获取信息后,我会把它和短信一起发回去。
首先,我们需要安装一个 HTTP 请求库,我不太喜欢http
Node.js 默认的那个。巧的是,它的名字是request
,所以我们通过 来安装它npm
:
$ npm install request
http://numbersapi.com/${number}
每次端点收到 POST 请求时,我们都会向 发起请求/webhooks/inbound
,其中number
代表我们收到的短信中的数字。我们需要将文本解析为整数。我将其默认为 42 而不是 0,因为 42 代表生命的意义。
让我们更新/webhooks/inbound
路由,在回复收到的短信之前向 NumbersAPI 发出请求。
app.post('/webhooks/inbound', (req, res) => {
console.log(req.body)
var number = parseInt(req.body.text) || 42;
request(`http://numbersapi.com/${number}`, (error, response, body) => {
if (error) {
text = "The Numbers API has thrown an error."
} else {
text = body
}
nexmo.channel.send(
{ "type": "sms", "number": req.body.msisdn },
{ "type": "sms", "number": req.body.to },
{
"content": {
"type": "text",
"text": text
}
},
(err, responseData) => {
if (err) {
console.log("Message failed with error:", err);
} else {
console.log(`Message ${responseData.message_uuid} sent successfully.`);
}
}
);
res.status(200).end();
})
});
试用
作为参考,您的最终server.js
文件应该类似于此。如果您已经完成了这么长时间的操作,则需要node server.js
在终端中再次运行以重新启动服务器,然后就可以开始了。向您的 Nexmo 电话号码发送一条包含号码的短信,然后开始与您的自动回复器进行交互。
编者注:了解有关消息 API 的更多信息
如果您想了解更多关于 Messages API 的信息,不妨来参加我们在旧金山举办的Vonage Campus 活动。Alex(本文作者)将在那里举办一个关于构建语音网站的研讨会——他喜欢谈论 JavaScript 的各种话题,所以这是一个与 Nexmo 成员交流的好机会。
如何使用 Node.js 和 Express 发送和接收短信一文首先出现在Nexmo 开发者博客上。
文章来源:https://dev.to/vonagedev/how-to-send-and-receive-sms-messages-with-node-js-and-express-4g46