虽然随着移动电话的兴起,固定电话的普及率越来越低,但有些家庭仍然把固定电话作为主要的联系手段。根据国家卫生统计中心的数据,10.4%的65岁及以上的成年人只有固定电话而没有移动服务。在向客户发送重要的警报和时间敏感的通知时,这一人口统计学上的情况是很重要的。
在本教程中,我们将建立一个演示,检查终端用户的电话号码类型,并根据设备是固定电话还是移动电话,以语音电话或短信的方式发送即时警报。你可以在Twilio控制台或以编程方式建立这个程序。在这篇博文中,我们将使用控制台。
我们要做的是
- 一个Twilio函数,使用 Twilio Lookup API来确定电话号码的线路类型。它返回 "手机 "或 "固定电话"。Lookup API能够确定关于一个电话号码的更多信息,包括运营商类型或来电者姓名,但对于我们的目的,我们只需要线路类型。
- 一个Twilio Studio流程,触发上述功能,并使用其输出来决定是否触发对客户的呼叫或短信。
- 我们将使用控制台中的 API Explorer来测试这个演示,用一个你可以访问的电话号码来触发Studio Flow。
编写函数
首先,我们要建立一个函数来返回线路类型:
- 登录Twilio控制台,导航到 函数标签。
- 函数包含在服务中。点击 " 创建服务"按钮,创建一个 服务。将其命名为 "lookup"。
- 一旦你被重定向到新的服务,点击Add + 按钮,从下拉菜单中选择Add Function 。将路径从"/path_1 "重命名为"/lookup"。
- 将以下代码复制到你新创建的函数中:
exports.handler = async (context, event, callback) => {
const client = context.getTwilioClient();
const {phoneNumber, additionalParams = {}} = event;
try {
// This allows you to pass in the phone number while allowing you to
// add additional lookup attributes. Like Carrier and Caller Name.
// See: https://www.twilio.com/docs/lookup/api
const result = await client.lookups
.phoneNumbers(phoneNumber)
.fetch(additionalParams);
return callback(null, result);
} catch (error) {
console.error(error);
return callback(null, error);
}
};
最后,点击Deploy All 来部署该函数。
构建工作室流程
现在,我们要建立一个Studio流程,它将决定是发送短信还是给客户打电话:
- 导航到 Studio标签。
- 选择 "+"小部件来创建一个新的流程。给它一个描述性的名字,如 "呼叫或短信"。选择下一步。
- 向下滚动选择 "从JSON导入 "并点击下一步。

- 删除任何现有的JSON,并将以下内容复制到框中:
{
"description": "Call or Text a Phone Number",
"states": [
{
"name": "Trigger",
"type": "trigger",
"transitions": [
{
"event": "incomingMessage"
},
{
"event": "incomingCall"
},
{
"event": "incomingConversationMessage"
},
{
"next": "lookup",
"event": "incomingRequest"
},
{
"event": "incomingParent"
}
],
"properties": {
"offset": {
"x": 0,
"y": 0
}
}
},
{
"name": "split_1",
"type": "split-based-on",
"transitions": [
{
"event": "noMatch"
},
{
"next": "call_user_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to landline",
"arguments": [
"{{widgets.lookup.parsed.carrier.type}}"
],
"type": "equal_to",
"value": "landline"
}
]
},
{
"next": "send_message_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to mobile",
"arguments": [
"{{widgets.lookup.parsed.carrier.type}}"
],
"type": "equal_to",
"value": "mobile"
}
]
},
{
"next": "send_message_1",
"event": "match",
"conditions": [
{
"friendly_name": "If value equal_to voip",
"arguments": [
"{{widgets.lookup.parsed.carrier.type}}"
],
"type": "equal_to",
"value": "voip"
}
]
}
],
"properties": {
"input": "{{widgets.lookup.parsed.carrier.type}}",
"offset": {
"x": 90,
"y": 420
}
}
},
{
"name": "call_user_1",
"type": "make-outgoing-call-v2",
"transitions": [
{
"next": "say_play_1",
"event": "answered"
},
{
"event": "busy"
},
{
"event": "noAnswer"
},
{
"event": "failed"
}
],
"properties": {
"machine_detection_speech_threshold": "2400",
"detect_answering_machine": false,
"send_digits": "",
"sip_auth_username": "",
"offset": {
"x": 10,
"y": 730
},
"recording_status_callback": "",
"sip_auth_password": "",
"recording_channels": "mono",
"timeout": 60,
"machine_detection": "Enable",
"trim": "true",
"record": false,
"machine_detection_speech_end_threshold": "1200",
"machine_detection_timeout": "30",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"machine_detection_silence_timeout": "5000"
}
},
{
"name": "say_play_1",
"type": "say-play",
"transitions": [
{
"event": "audioComplete"
}
],
"properties": {
"offset": {
"x": -220,
"y": 990
},
"loop": 1,
"say": "This is an alert"
}
},
{
"name": "send_message_1",
"type": "send-message",
"transitions": [
{
"event": "sent"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": 440,
"y": 710
},
"service": "{{trigger.message.InstanceSid}}",
"channel": "{{trigger.message.ChannelSid}}",
"from": "{{flow.channel.address}}",
"to": "{{contact.channel.address}}",
"body": "This is an alert"
}
},
{
"name": "lookup",
"type": "make-http-request",
"transitions": [
{
"next": "split_1",
"event": "success"
},
{
"event": "failed"
}
],
"properties": {
"offset": {
"x": 390,
"y": 190
},
"method": "POST",
"content_type": "application/json;charset=utf-8",
"body": "{\n \"phoneNumber\":\"{{contact.channel.address}}\",\n \"additionalParams\":{\n \"type\":\"carrier\"\n }\n}",
"url": "https://ui-2-7342.twil.io/lookup"
}
}
],
"initial_state": "Trigger",
"flags": {
"allow_concurrent_calls": true
}
}
你的流程已经创建现在,只有几个步骤可以完成这个流程:
- 点击标有 "查找 "的小部件。你需要编辑这个字段以引用你先前创建的函数。
- 使用下拉菜单选择 "lookup "服务、"ui "环境和"/lookup "功能。
- 点击 "保存"。选择 "发布 "来发布最新的变化。
- 返回到Studio Flows页面,复制你刚刚创建的Flow的SID。
测试你的演示
你的下一步是创建一个Studio流程的执行。执行代表了一个特定的人在流程中的运行。Twilio API Explorer允许我们在控制台中进行API请求,所以你可以很容易地测试你的Flow,而不需要为运行代码设置自己的环境:
- 导航到 API Explorer标签。
- 在下拉菜单中,开始输入 "Studio "并选择 "Studio"。

- 选择Studio Flows的下拉菜单。
- 向下滚动并选择 "创建一个执行"。

- 在 "收件人 "栏中输入一个你可以访问的线路的电话号码。
- 在 "发件人 "栏中输入一个你拥有的Twilio电话号码。如果你没有Twilio的电话号码,请向上滚动到先决条件部分,了解购买电话号码的说明。
- 将你上面复制的流量SID粘贴到流量SID部分。
- 点击发出请求。你的设备将收到一条短信或电话,这取决于你的电话号码是手机还是座机。
根据线路类型提醒客户
祝贺你!你现在有了一个无服务器的Studio流程。你现在有了一个无服务器的Studio流程和功能,可以根据客户的电话线类型,通过短信或语音电话提醒客户。你可以把这个流程集成到你的环境中,使用上面提到的API调用发送关键的实时警报。