Overview

Skill Level: Any Skill Level

Intermediate

Ingredients

Bluemix account

Telegram app installed in a phone

Step-by-step

  1. Introduction

    Sometimes people send you audio messages and you can’t listen to them. If you use Telegram app, you can create a bot that, using Watson API Speech To Text, transcribe the audio and send you a text message with its content. In any language supported by Watson.

    This tutorial will also show you how to run a Node.js server locally and in Bluemix so you can learn how to upload other apps into it.

  2. Install the Cloud Foundry command-line tool

    Go to https://github.com/cloudfoundry/cli#downloads and download the installer for your platform. Install it!

    Test if everything is ok but running the command:

     cf -v

    If it doesn’t work, make sure the binaries are in your PATH.

  3. Install the Node.js runtime

    You can install the Node.js runtime and the Node Package Manager (npm) command for your operating system from http://nodejs.org . The default installation includes both the runtime and package manager. Make sure to include the command on your PATH environment variable after installation.

    Test the installation with the command:

     npm -v

  4. Create a Node.js application in Bluemix

    Now that our environment is set, let’s create an application in Bluemix that will have the Node.js server.

    Log into your Bluemix account and, in the dashboard, click Create App.

    Then, select the web application type.

    Choose the SDK for Node.js runtime and continue.

    Now, choose a name for your application. In this tutorial, it will be TelegramWatsonBot.

    Wait while the application is staging.

    When it finishes, you can go to http://your-application-name.mybluemix.net and check it out.

  5. Add Watson’s Speech To Text API to your application

    Now that your application is created, let’s add the Watson’s Speech To Text API to it. In the side bar, click in Overview to check the details of your application. Click in the box “Add a service or API”.

    Now choose the Speech To Text API.

    Check out the API’s details and create it.

    Wait again until your application finishes staging. Don’t close Bluemix. Go to the next step instead!

  6. Set up your application locally

    In the same page that show that your application is running, there is a link where you can download the source code. Click on it and download it!

    Unzip the source code. Go to the directory and log in into Bluemix.

     cf login -a https://api.ng.bluemix.net -u USERNAME -p PASSWORD

    You can obtain you Bluemix credentials and URL now.

     cf env application-name

    In the output of the command, find the values for the system-provided VCAP_SERVICES JSON environment variable. Save the values of the url, username, and password keys from that environment variable. These values specify the URL for contacting the service and the HTTP basic authentication credentials you use with Bluemix.

    Change your package.json file and add request, watson and telegram dependencies.

     {
    "name": "NodejsStarterApp",
    "version": "0.0.1",
    "private": true,
    "scripts": {
    "start": "node app.js"
    },
    "dependencies": {
    "cfenv": "1.0.x",
    "express": "4.13.x",
    "watson-developer-cloud": "^1.4.1",
    "request": "*",
    "node-telegram-bot-api": "*"
    },
    "repository": {},
    "engines": {
    "node": "4.2.x"
    }
    }

    Now, use the node package manager to install those dependencies libraries.

     npm install

    Start the application.

     node app.js

    Access the application via the local port displayed when you started the application. The port is specified in the app.js file. By default, the application listens at port 3000, so you would enter the URL http://localhost:3000 to access the application in a browser.

  7. Create the Telegram Bot

    Now, go to your phone and open the Telegram application. To create a bot, you have to talk with the godfather of all bots: BotFather! Search for the @BotFather (it doesn’t matter if you don’t have it in your contacts, when you search for @BotFather the app will look into the servers as well).

    Open the conversation with @BotFather and start the bot.

    It will show you a list of commands. To create a new bot, type:

     /newbot

    It will the ask you to enter the bot name and username (I don’t know the diference, so I put the same name for them).

    Write down the API token. And that’s it.

  8. Create the Bot server locally

    Now that everything is configured, we can create the actual server. Create a file Bot.js in your application directory.

    Write this code into it. Remeber to replace the variables you wrote down.

    var Bot = require('node-telegram-bot-api')
    var watson = require('watson-developer-cloud');
    var request = require('request');

    var speech_to_text = watson.speech_to_text({
    username: 'BLUEMIX WATSON SPEECH TO TEXT USERNAME', //username from VCAP SERVICES
    password: 'BLUEMIX WATSON SPEECH TO TEXT PASSWORD', //password from VCAP SERVICES
    version: 'v1',
    url: 'https://stream.watsonplatform.net/speech-to-text/api'
    });

    var params = {
    model: 'pt-BR_BroadbandModel', //you can change the language here
    content_type: 'audio/ogg;codecs=opus',
    continuous: true,
    interim_results: false
    };

    var bot = new Bot('TELEGRAM API TOKEN', { polling: true }); //token generated by the bot you created
    bot.on('message', function (msg) {
    if(msg['voice']){ return onVoiceMessage(msg); }
    });

    function onVoiceMessage(msg){
    var chatId = msg.chat.id;
    bot.getFileLink(msg.voice.file_id).then(function(link){
    //setup new recognizer stream
    var recognizeStream = speech_to_text.createRecognizeStream(params);
    recognizeStream.setEncoding('utf8');
    recognizeStream.on('results', function(data){
    if(data && data.results && data.results.length>0 && data.results[0].alternatives && data.results[0].alternatives.length>0){
    var result = data.results[0].alternatives[0].transcript;
    console.log("result: ", result);
    //send speech recognizer result back to chat
    bot.sendMessage(chatId, result, {
    disable_notification: true,
    reply_to_message_id: msg.message_id
    }).then(function () {
    // reply sent!
    });
    }

    });
    ['data', 'error', 'connection-close'].forEach(function(eventName){
    recognizeStream.on(eventName, console.log.bind(console, eventName + ' event: '));
    });
    //pipe voice message to recognizer -> send to watson
    request(link).pipe(recognizeStream);
    });
    }

    Save the Bot.js file and start the server.

     node Bot.js

    Go to your phone and open Telegram. Start a conversation with the bot you have created. Send an audio message. You can check the transcribed text in your console too.

    You can also add your bot in a group so it transcribes any audio in there.

  9. Run your Bot server in Bluemix

    Your Bot server is running, but you have to keep your computer open. How nice it would be to have it running in the cloud? So, use CTRL+C and stop the local server.

    In Bluemix, the Node.js runtime have some options to run (check the docs for details). If it doesn’t found any of these options, it will look for an app.js file to run. We could just rename Bot.js to app.js and it would work. But, instead of this, let’s add our code to app.js to our server is a web server as well giving us more options to improve this solution.

    So, copy the source code from Bot.js and insert it into app.js at the beggining of the file. It will look like this.

    var Bot = require('node-telegram-bot-api')
    var watson = require('watson-developer-cloud');
    var request = require('request');

    var speech_to_text = watson.speech_to_text({
    username: 'BLUEMIX WATSON SPEECH TO TEXT USERNAME', //username from VCAP SERVICES
    password: 'BLUEMIX WATSON SPEECH TO TEXT PASSWORD', //password from VCAP SERVICES
    version: 'v1',
    url: 'https://stream.watsonplatform.net/speech-to-text/api'
    });

    var params = {
    model: 'pt-BR_BroadbandModel', //you can change the language here
    content_type: 'audio/ogg;codecs=opus',
    continuous: true,
    interim_results: false
    };

    var bot = new Bot('TELEGRAM API TOKEN', { polling: true }); //token generated by the bot you created
    bot.on('message', function (msg) {
    if(msg['voice']){ return onVoiceMessage(msg); }
    });

    function onVoiceMessage(msg){
    var chatId = msg.chat.id;
    bot.getFileLink(msg.voice.file_id).then(function(link){
    //setup new recognizer stream
    var recognizeStream = speech_to_text.createRecognizeStream(params);
    recognizeStream.setEncoding('utf8');
    recognizeStream.on('results', function(data){
    if(data && data.results && data.results.length>0 && data.results[0].alternatives && data.results[0].alternatives.length>0){
    var result = data.results[0].alternatives[0].transcript;
    console.log("result: ", result);
    //send speech recognizer result back to chat
    bot.sendMessage(chatId, result, {
    disable_notification: true,
    reply_to_message_id: msg.message_id
    }).then(function () {
    // reply sent!
    });
    }

    });
    ['data', 'error', 'connection-close'].forEach(function(eventName){
    recognizeStream.on(eventName, console.log.bind(console, eventName + ' event: '));
    });
    //pipe voice message to recognizer -> send to watson
    request(link).pipe(recognizeStream);
    });
    }


    /*eslint-env node*/

    //------------------------------------------------------------------------------
    // node.js starter application for Bluemix
    //------------------------------------------------------------------------------

    // This application uses express as its web server
    // for more info, see: http://expressjs.com
    var express = require('express');

    // cfenv provides access to your Cloud Foundry environment
    // for more info, see: https://www.npmjs.com/package/cfenv
    var cfenv = require('cfenv');

    // create a new express server
    var app = express();

    // serve the files out of ./public as our main files
    app.use(express.static(__dirname + '/public'));

    // get the app environment from Cloud Foundry
    var appEnv = cfenv.getAppEnv();

    // start server on the specified port and binding host
    app.listen(appEnv.port, '0.0.0.0', function() {

    // print a message when the server starts listening
    console.log("server starting on " + appEnv.url);
    });

    Save the new and improved app.js. Push your application into Bluemix.

     cf push application-name

    This command will upload your application back to Bluemix, install the dependencies, compile your code and deploy it. Nice. It should take a minute or two. Now, you can test again in Telegram.

  10. Conclusion

    This tutorial was made to show how easy is to integrate Watson APIs using Node.js. But instead I think it can help people understand how to create apps in Bluemix, run local servers, upload code to Bluemix and use Watson APIs.

    I built this tutorial after reading Philipp Langhans tutorial here: https://medium.com/chat-bots/building-an-ibm-watson-powered-ai-chatbot-9635290fb1d3#.o0mx2spk3 . Huge thanks to him!

Join The Discussion