Viber Integration with Twilio Flex via Corezoid

March 15, 2022
Written by
Reviewed by

Viber Title

This guide is for Flex UI 1.x and channels that use Programmable Chat and Proxy. If you are using Flex UI 2.x or you are starting out, we recommend that you build with Flex Conversations.

Recently, one of our customers asked us to check on the feasibility of integrating Viber messenger with Twilio Flex. These were their requirements:

  • Due to the urgent nature of the situation, the solution should be quick to stand-up and deploy.
  • The solution should be scalable as this would be a critical mode of communication for the end-users.
  • The messages being exchanged should be persistent for a specific user irrespective of which agent they first engage. In short – maintain conversation history across interactions.

Prerequisites

To build this solution, you will need:

Let’s get started!

Start with Flex

If you’ve already set up your Flex instance, you can skip ahead to the next step.

If you’re new to Flex, create a new Flex account. Follow the prompts to kick off the Flex setup. During this process, several Twilio services will be created/provisioned for you.

Launch the Flex UI in your browser, and you should see something like this.

Twilio Flex with no CRM attached

Create API Keys for Corezoid

Twilio recommends to issue an API token for Corezoid and not use  Account SID and Test Auth Token. Twilio API Keys can be provisioned and revokedthrough the REST API or the Twilio Console. This provides a powerful and flexible primitive for managing access to the Twilio API.

API Token setup in the Twilio Console

For example, you might issue separate API Keys to different developers or to different subsystems within your application.

Since API Keys can be independently revoked, you have complete control of the lifecycle of your API credentials. You can create a key from here.

Set up a Viber Task Channel in Task Router

Task Channels provide a mechanism to separate tasks of different types.

Execute the below command using twilio-cli

curl -X POST https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/TaskChannels \
--data-urlencode "FriendlyName=Viber" \
--data-urlencode "UniqueName=viber" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:

{
  "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "workspace_sid": "WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "sid": "TCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "friendly_name": "Viber",
  "unique_name": "viber",
  "date_created": "2016-04-14T17:35:54Z",
  "date_updated": "2016-04-14T17:35:54Z",
  "channel_optimized_routing": true,
  "url": "https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/TaskChannels/TCXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "links": {
    "workspace": "https://taskrouter.twilio.com/v1/Workspaces/WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
  }
} 

Set up a Studio Flow for Viber

Twilio Studio is a visual tool that you can use to build communication applications with little or no code. In this section you will import and publish 1 Studio flow.

Import the Viber Flow

Navigate to the Twilio Studio Dashboard. Click + to create a new Studio Flow, then name the flow Viber Flow (or whatever name you prefer), and click Next.

Viber Studio Flow

Scroll to the bottom of the next pop-up and select the Import from JSON template, then click Next.

{
        "description": "Viber Flow",
        "states": [
                {
                        "name": "Trigger",
                        "type": "trigger",
                        "transitions": [
                                {
                                        "next": "send_to_flex_1",
                                        "event": "incomingMessage"
                                },
                                {
                                        "event": "incomingCall"
                                },
                                {
                                        "event": "incomingRequest"
                                },
                                {
                                        "event": "incomingParent"
                                }
                        ],
                        "properties": {
                                "offset": {
                                        "x": 0,
                                        "y": 0
                                }
                        }
                },
                {
                        "name": "send_to_flex_1",
                        "type": "send-to-flex",
                        "transitions": [
                                {
                                        "event": "callComplete"
                                },
                                {
                                        "event": "failedToEnqueue"
                                },
                                {
                                        "event": "callFailure"
                                }
                        ],
                        "properties": {
                                "offset": {
                                        "x": 40,
                                        "y": 300
                                },
                                "workflow": "WorkflowSID",
                                "channel": "viberTaskChannelUniqueSID",
                                "attributes": "{}"
                        }
                }
        ],
        "initial_state": "Trigger",
        "flags": {
                "allow_concurrent_calls": true
        }
}

Update the workflow and the channel to the Viber Task Channel in the placeholders in the “send_to_flex_1” with the actual values from the TaskRouter deployed as part of the Flex instance deployment.

Save the send_to_flex_1 widget after making the changes and Publish the Studio flow.

Make a note of the flowSid for the Studio flow for later.

Set up a Flex Flow

A Flex Flow is the logic linking a contact identity (e.g., SMS-enabled phone number or WhatsApp number) to Flex.

This page details the Flex Flow API Resource. Check out the additional documentation to learn more about working with Flex Flows.

Execute the below command using twilio-cli:

curl -X POST https://flex-api.twilio.com/v1/FlexFlows \
--data-urlencode "IntegrationType=studio" \
--data-urlencode "Enabled=True" \
--data-urlencode "Integration.FlowSid=FWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
--data-urlencode "ContactIdentity=viber" \
--data-urlencode "FriendlyName=Viber Flex Flow" \
--data-urlencode "ChannelType=custom" \
--data-urlencode "ChatServiceSid=ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
--data-urlencode "longLived=true" \
--data-urlencode "janitorEnabled=true" \
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:

{
    "integration": {
        "retry_count": 3,
        "flow_sid": "FWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    },
    "janitor_enabled": true,
    "integration_type": "studio",
    "date_updated": "2022-03-11T11:12:05Z",
    "enabled": true,
    "friendly_name": "Viber Flex Flow",
    "contact_identity": "viber",
    "account_sid": "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "channel_type": "custom",
    "url": "https://flex-api.twilio.com/v1/FlexFlows/FOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "sid": "FOXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "date_created": "2022-03-11T11:12:05Z",
    "long_lived": true,
    "chat_service_sid": "ISXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

Make a note of the flexFlowSid for the Flex flow. You will be using it later.

async init(flex, manager) {
   //Create Viber Task Channel
   const viberTaskChannel = flex.DefaultTaskChannels.createChatTaskChannel(
     "viber",
     (task) => task.taskChannelUniqueName === "viber"
   );}

Set up a Twilio Serverless Service

Let's create a new service called "viber" along with two functions:

  1. Check if webhook already exists, and if not, create one
  2. The webhook itself that is responsible for sending messages back to Viber

Picture of the two functions for Viber and Flex integration

create_webhook Function

This function is public because it’s being called from Corezoid (step 12 in the Corezoid section).

Please note that this is just a functional example that does not cover authentication and proper logging.

exports.handler = function (context, event, callback) {

    let client = context.getTwilioClient();
    const channelSid = event.channelSid;
    const viberId = event.viberId

    client.chat.services(<ISxxxx>)
        .channels(channelSid)
        .webhooks
        .list({ limit: 20 })
        .then(webhooks => {

            if (webhooks.filter(hook => { return (hook.configuration && hook.configuration.url && hook.configuration.url.includes("viber")) }).length > 0) {
                const res = { 'nok': 'nok' }
                return callback(null, res);
            } else {
                client.chat.services(<ISxxxx>)
                    .channels(channelSid)
                    .webhooks
                    .create({
                        type: 'webhook',
                        configuration: {
                            filters: ['onMessageSent', 'onChannelUpdated'],
                            url: `https://<FUNCTION_URL>/webhook?viberId=${viberId}`
                        }
                    })
                    .then(webhook => {
                        console.log(webhook.sid)
                        const res = { 'ok': 'ok' }
                        return callback(null, res);
                    });
            }
        })
};

webhook Function

This function can be protected as it is being called from within Twilio any time a message is being added to the channel. If the message is from the agent, then we pass it to the Viber user.

const axios = require("axios");

exports.handler = async function (context, event, callback) {

  const viberResponse = new Twilio.Response();

  const viberId = event.viberId;
  const sendBy = event.From;
  const message = event.Body;
  const viberToken = context.VIBER_TOKEN;

  if (sendBy != viberId) {
    const url = `https://chatapi.viber.com/pa/send_message`;

    try {
      viberResponse = await axios.post(
        url,
        {
          receiver: viberId,
          type: "text",
          text: message,
          sender: {
            name: "agent",
          },
        },
        {
          headers: {
            "Content-Type": "application/json",
            "X-Viber-Auth-Token": viberToken,
          },
        }
      );
    } catch (error) {
        return callback(error);
    }
    return callback(null, {viberResponseData: viberResponse.data});

  } else {
    console.log(`Message from customer. No action to be taken.`);
    return callback(null, {
      responseText: "Message sent from the customer. No Action.",
    });
  }
};

Set up a Viber Account

  1. Login to https://partners.viber.com/.
  2. Create a bot account
  3. The name of your bot is displayed and you can chat to it by using a deep link - for example, viber://pa?chatURI=flexmirotest
  4. The token is a string that is required to authorize the bot and send requests to the Bot API.

Keep your token secure and store it safely, it can be used by anyone to control your bot.

If you do not see the bot(s) in your mobile app (settings > bots) then just reinstall the app on your phone.

Viber Bot screenshot

 

Create a Corezoid Trial Account

1. Create an account on Corezoid, if not already done so. If you have already created an account click here to sign in.

2. Once signed in, you will be greeted with the Corezoid home screen:

Corezoid home screen

3. Click on the “Create” button on the top left corner to create a new process.

Create a new Corezoid process

4. Create a new process called “Viber”.

Viber Corezoid new process

5. This will open a blank canvas to build the process flow.

Blank process in Corwzoid

6. Select the “Start” widget, this opens a side panel with multiple options. Click on the “Connect to Messenger” button on the side panel.

Connect to messenger button in Corezoid

Pick Viber to integrate Corezoid and Viber

7. Enter the Viber Bot API Token which you created and saved earlier. Then click on “OK” button.

Viber new messenger bot API Token

This will connect the Viber Bot with Corezoid.

8. Let’s add additional api call widgets to the Corezoid process as described in the create customer channel blog post.

Add API callbacks in Corezoid

9. Create the channel API call:

URL = https://{{account_sid}}:{{twilio_token}}@flex-api.twilio.com/v1/Channels

Parameters:

  • FlexFlowSid = FOxxx
  • LongLived = True
  • Identity = {{sender.id}}
  • ChatFriendlyName = Viber
  • ChatUserFriendlyName = {{sender.name}}
  • Target = {{sender.id}}

Corezoid Viber channel entry of params and values

 

10. Add a “Reply to Process” widget to add the Channel SID created

A Corezoid Reply to Process widget

11. Call Function that adds webhook to the Channel (more about the function in the next chapter):
URL = https://<function_url>/create_webhook

Parameters:

  • channelSid = {{sid}}
  • viberId = {{sender.id}}

Viber Create Webhook Corezoid

 

12. Send Message to Channel Widget:
URL = https://{{account_sid}}:{{twilio_token}}@chat.twilio.com/v2/Services/{{service_sid}}/Channels/{{sid}}/Messages

Parameters:

  • Body = {{message.text}}
  • From = {{sender.id}}


Headers:

  • X-Twilio-Webhook-Enabled = True

Viber Corezoid Send Message

 

And that’s it! You've completed the straightforward example of a process used as middleware between Viber & Twilio.

Great job!

That’s it! You can start testing your solution:

  1. Send a message to your Viber Bot
  2. This triggers the process in Corezoid
  3. Corezoid API calls creates a new channel, adds webhook & adds a new message into the channel
  4. Flex Flow triggers the Studio as soon as the message is in the channel
  5. Studio creates a new task in Flex
  6. Reply in Flex that triggers webhook sending agent’s message back to the Viber

Viber converstion inside Flex

Viber example chat history integrated with Flex

More from the Twilio.org product team coming soon

This is just one of the many ways that the fast-growing Twilio.org product team is building software to help social impact organizations advance their missions with Twilio. Stay tuned for future product releases from Twilio.org that focus on the unique needs of the social sector including tools for beneficiary, volunteer, and donor engagement.

Vinit Dave is a Senior Solutions Architect at Twilio Professional Services, primarily functioning to innovate, design and build complete e2e solutions for variety to customer problems and industry verticals. He can be reached at vdave [at] twilio [dot] com.

Miroslav Botur is a Senior Solution Architect at Twilio Professional Services. He is focused mainly on Flex Insights and enhancing analytics data by using Flex plugins, Functions and advanced Studio flows. He can be reached at mbotur [at] twilio [dot] com