Skip to content

Commit

Permalink
Merge pull request #555 from twilio-labs/block-spam-calls
Browse files Browse the repository at this point in the history
feat(templates): add block-spam-calls template
  • Loading branch information
druv5319 authored Sep 4, 2024
2 parents 3a18edf + 5826c72 commit 4c9bf56
Show file tree
Hide file tree
Showing 14 changed files with 509 additions and 0 deletions.
3 changes: 3 additions & 0 deletions block-spam-calls/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# description: The path to the webhook
# configurable: false
TWILIO_VOICE_WEBHOOK_URL=/block-spam-calls
9 changes: 9 additions & 0 deletions block-spam-calls/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Changelog

## [Unreleased]

## [1.0.0]

### Added

- Initial release.
54 changes: 54 additions & 0 deletions block-spam-calls/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# block-spam-calls

Uses Twilio Add-ons to block unwanted calls by checking the spam ratings of incoming phone numbers.

## Pre-requisites

- A Twilio account - [sign up here](https://www.twilio.com/try-twilio)
- A Twilio phone number
- Spam filtering Add-ons (see below)

### Install Add-Ons

The following guide will help you to [install Add-ons](https://www.twilio.com/docs/add-ons/install). You can access the Add-ons in the Twilio console [here](https://www.twilio.com/console/add-ons). The Spam Filtering Add-ons that are used on this application are:

- [Marchex Clean Call](https://www.twilio.com/console/add-ons/XBac2c99d9c684a765ced0b18cf0e5e1c7)
- [Nomorobo Spam Score](https://www.twilio.com/console/add-ons/XB06d5274893cc9af4198667d2f7d74d09)

Once you've selected the Add-on, just click on `Install` button. Then, you will see a pop-up window where you should read and agree the terms, then, click the button `Agree & Install`. For this application, you just need to handle the incoming voice calls, so make sure the `Incoming Voice Call` box for `Use In` is checked and click `Save`.

### Function Parameters

This template by default accepts no additional parameters.

## Create a new project with the template

1. Install the [serverless toolkit](https://www.twilio.com/docs/labs/serverless-toolkit/getting-started)
2. Install the [Twilio CLI](https://www.twilio.com/docs/twilio-cli/quickstart#install-twilio-cli)
3. Initiate a new project

```
twilio serverless:init sample --template=block-spam-calls && cd sample
```

4. Start the server with the [Twilio CLI](https://www.twilio.com/docs/twilio-cli/quickstart):

```
twilio serverless:start --ngrok
```

5. Set your incoming call webhook URL for the phone number you want to configure to `https://<your-ngrok-code>.ngrok.io/block-spam-calls`

ℹ️ Check the developer console and terminal for any errors

## Deploying

Deploy your functions and assets with either of the following commands. Note: you must run these commands from inside your project folder. [More details in the docs.](https://www.twilio.com/docs/labs/serverless-toolkit)

With the [Twilio CLI](https://www.twilio.com/docs/twilio-cli/quickstart):

```
twilio serverless:deploy
```

Make sure to update your incoming voice URL to your newly deployed Function URL.
141 changes: 141 additions & 0 deletions block-spam-calls/assets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title>Get started with your Twilio Functions!</title>

<link
rel="icon"
href="https://twilio-labs.github.io/function-templates/static/v1/favicon.ico"
/>
<link
rel="stylesheet"
href="https://twilio-labs.github.io/function-templates/static/v1/ce-paste-theme.css"
/>
<script
src="https://twilio-labs.github.io/function-templates/static/v1/ce-helpers.js"
defer
></script>
<script>
window.addEventListener('DOMContentLoaded', (_event) => {
inputPrependBaseURL();
});
</script>
</head>
<body>
<div class="page-top">
<header>
<div id="twilio-logo">
<a href="https://www.twilio.com/" target="_blank" rel="noopener">
<svg
class="logo"
data-name="Layer 1"
xmlns="http://www.w3.org/2000/svg"
viewbox="0 0 60 60"
>
<title>Twilio Logo</title>
<path
class="cls-1"
d="M30,15A15,15,0,1,0,45,30,15,15,0,0,0,30,15Zm0,26A11,11,0,1,1,41,30,11,11,0,0,1,30,41Zm6.8-14.7a3.1,3.1,0,1,1-3.1-3.1A3.12,3.12,0,0,1,36.8,26.3Zm0,7.4a3.1,3.1,0,1,1-3.1-3.1A3.12,3.12,0,0,1,36.8,33.7Zm-7.4,0a3.1,3.1,0,1,1-3.1-3.1A3.12,3.12,0,0,1,29.4,33.7Zm0-7.4a3.1,3.1,0,1,1-3.1-3.1A3.12,3.12,0,0,1,29.4,26.3Z"
/>
</svg>
</a>
</div>
<nav>
<span>Your Twilio application</span>
<aside>
<svg
class="icon"
role="img"
aria-hidden="true"
width="100%"
height="100%"
viewBox="0 0 20 20"
aria-labelledby="NewIcon-1577"
>
<path
fill="currentColor"
fill-rule="evenodd"
d="M6.991 7.507c.003-.679 1.021-.675 1.019.004-.012 2.956 1.388 4.41 4.492 4.48.673.016.66 1.021-.013 1.019-2.898-.011-4.327 1.446-4.48 4.506-.033.658-1.01.639-1.018-.02-.03-3.027-1.382-4.49-4.481-4.486-.675 0-.682-1.009-.008-1.019 3.02-.042 4.478-1.452 4.49-4.484zm.505 2.757l-.115.242c-.459.9-1.166 1.558-2.115 1.976l.176.08c.973.465 1.664 1.211 2.083 2.22l.02.05.088-.192c.464-.973 1.173-1.685 2.123-2.124l.039-.018-.118-.05c-.963-.435-1.667-1.117-2.113-2.034l-.068-.15zm10.357-8.12c.174.17.194.434.058.625l-.058.068-1.954 1.905 1.954 1.908a.482.482 0 010 .694.512.512 0 01-.641.056l-.07-.056-1.954-1.908-1.954 1.908a.511.511 0 01-.71 0 .482.482 0 01-.058-.626l.058-.068 1.954-1.908-1.954-1.905a.482.482 0 010-.693.512.512 0 01.64-.057l.07.057 1.954 1.905 1.954-1.905a.511.511 0 01.71 0z"
></path>
</svg>
Live
</aside>
</nav>
</header>
</div>
<main>
<div class="content">
<h1>
<img
src="https://twilio-labs.github.io/function-templates/static/v1/success.svg"
/>
<div>
<p>Welcome!</p>
<p>Your live application with Twilio is ready to use!</p>
</div>
</h1>
<section>
<h2>Get started with your application</h2>
<p>
Follow the set up steps located in the
<a
href="https://github.com/twilio-labs/function-templates/tree/main/block-spam-calls"
target="_blank"
rel="noopener"
>Block Spam Calls functions template repo</a
>
to get started.
</p>

<p>
This app will return the
<a
href="https://www.twilio.com/docs/sms/twiml"
target="_blank"
rel="noopener"
>TwiML</a
>
required to reject or accept incoming Voice calls based on the phone
numbers spam rating.
</p>
</section>
<section>
<!-- APP_INFO_V2 -->
</section>
<section>
<h2>Troubleshooting</h2>
<ul>
<li>
Check the
<a
href="https://www.twilio.com/console/phone-numbers/incoming"
target="_blank"
rel="noopener"
>
phone number configuration
</a>
and make sure the Twilio phone number you want for your app has a
Voice webhook configured to point at the following URL
<form>
<label for="twilio-webhook">Webhook URL</label>
<input
type="text"
id="twilio-webhook"
class="function-root"
readonly="true"
value="/block-spam-calls"
/>
</form>
</li>
</ul>
</section>
</div>
</main>
<footer>
<span class="statement">We can't wait to see what you build.</span>
</footer>
</body>
</html>
83 changes: 83 additions & 0 deletions block-spam-calls/functions/block-spam-calls.protected.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Block Spam Calls
*
* Description:
* This application uses Twilio Add-ons from the Twilio Marketplace to block
* unwanted voice calls. The 2 Add-ons used in this application are Marchex
* Clean Call and Nomorobo Spam Score. The application provides the spam rating
* of every inbound call to a Twilio number via the three Add-ons.
* If the phone number is classified as spam by any of the two integrations, the
* call is rejected. If the number isn't categorized as spam, the call will go through.
*
* Contents:
* 1. Input Helpers
* 2. Main Handler
*/

/*
* 1. Input Helpers
* These helper functions help read the results from the spam Add-ons
* in the incoming voice TwiML callback.
*
* Function will return true if the call is classified as spam.
* Otherwise, it will return false.
*/

function blockedByMarchex(response) {
if (!response || response.status !== 'successful') {
return false;
}

return response.result.result.recommendation === 'BLOCK';
}

function blockedByNomorobo(response) {
if (!response || response.status !== 'successful') {
return false;
}

return response.result.score === 1;
}
/**
* 2. Main Handler
*
* This is the entry point to your Twilio Function,
* which will create a new Voice Response using Twiml based on
* the spam filters. If the call is flagged as spam by any of the
* spam filtering add-ons, the call will blocked by the <Reject> Twiml
* verb. Else, the call will proceed and the Voice Response
* will respond to the caller with a greeting.
*
* The callback will be used to return from your function
* with the Twiml Voice Response you defined earlier.
* In the callback in non-error situations, the first
* parameter is null and the second parameter
* is the value you want to return.
*/
exports.handler = function (context, event, callback) {
const twiml = new Twilio.twiml.VoiceResponse();

let blockCalls = false;

/*
* If the request body contains add-ons, check to see if any of
* the spam filtering add-ons have flagged the number.
*/
const addOns = 'AddOns' in event && JSON.parse(event.AddOns);
if (addOns && addOns.status === 'successful') {
const { results } = addOns;
blockCalls =
blockedByMarchex(results.marchex_cleancall) ||
blockedByNomorobo(results.nomorobo_spamscore);
}

if (blockCalls) {
twiml.reject();
} else {
// Add instructions here on what to do if call goes through
twiml.say('Welcome to the jungle.');
twiml.hangup();
}

callback(null, twiml);
};
6 changes: 6 additions & 0 deletions block-spam-calls/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "block-spam-calls",
"version": "1.0.0",
"private": true,
"dependencies": {}
}
Loading

0 comments on commit 4c9bf56

Please sign in to comment.