Skip to content

Repository files navigation

Viber Node.JS Bot API

Use this library to develop a bot for the Viber platform. The library is available on GitHub as well as a package on npm.

License

This library is released under the terms of the Apache 2.0 license. See License for more information.

Library Prerequisites

  1. Node >= 5.0.0
  2. An Active Viber account on a platform which supports Public Accounts/ bots (iOS/Android). This account will automatically be set as the account administrator during the account creation process.
  3. Active Public Account/ bot - Create an account here.
  4. Account authentication token - unique account identifier used to validate your account in all API requests. Once your account is created your authentication token will appear in the account’s “edit info” screen (for admins only). Each request posted to Viber by the account will need to contain the token.
  5. Webhook - Please use a server endpoint URL that supports HTTPS. If you deploy on your own custom server, you'll need a trusted (ca.pem) certificate, not self-signed. Read our blog post on how to test your bot locally.

Installation

This library is released on npm.

npm

Install with npm install viber-bot --save

Express

If you are already using express or equivalent, you can do the following:

app.use("/viber/webhook",bot.middleware());

Please revisit app.use() documentation. For more information see ViberBot.middleware().

Let's get started!

Creating a basic Viber bot is simple:

  1. Import viber-bot library to your project
  2. Create a Public Account or bot and use the API key from https://developers.viber.com
  3. Configure your bot as described in the documentation below
  4. Add the bot as middleware to your server with bot.middleware()
  5. Start your web server
  6. Call setWebhook(url) with your web server url

Creating an echo Bot

Firstly, let's import and configure our bot:

'use strict';constViberBot=require('viber-bot').Bot;constBotEvents=require('viber-bot').Events;constbot=newViberBot({authToken: YOUR_AUTH_TOKEN_HERE,name: "EchoBot",avatar: "http://viber.com/avatar.jpg"// It is recommended to be 720x720, and no more than 100kb.});// Perfect! Now here's the key part:bot.on(BotEvents.MESSAGE_RECEIVED,(message,response)=>{// Echo's back the message to the client. Your bot logic should sit here.response.send(message);});// Wasn't that easy? Let's create HTTPS server and set the webhook:consthttps=require('https');constport=process.env.PORT||8080;// Viber will push messages sent to this URL. Web server should be internet-facing.constwebhookUrl=process.env.WEBHOOK_URL;consthttpsOptions={key: ...,cert: ...,ca: ...
};// Trusted SSL certification (not self-signed).https.createServer(httpsOptions,bot.middleware()).listen(port,()=>bot.setWebhook(webhookUrl));

Using Winston logger

We provide an option to use Winston logger with our library. The only requirement is that you use Winston >= 2.0.0.

'use strict';constViberBot=require('viber-bot').Bot;constwinston=require('winston');consttoYAML=require('winston-console-formatter');// makes the output more friendlyfunctioncreateLogger(){constlogger=newwinston.Logger({level: "debug"});// We recommend DEBUG for developmentlogger.add(winston.transports.Console,toYAML.config());returnlogger;}constlogger=createLogger();constbot=newViberBot({logger: logger,authToken: ...,
...
});

Do you supply a basic router for text messages?

Well funny you ask. Yes we do. But a word of warning - messages sent to your router callback will also be emitted to the BotEvents.MESSAGE_RECEIVED event.

constTextMessage=require('viber-bot').Message.Text;// A simple regular expression to answer messages in the form of 'hi' and 'hello'.bot.onTextMessage(/^hi|hello$/i,(message,response)=>response.send(newTextMessage(`Hi there ${response.userProfile.name}. I am ${bot.name}`)));

Have you noticed how we created the TextMessage instance? There's a all bunch of message types you should get familiar with.

Creating them is easy! Every message object has its own unique constructor corresponding to its API implementation. Click on each type in the list to find out more. Check out the full API documentation for more advanced uses.

API

Viber Bot

require('viber-bot').Bot

An event emitter, emitting events described here.

New ViberBot()

ParamTypeDescription
options.loggerobjectWinston logger
options.authTokenstringViber Auth Token
options.namestringYour BOT Name
options.avatarstringAvatar URL. No more than 100kb.
options.registerToEventsarrayexample: ["message", "delivered"]

bot.on(handler)

require('viber-bot').Events

ParamType
handlerEventHandlerCallback
messageMessage Object
responseResponse Object
errError Object

Subscribe to events:

  • MESSAGE_RECEIVED (Callback: function (message, response) {})
  • MESSAGE_SENT (Callback: function (message, userProfile) {})
  • SUBSCRIBED (Callback: function (response) {})
  • UNSUBSCRIBED (Callback: function (response) {})
  • CONVERSATION_STARTED (Callback: function (userProfile, isSubscribed, context, onFinish) {})
  • ERROR (Callback: function (err) {})

Example

bot.on(BotEvents.MESSAGE_RECEIVED,(message,response)=> ... );bot.on(BotEvents.MESSAGE_SENT,(message,userProfile)=> ... );bot.on(BotEvents.CONVERSATION_STARTED,(userProfile,isSubscribed,context,onFinish)=> ... );bot.on(BotEvents.ERROR,err=> ... );bot.on(BotEvents.UNSUBSCRIBED,response=> ... );bot.on(BotEvents.SUBSCRIBED,response=>response.send(`Thanks for subscribing, ${response.userProfile.name}`));

bot.getBotProfile()

Returns a promise.JSONwith the following JSON.

bot.getBotProfile().then(response=>console.log(`Public Account Named: ${response.name}`));

bot.getUserDetails(userProfile)

ParamTypeDescription
userProfileUserProfileUserProfile object

The getUserDetails function will fetch the details of a specific Viber user based on his unique user ID. The user ID can be obtained from the callbacks sent to the account regarding user's actions. This request can be sent twice during a 12 hours period for each user ID.

Returns a promise.JSON.

bot.onSubscribe(response=>bot.getUserDetails(response.userProfile).then(userDetails=>console.log(userDetails)));

bot.getOnlineStatus(viberUserIds)

ParamTypeDescription
viberUserIdsarray of stringsCollection of Viber user ids

Returns a promise.JSON.

bot.getOnlineStatus(["a1, "a2"]).then(onlineStatus=>console.log(onlineStatus));

bot.setWebhook(url)

ParamTypeDescription
urlstringTrusted SSL Certificate

Returns a promise.JSON.

bot.setWebhook("https://my.bot/incoming").then(()=>yourBot.doSomething()).catch(err=>console.log(err));

bot.sendMessage(userProfile, messages, [optionalTrackingData])

ParamTypeDescription
userProfileUserProfileUserProfile object
messagesobject or arrayCan be Message object or array of Message objects
[optionalTrackingData]JSONOptional. JSON Object. Returned on every message sent by the client

Note: When passing array of messages to sendMessage, messages will be sent by explicit order (the order which they were given to the sendMessage method). The library will also cancel all custom keyboards except the last one, sending only the last message keyboard.

Returns a promise.ARRAY array of message tokens.

// Single messageconstTextMessage=require('viber-bot').Message.Text;bot.sendMessage(userProfile,newTextMessage("Thanks for shopping with us"));// Multiple messagesconstUrlMessage=require('viber-bot').Message.Url;bot.sendMessage(userProfile,[newTextMessage("Here's the product you've requested:"),newUrlMessage("http://my.ecommerce.site/product1"),newTextMessage("Shipping time: 1-3 business days")]);

bot.postToPublicChat(userProfile, messages)

The Viber post API allows the Public Account owner to post a message in the Public Account’s public chat.

ParamTypeDescription
userProfileUserProfileUserProfile object
messagesobject or arrayCan be Message object or array of Message objects

Note: When passing array of messages to postToPublicChat, messages will be sent by explicit order (the order which they were given to the postToPublicChat method).

Note: This method does not support keyboard attachment.

Returns a promise.ARRAY array of message tokens.

// Single messageconstTextMessage=require('viber-bot').Message.Text;bot.postToPublicChat(userProfile,newTextMessage("Thanks for shopping with us"));// Multiple messagesconstUrlMessage=require('viber-bot').Message.Url;bot.postToPublicChat(userProfile,[newTextMessage("Here's the product you've requested:"),newUrlMessage("http://my.ecommerce.site/product1"),newTextMessage("Shipping time: 1-3 business days")]);

bot.middleware()

Returns a middleware implementation to use with http/https.

consthttps=require('https');https.createServer({key: ...,cert: ...,ca: ...
},bot.middleware()).listen(8080);

bot.onTextMessage(regex, handler)

ParamType
regexregular expression
handlerTextMessageHandlerCallback

TextMessageHandlerCallback: function (message, response) {}
bot.onTextMessage(/^hi|hello$/i,(message,response)=>response.send(newTextMessage(`Hi there ${response.userProfile.name}. I am ${bot.name}`)));

bot.onError(handler)

ParamType
handlerErrorHandlerCallback

ErrorHandlerCallback: function (err) {}
bot.onError(err=>logger.error(err));

bot.onConversationStarted(userProfile, isSubscribed, context, onFinish)

| Param | Type | Description | | --- | --- | | userProfile | UserProfile | UserProfile object | | isSubscribed | boolean | Indicates whether a user is already subscribed | | context | String | Any additional parameters added to the deep link used to access the conversation passed as a string | | onFinish | ConversationStartedOnFinishCallback | When called, a Message will be sent to the client |

Conversation started event fires when a user opens a conversation with the Public Account/ bot using the “message” button (found on the account’s info screen) or using a deep link.

This event is not considered a subscribe event and doesn't allow the account to send messages to the user; however, it will allow sending one "welcome message" to the user. See sending a welcome message below for more information.

ConversationStartedOnFinishCallback: function (responseMessage, optionalTrackingData) {}

The ConversationStartedOnFinishCallback accepts null and MessageObject only. Otherwise, an exception is thrown.

bot.onConversationStarted((userProfile,isSubscribed,context,onFinish)=>onFinish(newTextMessage(`Hi, ${userProfile.name}! Nice to meet you.`)));bot.onConversationStarted((userProfile,isSubscribed,context,onFinish)=>onFinish(newTextMessage(`Thanks`),{saidThanks: true}));

bot.onSubscribe(handler)

ParamType
handlerSubscribeResponseHandlerCallback

SubscribeResponseHandlerCallback: function (response) {}
bot.onSubscribe(response=>console.log(`Subscribed: ${response.userProfile.name}`));

bot.onUnsubscribe(handler)

ParamType
handlerUnsubscribeResponseHandlerCallback

UnsubscribeResponseHandlerCallback: function (userId) {}
bot.onUnsubscribe(userId=>console.log(`Unsubscribed: ${userId}`));

Response object

Members:

ParamTypeNotes
userProfileUserProfile---

UserProfile object

Members:

ParamTypeNotes
idstring---
namestring---
avatarstringOptional Avatar URL
countrystringcurrently set in CONVERSATION_STARTED event only
languagestringcurrently set in CONVERSATION_STARTED event only

Message Object

constTextMessage=require('viber-bot').Message.Text;constUrlMessage=require('viber-bot').Message.Url;constContactMessage=require('viber-bot').Message.Contact;constPictureMessage=require('viber-bot').Message.Picture;constVideoMessage=require('viber-bot').Message.Video;constLocationMessage=require('viber-bot').Message.Location;constStickerMessage=require('viber-bot').Message.Sticker;constRichMediaMessage=require('viber-bot').Message.RichMedia;constKeyboardMessage=require('viber-bot').Message.Keyboard;

Common Members for Message interface:

ParamTypeDescription
timestampstringEpoch time
tokenstringSequential message token
trackingDataJSONJSON Tracking Data from Viber Client

Common Constructor Arguments Message interface:

ParamTypeDescription
optionalKeyboardJSONWriting Custom Keyboards
optionalTrackingDataJSONData to be saved on Viber Client device, and sent back each time message is received

TextMessage object

MemberType
textstring
constmessage=newTextMessage(text,[optionalKeyboard],[optionalTrackingData]);console.log(message.text);

UrlMessage object

MemberType
urlstring
constmessage=newUrlMessage(url,[optionalKeyboard],[optionalTrackingData]);console.log(message.url);

ContactMessage object

MemberType
contactNamestring
contactPhoneNumberstring
constmessage=newContactMessage(contactName,contactPhoneNumber,[optionalAvatar],[optionalKeyboard],[optionalTrackingData]);console.log(`${message.contactName}, ${message.contactPhoneNumber}`);

PictureMessage object

MemberType
urlstring
textstring
thumbnailstring
constmessage=newPictureMessage(url,[optionalText],[optionalThumbnail],[optionalKeyboard],[optionalTrackingData]);console.log(`${message.url}, ${message.text}, ${message.thumbnail}`);

VideoMessage object

MemberType
urlstring
sizeint
thumbnailstring
durationint
constmessage=newVideoMessage(url,size,[optionalText],[optionalThumbnail],[optionalDuration],[optionalKeyboard],[optionalTrackingData]);console.log(`${message.url}, ${message.size}, ${message.thumbnail}, ${message.duration}`);

LocationMessage object

MemberType
latitudefloat
longitudefloat
constmessage=newLocationMessage(latitude,longitude,[optionalKeyboard],[optionalTrackingData]);console.log(`${message.latitude}, ${message.longitude}`);

StickerMessage object

MemberType
stickerIdint
constmessage=newStickerMessage(stickerId,[optionalKeyboard],[optionalTrackingData]);console.log(message.stickerId);

FileMessage object

MemberType
urlstring
sizeInBytesint
filenamestring
constmessage=newFileMessage(url,sizeInBytes,filename,[optionalKeyboard],[optionalTrackingData]);console.log(`${message.url}, ${message.sizeInBytes}, ${message.filename}`);

RichMediaMessage object

MemberType
richMediaObject
constSAMPLE_RICH_MEDIA={"ButtonsGroupColumns": 6,"ButtonsGroupRows": 2,"BgColor": "#FFFFFF","Buttons": [{"ActionBody": "http://www.website.com/go_here","ActionType": "open-url","BgMediaType": "picture","Image": "http://www.images.com/img.jpg","BgColor": "#000000","TextOpacity": 60,"Rows": 4,"Columns": 6},{"ActionBody": "http://www.website.com/go_here","ActionType": "open-url","BgColor": "#85bb65","Text": "Buy","TextOpacity": 60,"Rows": 1,"Columns": 6}]};constmessage=newRichMedia(SAMPLE_RICH_MEDIA,[optionalKeyboard],[optionalTrackingData]);

KeyboardMessage object

MemberType
keyboardJSON
constSAMPLE_KEYBOARD={"Type": "keyboard","Revision": 1,"Buttons": [{"Columns": 3,"Rows": 2,"BgColor": "#e6f5ff","BgMedia": "http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg","BgMediaType": "picture","BgLoop": true,"ActionType": "reply","ActionBody": "Yes"}]};constmessage=newKeyboardMessage(SAMPLE_KEYBOARD,[optionalTrackingData]);

Sample project

We've created the Is It Up sample project to help you get started.

Community

Join the conversation on Gitter.

About

The Viber bot NodeJS library provides just what you need to develop intelligent bots that interact naturally with your Viber users.

Resources

Stars

110 stars

Watchers

25 watching

Forks

Releases

Packages

Used by

Contributors

Languages