# Getting Started

{% hint style="info" %}
Make sure to **add your email** to the plugin to (**App Owner Email**) field. It helps us provide better support when you need it.
{% endhint %}

## Create a Twilio Account

Go to [Twilio](https://twilio.com/referral/q7Bd3H) and Get started with a free Twilio account (No credit card required).

## Buy a phone number

Go to the **console** > [Programmable Voice menu](https://www.twilio.com/console/voice/numbers). Under this menu > **Numbers** and Get a number

## Create a voice application

1. Under the Programmable Voice Menu > TwiML > [TwiML Apps](https://www.twilio.com/console/voice/twiml/apps) then&#x20;
2. Click "+" to create a new TwiLM app
3. Give your app a **friendly name**, then click save.

## Create an API key

1. Go to [API Keys](https://console.twilio.com/us1/account/keys-credentials/api-keys)
2. Click "New API key"
3. Give it a friendly name (ex my bubble app voice)
4. Click Create
5. Copy the SID and Secret and store them in a safe place. Later you will add them to the [functions environment variables](#create-token-and-service-functions).&#x20;

## Create token & service functions

1. Go to [functions](https://console.twilio.com/us1/develop/functions/services)
2. Create a new service. Give it a name (ex yourappname)
3. Add the following environment variables
   1. CALLER\_ID (*optional* if you're planing on using mutliple Twilio numbers ignore this step)
   2. TWIML\_APP\_SID: add the voice application SID from the [voice application step](#create-a-voice-application)
   3. TWILIO\_API\_KEY: add the API key from the [API key step](#create-an-api-key)
   4. TWILIO\_API\_SECRET: add the API key secrete from the [API key step](#create-an-api-key)

### Create Access Token Function

1. Create a new function. Click "Add +" -> Add Function -> give the function a name (ex access-token)
2. Add following code

```javascript
exports.handler = function (context, event, callback) {
    const AccessToken = require('twilio').jwt.AccessToken;
    const VoiceGrant = AccessToken.VoiceGrant;

    // Prepare response
    let response = new Twilio.Response();

    // Add CORS Headers
    let headers = {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET",
    "Content-Type": "application/json"
    };
    
    // Used when generating any kind of tokens
    const twilioAccountSid = context.ACCOUNT_SID;
    const twilioApiKey = context.TWILIO_API_KEY;
    const twilioApiSecret = context.TWILIO_API_SECRET;

    // Used specifically for creating Voice tokens
    const outgoingApplicationSid = context.TWIML_APP_SID;
    const identity = event.identity;
    const ttl = 3600; //Time to live for the token, in seconds. 

    // Create a "grant" which enables a client to use Voice as a given user
    const voiceGrant = new VoiceGrant({
        outgoingApplicationSid: outgoingApplicationSid,
        incomingAllow: true, // Optional: add to allow incoming calls
    });

    // Create an access token which we will sign and return to the client,
    // containing the grant we just created
    const token = new AccessToken(
        twilioAccountSid,
        twilioApiKey,
        twilioApiSecret,
        { identity: identity,
        ttl: ttl
          }
    );
    token.addGrant(voiceGrant);

    const jwt = token.toJwt();
    console.log(jwt);

    response.setHeaders(headers);
    response.setStatusCode(200);

    // Set body
    response.setBody({
        'identity': identity,
        'token': jwt
    });

    // Return the response
    callback(null, response);
};
```

1. Make sure the function is Public, Click the icon next to the function and select Public
2. Save
3. Deploy

### Create Voice Function

1. Create a new function. Click "Add +" -> Add Function -> give the function a name (ex client-voice)
2. Add following code \
   Replace `context.CALLER_ID` with `event.appCallerId` if you are using multi Twilio numbers

```javascript
exports.handler = function(context, event, callback) {
    let twiml = new Twilio.twiml.VoiceResponse();
    console.log(event.To)
    console.log(event.From)
    if(event.To) {
      // Wrap the phone number or client name in the appropriate TwiML verb
      // if is a valid phone number
      const attr = isAValidPhoneNumber(event.To) ? 'number' : 'client';

      const dial = twiml.dial({
        answerOnBridge: true,
        callerId: context.CALLER_ID
      });
      dial[attr]({}, event.To);
    } else {
      twiml.say('Sorry unable to make the call!');
    }

     callback(null, twiml);
};

/**
* Checks if the given value is valid as phone number
* @param {Number|String} number
* @return {Boolean}
*/
function isAValidPhoneNumber(number) {
  return /^[\d\+\-\(\) ]+$/.test(number);
};
```

1. Make sure the function is Public, Click the icon next to the function and select Public
2. Save
3. Deploy

## Add the voice URL to the Twilio voice app you have created

To get your capability token URL:

1. Go to [Functions](https://www.twilio.com/console/functions/manage), then manage.
2. Click the [voice function](#create-voice-function) then&#x20;
3. **Copy URL** (<https://xxxx-####.twil.io/client-voice>)

Then add the URL to your app

1. Go to [TwiML Apps](https://www.twilio.com/console/voice/twiml/apps)
2. Select your app
3. In Voice > Request URL > Paste your client voice URL (<https://xxxx-####.twil.io/client-voice>)

## Add the access token URL to your Bubble plugin

To get your access token URL:

1. Go to [Functions](https://www.twilio.com/console/functions/manage), then manage.&#x20;
2. Click service then the [access token function](#create-access-token-function)
3. **Copy URL** it should be something like <https://xxxx-####.twil.io/capability-token>
4. Paste this Capability token URL in your bubble plugin

## Plugin Settings

Make sure you have all the plugin settings filled as shown below. Go to Plugins > Twilio Plugin > Fill out the username, password, accessTokenURL, & App Owner Email

<figure><img src="/files/Fj9NDeZeNjk8kTv7eMc8" alt=""><figcaption></figcaption></figure>

## Log Level

The value is a number that corresponds to the different levels of logging available. For best practice only change the log level when needed.

<table><thead><tr><th width="124">Option</th><th>Logging Type</th></tr></thead><tbody><tr><td>0</td><td>TRACE</td></tr><tr><td>1</td><td>DEBUG</td></tr><tr><td>2</td><td>INFO</td></tr><tr><td>3</td><td>WARN</td></tr><tr><td>4</td><td>ERROR</td></tr><tr><td>5</td><td>SILENT</td></tr></tbody></table>

{% hint style="info" %}
If you are using an old version of our plugin you may need to use the following function instead.
{% endhint %}

## Create a quick client functions (capability token and voice function) <mark style="background-color:red;">LEGACY</mark>

1. Go to [Functions](https://www.twilio.com/console/functions/manage),&#x20;
2. Click "+" to create a new function, then select "**Twilio Client Quickstart**".&#x20;
3. Then Enter your APP\_SID ( you will find it under [TwiML Apps,](https://www.twilio.com/console/voice/twiml/apps/) click your app then copy the app SID) and CALLER\_ID (Your [Twilio phone number](https://www.twilio.com/console/phone-numbers/incoming) formatted as +11231231234)
4. Under the function configuration code replace `const identity = 'the_user_id'` with `const identity = event.identity`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inova.us/v1/twilio-in-browser-call-plugin/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
