Build a Translation Bot using Twilio Whatsapp API and AWS Translate

[twilio.com] 2 weeks ago

    Are you tired of language barriers hindering your global conversations on WhatsApp? Well, fret no more! Here is an exciting solution for you.

    Imagine having a chatbot as your personal language translator on WhatsApp. It's like having a witty sidekick who understands every language, cracks hilarious jokes, and helps you connect with people from different corners of the world. With the powerful capabilities of Twilio's WhatsApp API and AWS Translate, you will build a bot that can seamlessly translate your messages of languages foreign to English in real-time.

    Through this tutorial, you will learn how to integrate Twilio's WhatsApp API and AWS Translate, unlocking a realm of endless possibilities for seamless communication.

    Prerequisites

    Here are what you need to follow along in this tutorial

    Developing Your Application

    Since you are using platforms and APIs from both Twilio and AWS, you will need access keys and the WhatsApp number to be able to read and/or write to them. This section will show you how to set up your Twilio and AWS accounts and how to access the credentials you need to build your solution.

    Setting up AWS Account

    To set up your AWS account, go to the official website of AWS services and sign up. After signing up and logging in to your console, you should set up an IAM user and give the user privilege to AWS Translate services. Amazon Translate lets you localize content for diverse global users and translate and analyze large volumes of text to activate cross-lingual communication between users.

    To access the IAM settings page on AWS console, log in to your AWS console using your account details. From the toolbar's Account menu, select Security Credentials. From the options in the left pane as shown below, select Users and proceed to create a new user (by clicking Create User) and a group that will contain all the privileges the user is entitled to on the AWS account.

    Remember to add AWS Translation services to the list of permissions for the user you just created and while logging in to AWS console, log in as IAM user with the credentials generated.

    AWS advised that it is a best and safe practice to use credentials from an IAM user instead of the one from the root user hence you are to follow this approach.

    Sign in detail for IAM User

    Once you are done with the IAM user creation, you will get the sign in details like in the photo above to log in to your AWS console.

    Now, after logging in with your IAM user details, go to the toolbar's Account menu, select Security Credentials. When the page opens up, scroll to the Access Keys section to create your access keys. Remember to select Application running outside AWS when choosing use cases for your access keys and that’s all! You will be using the access key and the secret access key in this tutorial so store them in a safe place.

    Setting up Twilio Account

    To set up your Twilio account, sign up for an account and login to your Twilio Console using your account details. From the toolbar's Account menu, select API Keys and Tokens. Take note of your test credentials as shown in the photo below, which include the Account SID and Auth Token, you will use them later in your application.

    API keys from Twilio"s Console

    To complete the setup process, access your Twilio Console dashboard and navigate to the WhatsApp sandbox in your account. This sandbox is designed to enable you to test your application in a development environment without requiring approval from WhatsApp. To access the sandbox, select Messaging from the left-hand menu, followed by Try It Out and then Send A WhatsApp Message. From the sandbox tab, take note of the Twilio phone number and the join code.

    WhatsApp connection code on Twilio"s Console

    Access the Sandbox Settings tab and configure the endpoint URL that Twilio will use to forward messages sent or received from WhatsApp. This is where you will paste the public URL for your endpoint later in the tutorial.

    WhatsApp Sandbox Settings in Twilio Console

    Building Your Node.js Server and Functions for the App

    In this section, you will delve into building your application using Node.js and Express framework. You will first set up the project directory and install the packages you will need for the project to run successfully. After that you will proceed to define the functions that will perform tasks like translating the texts, sending the translated texts back to WhatsApp and handling incoming messages from WhatsApp. You will also set up the server with Express and deploy to ngrok to test locally.

    Setting up Project Directory

    mkdir twilio-translate && cd twilio-translate && npm init
    

    This command will create a new directory called twilio-translate and initialize a node package manager for us. Go ahead and fill in the details for your project as shown below:

    Initializing our project with node package manager

    Setting up Node.js Server

    Here you will start with setting up the server by installing packages you need, defining some environmental variables which is where you will store your access keys for AWS and Twilio access and running the server using ngrok to proxy your local host to the internet.

    Execute the following command in your terminal to install the necessary dependencies you’ll need for this tutorial:

    npm i aws-sdk body-parser cors dotenv express twilio
    

    When the packages are done installing, create a file named index.js with the code below:

    import express from 'express';
    import bodyParser from 'body-parser';
    import cors from 'cors';
    const app = express();
    /** middlewares */
    app.use(express.json());
    app.use(cors());
    app.disable('x-powered-by'); // less hackers know about your stack
    app.use(bodyParser.urlencoded({ extended: false }));
    // Handle incoming messages
    app.post('/incoming-message', async (req, res) => {
      res.send("Hello World")
    });
    // Start the server
    app.listen(8000, () => {
      console.log('Server is running on port 8000');
    });
    

    The provided code import packages you installed previously for configuring your middlewares. It also creates an app instance using the express framework and the app server is now listening on port 8000. You can proxy the localhost server through ngrok to the internet by running the below command on another tab on your terminal:

    You will get a response like this with your public app address hosted on ngrok. Your server is now up and running. We can now use the base URL from ngrok in our Twilio Sandbox Settings.

    Terminal output after running ngrok tunnel

    Twilio Functions

    Next, you will write the functions for handling incoming and outgoing messages using the Twilio Whatsapp number you got from your console. For this, create a new file named functions.js in the root directory. Also create a .env file where you will store your twilio credentials and reference it in your app without exposing your keys to the public.

    If you are hosting this code on a public repository like Github, create a .gitignore file and add .env inside it so any file with that extension will be ignored while pushing your code to keep your keys safe!

    Copy this into your .env file and replace the placeholders with their respective values:

    TWILIO_ACCOUNT_SID=XXXXX
    TWILIO_AUTH_TOKEN=XXXXX
    MY_AWS_SECRET_ACCESS_KEY=XXXXX
    MY_AWS_ACCESS_KEY_ID=XXXXX
    MY_AWS_REGION=XXXXX
    

    In your functions.js file, add the following lines of code:

    import twilio from 'twilio';
    import AWS from 'aws-sdk';
    import dotenv from 'dotenv';
    dotenv.config();
    // Twilio credentials
    const accountSid = process.env.TWILIO_ACCOUNT_SID;
    const authToken = process.env.TWILIO_AUTH_TOKEN;
    // Set up Twilio client
    const twilioClient = twilio(accountSid, authToken);
    // Function to send voice note to Twilio WhatsApp number
    export async function handleOutgoingMessage(from, to, text) {
        // Use Twilio API to send `text` message from `from` to `to` number  
        await twilioClient.messages.create({
            to: to,
            from: from,
            body: text
        });
    }
    // Function to handle incoming messages
    export async function handleIncomingMessage(req, res) {
        try {
            const { Body, From, To } = req.body;
            let translation = await translateText(Body);
            handleOutgoingMessage(To, From, translation);
        } catch (error) {
            res.status(500).send(error);
        }
    }
    

    This code example uses ES6 style; add this line: "type": "module", after the line ”main”: “index.js” in your package.json` or else you will get an error while running the code.

    The functions above handle the incoming and outgoing messaging to and from Twilio with the following query parameters:

    • Body - this contains the text content to be translated or the translated text to be sent.
    • From - The sender, who the message is coming from at the moment
    • To - The recipient, who is receiving the message at the moment

    AWS Function

    In the same function.js file, you will also write the function for translating the text from Twilio Whatsapp using the AWS Node SDK you installed earlier. The updated code for the is:

    import twilio from 'twilio';
    import AWS from 'aws-sdk';
    import dotenv from 'dotenv'
    dotenv.config()
    // Twilio credentials
    const accountSid = process.env.TWILIO_ACCOUNT_SID;
    const authToken = process.env.TWILIO_AUTH_TOKEN;
    // AWS credentials
    const accessKeyId = process.env.MY_AWS_ACCESS_KEY_ID;
    const secretAccessKey = process.env.MY_AWS_SECRET_ACCESS_KEY;
    const region = `${process.env.MY_AWS_REGION}`;
    // Set up Twilio client
    const twilioClient = twilio(accountSid, authToken);
    // Set up AWS client
    const translate = new AWS.Translate({ accessKeyId, secretAccessKey, region });
    // Function to send voice note to Twilio WhatsApp number
    export async function handleOutgoingMessage(from, to, text) {
        // Use Twilio API to send `text` message from `from` to `to` number  
        await twilioClient.messages.create({
            to: to,
            from: from,
            body: text
        });
    }
    async function translateText(text) {
        const params = {
            Text: text,
            SourceLanguageCode: 'auto',
            TargetLanguageCode: 'en',
        };
        return new Promise((resolve, reject) => {
            translate.translateText(params, (err, data) => {
                if (err) reject(err);
                else {
                    const translation =  `Your translation from ${data.SourceLanguageCode} to ${data.TargetLanguageCode} is: \n ${data.TranslatedText}`;
                    resolve(translation);
                }
            });
        });
    }
    // Function to handle incoming messages
    export async function handleIncomingMessage(req, res) {
        try {
            const { Body, From, To } = req.body;
            let translation = await translateText(Body);
            handleOutgoingMessage(To, From, translation);
        } catch (error) {
            res.status(500).send(error);
        }
    }
    

    The translateText function here accepts three parameters: the text to be translated, the source language which the SDK auto detects and the target language you want to translate to which is English in this case. The function uses the instance of AWS Translate from the SDK to perform this operation and return the result which is sent back to WhatsApp by Twilio.

    Finally, update your server to run the handleIncomingMessage function when the /incoming endpoint is triggered by a user sending text to your Twilio number for translation. Update your index.js file with the highlighted lines:

    import express from 'express';
    import bodyParser from 'body-parser';
    import cors from 'cors';
    import { handleIncomingMessage } from './functions.js';
    const app = express();
    /** middlewares */
    app.use(express.json());
    app.use(cors());
    app.disable('x-powered-by'); // less hackers know about your stack
    app.use(bodyParser.urlencoded({ extended: false }));
    // Handle incoming messages
    app.post('/incoming-message', async (req, res) => {
      handleIncomingMessage(req, res) 
    });
    // Start the server
    app.listen(8000, () => {
      console.log('Server is running on port 8000');
    });
    }
    

    Testing and Product Demonstration

    Your app is now ready for testing. Before we start testing on WhatsApp, we will have to update our webhook URL on Twilio Console so that our app can communicate with the Twilio WhatsApp API. Append /incoming-message to your ngrok Forwarding URL and add it to the When a message comes in text box within the Sandbox settings.

    Updating the sandbox webhook URL to the ngrok live URL and the /incoming-message endpoint in our application.

    We will now proceed to start the project on your computer by opening a new terminal and running this command:

    Once the app is running, open your WhatsApp and send join <sandbox code> first in order to establish a connection to the sandbox. When you have established a connection, you can go ahead to send texts in languages foreign to English like French, Spanish, German etc. and you will get translations on the go. Below is a demonstration on how it works:

    A Demo of Twilio Translate App

    Conclusion

    Congratulations on creating your translation app using NodeJS, AWS Translate and Twilio. You have learned how to create a messaging application using the Express framework and integrate it with Twilio to make it available on WhatsApp. You have also learned how you can use AWS translate service to translate texts from different languages to English and vice versa. You can learn more about taking your chatbot into a production environment by referring to Twilio’s documentation.

    Desmond Obisi is a software engineer and a technical writer who loves developer experience engineering. He’s very invested in building products and providing the best experience to users through documentations, guides, building relations and strategies around products . He can be reached on Twitter, LinkedIn or through my mail desmond.obisi.g20@gmail.com.