Viber API Documentation7.3.0

Docs / API / Viber Node.JS Bot API

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.

Important note for bot developers: Viber’s bot platform is open and free for developers to create bots in our ecosystem. Once you’ve created your bot you are welcome to share it with your Viber contacts or promote it outside Viber on your website or social media channels. Please note that Viber is not responsible for promoting your bot.


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 bots (iOS/Android). This account will automatically be set as the account administrator during the account creation process.
  3. Active 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.


This library is released on npm.


Install with npm install viber-bot --save


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 bot and use the authentication token from
  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';

const ViberBot = require('viber-bot').Bot;
const BotEvents = require('viber-bot').Events;

const bot = new ViberBot({
	name: "EchoBot",
	avatar: "" // 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.

// Wasn't that easy? Let's create HTTPS server and set the webhook:
const https = require('https');
const port = process.env.PORT || 8080;

// Viber will push messages sent to this URL. Web server should be internet-facing.
const webhookUrl = process.env.WEBHOOK_URL;

const httpsOptions = {
	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';

const ViberBot = require('viber-bot').Bot;
const winston = require('winston');
const toYAML = require('winston-console-formatter'); // makes the output more friendly

function createLogger() {
	const logger = new winston.Logger({
		level: "debug"
	}); // We recommend DEBUG for development
	logger.add(winston.transports.Console, toYAML.config());
	return logger;

const logger = createLogger();
const bot = new ViberBot({
	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.

const TextMessage = 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(new TextMessage(`Hi there ${}. I am ${}`)));

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.


Viber Bot


An event emitter, emitting events described here.

New ViberBot()

Param Type Description
options.logger object Winston logger
options.authToken string Viber Auth Token string Your BOT Name
options.avatar string Avatar URL. No more than 100kb.
options.registerToEvents array example: [“message”, “delivered”]



Param Type
handler EventHandlerCallback
message Message Object
response Response Object
err Error Object

Subscribe to events:


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, ${}`));


Returns a promise.JSON with the following JSON.

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


Param Type Description
userProfile UserProfile UserProfile 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)));


Param Type Description
viberUserIds array of strings Collection of Viber user ids

Returns a promise.JSON.

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


Param Type Description
url string Trusted SSL Certificate

Returns a promise.JSON.

bot.setWebhook("").then(() => yourBot.doSomething()).catch(err => console.log(err));

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

Param Type Description
userProfile UserProfile UserProfile object
messages object or array Can be Message object or array of Message objects
[optionalTrackingData] JSON Optional. 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 message
const TextMessage = require('viber-bot').Message.Text;
bot.sendMessage(userProfile, new TextMessage("Thanks for shopping with us"));

// Multiple messages
const UrlMessage = require('viber-bot').Message.Url;
bot.sendMessage(userProfile, [
	new TextMessage("Here's the product you've requested:"),
	new UrlMessage(""),
	new TextMessage("Shipping time: 1-3 business days")


Returns a middleware implementation to use with http/https.

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

bot.onTextMessage(regex, handler)

Param Type
regex regular expression
handler TextMessageHandlerCallback

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


Param Type
handler ErrorHandlerCallback

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 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(new TextMessage(`Hi, ${}! Nice to meet you.`)));

bot.onConversationStarted((userProfile, isSubscribed, context, onFinish) =>
	onFinish(new TextMessage(`Thanks`), {
		saidThanks: true

The ConversationStartedOnFinishCallback isn’t compatible with certain keyboard features, and therefore sendMessage is preferable when sending messages with keyboards.


const message = new TextMessage("new text",KEYBOARD_JSON,null,null,null,3);

bot.onConversationStarted((userProfile, isSubscribed, context) =>


Param Type
handler SubscribeResponseHandlerCallback

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


Param Type
handler UnsubscribeResponseHandlerCallback

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

Response object


Param Type Notes
userProfile UserProfile

UserProfile object


Param Type Notes
id string
name string
avatar string Optional Avatar URL
country string currently set in CONVERSATION_STARTED event only
language string currently set in CONVERSATION_STARTED event only

Message Object

const TextMessage = require('viber-bot').Message.Text;
const UrlMessage = require('viber-bot').Message.Url;
const ContactMessage = require('viber-bot').Message.Contact;
const PictureMessage = require('viber-bot').Message.Picture;
const VideoMessage = require('viber-bot').Message.Video;
const LocationMessage = require('viber-bot').Message.Location;
const StickerMessage = require('viber-bot').Message.Sticker;
const RichMediaMessage = require('viber-bot').Message.RichMedia;
const KeyboardMessage = require('viber-bot').Message.Keyboard;

Common Members for Message interface:

Param Type Description
timestamp string Epoch time
token string Sequential message token
trackingData JSON JSON Tracking Data from Viber Client

Common Constructor Arguments Message interface:

Param Type Description
optionalKeyboard JSON Writing Custom Keyboards
optionalTrackingData JSON Data to be saved on Viber Client device, and sent back each time message is received

TextMessage object

Member Type
text string
const message = new TextMessage(text, [optionalKeyboard], [optionalTrackingData]);

Note: to enable features that have an api level requirement in your keyboard, it’s necessary to add the following arguments to the KeyboardMessage constructor: TextMessage(text, [optionalKeyboard], [optionalTrackingData], null, null, [minApiVersion]) [minApiVersion] should be an integer value of the desired minimum api version/level for the message.

UrlMessage object

Member Type
url string
const message = new UrlMessage(url, [optionalKeyboard], [optionalTrackingData]);

ContactMessage object

Member Type
contactName string
contactPhoneNumber string
const message = new ContactMessage(contactName, contactPhoneNumber, [optionalAvatar], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.contactName}, ${message.contactPhoneNumber}`);

PictureMessage object

Member Type
url string
text string
thumbnail string
const message = new PictureMessage(url, [optionalText], [optionalThumbnail], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.text}, ${message.thumbnail}`);

VideoMessage object

Member Type
url string
size int
thumbnail string
duration int
const message = new VideoMessage(url, size, [optionalText], [optionalThumbnail], [optionalDuration], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.size}, ${message.thumbnail}, ${message.duration}`);

LocationMessage object

Member Type
latitude float
longitude float
const message = new LocationMessage(latitude, longitude, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.latitude}, ${message.longitude}`);

StickerMessage object

Member Type
stickerId int
const message = new StickerMessage(stickerId, [optionalKeyboard], [optionalTrackingData]);

FileMessage object

Member Type
url string
sizeInBytes int
filename string
const message = new FileMessage(url, sizeInBytes, filename, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.sizeInBytes}, ${message.filename}`);

RichMediaMessage object

Member Type
richMedia Object
	"ButtonsGroupColumns": 6,
	"ButtonsGroupRows": 2,
	"BgColor": "#FFFFFF",
	"Buttons": [{
		"ActionBody": "",
		"ActionType": "open-url",
		"BgMediaType": "picture",
		"Image": "",
		"BgColor": "#000000",
		"TextOpacity": 60,
		"Rows": 4,
		"Columns": 6
	}, {
		"ActionBody": "",
		"ActionType": "open-url",
		"BgColor": "#85bb65",
		"Text": "Buy",
		"TextOpacity": 60,
		"Rows": 1,
		"Columns": 6

const message = new RichMediaMessage(SAMPLE_RICH_MEDIA, [optionalKeyboard], [optionalTrackingData]);

KeyboardMessage object

Member Type
keyboard JSON
	"Type": "keyboard",
	"Revision": 1,
	"Buttons": [
			"Columns": 3,
			"Rows": 2,
			"BgColor": "#e6f5ff",
			"BgMedia": "",
			"BgMediaType": "picture",
			"BgLoop": true,
			"ActionType": "reply",
			"ActionBody": "Yes"

const message = new KeyboardMessage(SAMPLE_KEYBOARD, [optionalTrackingData]);

Note: to enable features that have an api level requirement in your keyboard, it’s necessary to add the following arguments to the KeyboardMessage constructor: KeyboardMessage(SAMPLE_KEYBOARD, [optionalTrackingData], null, null, [minApiVersion]) [minApiVersion] should be an integer value of the desired minimum api version/level for the message.

Sample project

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


Join the conversation on Gitter.