Identify Phone Number Line Type with Twilio Lookup to Alert Customers over SMS or Voice

October 17, 2022
Written by
Reviewed by
Paul Kamp
Twilion

Lookup Line Type Hero

Although landlines have been decreasing in popularity with the rise of mobile phones, some households continue to use them as a primary means of contact. According to the National Center for Health Statistics, 10.4% of adults aged 65 and older have a landline alone without mobile service. This demographic is important to account for when sending critical alerts and time-sensitive notifications to customers.

In this tutorial, we are going to build a demo that checks an end user’s phone number type and sends an instant alert as a voice call or SMS depending on whether the device is a landline or mobile. You can build this in the Twilio console or programmatically. We’ll use the console in this blog post.

Prerequisites

What we will build

  1. Twilio Function that uses the Twilio Lookup v2 API to determine a phone number line type. It returns eleven different types including: mobile, landline, fixedVoip, nonFixedVoip, tollFreeand more. The Lookup API is capable of determining even more information about a phone number, including its carrier, caller name, or even if the SIM card linked to the phone number has recently changed (which indicates potential account compromise), but for our purposes we only need the line type.
  2. A Twilio Studio Flow that triggers the above Function and uses its output to decide whether to trigger a call or SMS to the customer.
  3. We will test the demo using API Explorer in the console by triggering the Studio Flow with a phone number you have access to.

Write the Function

First, we’ll build the function to return line type.

  1. Log in to the Twilio Console and navigate to the Functions tab.
  2. Functions are contained within Services. Create a Service by clicking the Create Service button. Name it “lookup”.
  3. Once you've been redirected to the new Service, click the Add + button and select Add Function from the dropdown. Rename the path from “/path_1” to “/lookup”.
  4. Copy the following code into your newly created function:
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/v2-api
  const result = await client.lookups.v2
    .phoneNumbers(phoneNumber)
    .fetch(additionalParams);
 
  return callback(null, result);
} catch (error) {
  console.error(error);
  return callback(null, error);
}
};

   5. Click Save. Under Settings select Dependencies.

   6. Update the “twilio” module version to “latest” version.

Screen Shot 2022-10-14 at 1.58.20 PM

Finally, click Deploy All. Copy the URL for the function by selecting the three dots to the right of your function name, then clicking Copy URL. You’ll use this URL in the next step, so keep it handy.

Screen Shot 2022-10-14 at 1.54.04 PM

 

Build the Studio Flow

Now, we’re going to build the Studio flow which will decide whether to send an SMS or call the customer.

  1. Navigate to the Studio tab.
  2. Select the + Widget to create a new flow. Give it a descriptive name such as “Call or SMS”. Select Next.
  3. Scroll down to select “Import from JSON” and click Next.
Import a Studio Flow fro JSON
  • Remove any existing JSON and copy the following into the box:
  •  

{
  "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.lineTypeIntelligence.type}}"
              ],
              "type": "equal_to",
              "value": "landline"
            }
          ]
        },
        {
          "next": "send_message_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to mobile",
              "arguments": [
                "{{widgets.lookup.parsed.lineTypeIntelligence.type}}"
              ],
              "type": "equal_to",
              "value": "mobile"
            }
          ]
        },
        {
          "next": "send_message_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to fixedVoip",
              "arguments": [
                "{{widgets.lookup.parsed.lineTypeIntelligence.type}}"
              ],
              "type": "equal_to",
              "value": "fixedVoip"
            }
          ]
        },
        {
          "next": "send_message_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to nonFixedVoip",
              "arguments": [
                "{{widgets.lookup.parsed.lineTypeIntelligence.type}}"
              ],
              "type": "equal_to",
              "value": "nonFixedVoip"
            }
          ]
        },
        {
          "next": "send_message_1",
          "event": "match",
          "conditions": [
            {
              "friendly_name": "If value equal_to tollFree",
              "arguments": [
                "{{widgets.lookup.parsed.lineTypeIntelligence.type}}"
              ],
              "type": "equal_to",
              "value": "tollFree"
            }
          ]
        }
      ],
      "properties": {
        "input": "{{widgets.lookup.parsed.lineTypeIntelligence.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      \"fields\":\"line_type_intelligence\"\n   }\n}",
        "url": "https://lookupv2-3434.twil.io/lookup"
      }
    }
  ],
  "initial_state": "Trigger",
  "flags": {
    "allow_concurrent_calls": true
  }
}

Your flow has been created! Now, there are just a few more steps to finish the flow.

  1. Click on the widget that is labeled “lookup”. You’ll need to edit this field to reference the function you created earlier.
  2. Scroll down to “Request URL” and paste the Function URL you copied in Writing the Function Step 7.
  3. Click “Save”. Select “Publish” to publish the latest changes.
  4. Return to the Studio Flows page and copy the SID of the Flow you just created.

Test your Demo

Your next step is creating a Studio Flow execution. An execution represents a specific person’s run through the Flow. The Twilio API Explorer allows us to make API requests within the console, so you can easily test out your Flow without setting up your own environment for running code.

  1. Navigate to the API Explorer tab.
  2. In the dropdown, begin typing “Studio” and select “Studio”.
Studio executions in the API Explorer
  • Select the dropdown for Studio Flows.
  • Scroll down and select “Create an Execution”
Create an execution in the API Explorer
  • Enter a phone number for a line you have access to in the “To” field.
  • Enter a Twilio phone number that you own in the “From” field. If you do not own a Twilio phone number, scroll up to the Prerequisites section for instructions to buy one.
  • Paste a Flow SID you copied above into the Flow SID section.'
  • Click Make Request. Your device will receive an SMS or phone call, depending on whether your phone number is mobile or a landline.
  • Alerting customers based on line type

    Congratulations! You now have a serverless Studio flow and Function which can alert customers via SMS or voice call depending on their phone number line type. You can integrate this Flow into your environment to send critical, real-time alerts using the API call referenced above.

    To learn more about the power of Studio Flows as a low-code communications tool, check out this Quickstart guide or other existing templates when creating a new Studio Flow. Happy building!

    Angela Wieber is a Principal Solutions Engineer at Twilio, where she loves building and educating on cloud-based technologies that enable critical communications. She is based out of Austin, TX, home of the best BBQ and live music venues. She can be reached at awieber [at] twilio.com

    Anthony Wong is a Principal Solutions Engineer at Twilio. He’s focused on building integration between Twilio and companies like Salesforce, so adoption is one-click away. He can be found at anwong [at] twilio.com