Use this library to develop a bot for the Viber platform. The library is available on GitHub as well as a package on npm.
This library is released under the terms of the Apache 2.0 license. See License for more information.
- Node >= 5.0.0
- Winston >= 2.0.0
- Get your Viber Public Account authentication token.
- SSL Certification - You'll need a trusted (ca.pem) certificate, not self-signed. You can find one at Let's Encrypt or buy one.
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().
Creating a basic Viber bot is simple:
- Import
viber-bot
library to your project - Create a Public Account and use the API key from https://developers.viber.com
- Configure your bot as described in the documentation below
- Add the bot as middleware to your server with
bot.middleware()
- Start your web server
- Call setWebhook(url) with your webserver url
Firstly, let's import and configure our bot:
'use strict';
const ViberBot = require('viber-bot').Bot;
const BotEvents = require('viber-bot').Events;
const winston = require('winston');
const toYAML = require('winston-console-formatter');
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, {
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:
const https = require('https');
const port = process.env.PORT || 8080;
// Viber will push messages sent to this URL. Webserver 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));
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 ${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.
- Text Message
- Url Message
- Contact Message
- Picture Message
- Video Message
- Location Message
- Sticker Message
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.
require('viber-bot').Bot
An event emitter, emitting events described here.
- ViberBot
- new ViberBot()
- .getBotProfile() ⇒
promise.JSON
- .getUserDetails(userProfile) ⇒
promise.JSON
- .setWebhook(url) ⇒
promise.JSON
- .sendMessage(userProfile, messages, [optionalTrackingData]) ⇒
promise.ARRAY
- .on(handler)
- .onTextMessage(regex, handler) :
handler
=TextMessageHandlerCallback
- .onError(handler) :
handler
=ErrorHandlerCallback
- .onConversationStarted(userProfile, onFinish) :
onFinish
=ConversationStartedOnFinishCallback
- .onSubscribe(handler) :
handler
=SubscribeResponseHandlerCallback
- .onUnsubscribe(handler) :
handler
=UnsubscribeResponseHandlerCallback
- .middleware()
Param | Type | Description |
---|---|---|
logger | object |
Winston logger |
options.authToken | string |
Viber Auth Token |
options.name | string |
Your BOT Name |
options.avatar | string |
Avatar URL. No more than 100kb. |
options.registerToEvents | array |
example: ["message", "delivered"] |
require('viber-bot').Events
Param | Type |
---|---|
handler | EventHandlerCallback |
message | Message Object |
response | Response Object |
err | Error 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, 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, onFinish) => ... );
bot.on(BotEvents.ERROR, err => ... );
bot.on(BotEvents.UNSUBSCRIBED, response => ... );
bot.on(BotEvents.SUBSCRIBED, response =>
response.send(`Thanks for subscribing, ${response.userProfile.name}`));
Returns a promise.JSON
(With the following JSON.
bot.getBotProfile().then(response => console.log(`Public Account Named: ${response.name}`));
Param | Type | Description |
---|---|---|
userProfile | UserProfile |
UserProfile object |
Returns a promise.JSON
.
bot.onSubscribe(response => bot.getUserDetails(response.userProfile)
.then(userDetails => console.log(userDetails)));
Param | Type | Description |
---|---|---|
url | string |
Trusted SSL Certificate |
Returns a promise.JSON
.
bot.setWebhook("https://my.bot/incoming").then(() => yourBot.doSomething()).catch(err => console.log(err));
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("http://my.ecommerce.site/product1"),
new TextMessage("Shipping time: 1-3 business days")
]);
Returns a middleware implementation to use with http/https
.
const https = require('https');
https.createServer({ key: ... , cert: ... , ca: ... }, bot.middleware()).listen(8080);
Param | Type |
---|---|
regex | regular expression |
handler | TextMessageHandlerCallback |
bot.onTextMessage(/^hi|hello$/i, (message, response) =>
response.send(new TextMessage(`Hi there ${response.userProfile.name}. I am ${bot.name}`)));
Param | Type |
---|---|
handler | ErrorHandlerCallback |
bot.onError(err => logger.error(err));
Param | Type |
---|---|
userProfile | UserProfile |
onFinish | ConversationStartedOnFinishCallback |
Note: onConversationStarted
event happens once when A Viber client opens the conversation with your bot for the first time. Callback accepts null
and MessageObject
only. Otherwise, an exception is thrown.
bot.onConversationStarted((userProfile, onFinish) =>
onFinish(new TextMessage(`Hi, ${userProfile.name}! Nice to meet you.`)));
bot.onConversationStarted((userProfile, onFinish) =>
onFinish(new TextMessage(`Thanks`), { saidThanks: true }));
Param | Type |
---|---|
handler | SubscribeResponseHandlerCallback |
bot.onSubscribe(response => console.log(`Subscribed: ${response.userProfile.name}`));
Param | Type |
---|---|
handler | UnsubscribeResponseHandlerCallback |
bot.onUnsubscribe(userId => console.log(`Unsubscribed: ${userId}`));
Members:
Param | Type | Notes |
---|---|---|
userProfile | UserProfile |
--- |
- Response
- .send(messages, [optionalTrackingData]) ⇒
promise.JSON
- .send(messages, [optionalTrackingData]) ⇒
Members:
Param | Type | Notes |
---|---|---|
id | string |
--- |
name | string |
--- |
avatar | string |
Avatar URL |
country | string |
currently set in CONVERSATION_STARTED event only |
language | string |
currently set in CONVERSATION_STARTED event only |
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;
Common Members for Message
interface:
Param | Type | Description |
---|---|---|
timestamp | long |
Epoch time |
token | long |
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 recived |
Member | Type |
---|---|
text | string |
const message = new TextMessage(text, [optionalKeyboard], [optionalTrackingData]);
console.log(message.text);
Member | Type |
---|---|
url | string |
const message = new UrlMessage(url, [optionalKeyboard], [optionalTrackingData]);
console.log(message.url);
Member | Type |
---|---|
contactName | string |
contactPhoneNumber | string |
const message = new ContactMessage(contactName, contactPhoneNumber, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.contactName}, ${message.contactPhoneNumber}`);
Member | Type |
---|---|
url | string |
text | string |
thumbnail | string |
const message = new ContactMessage(url, [optionalText], [optionalThumbnail], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.text}, ${message.thumbnail}`);
Member | Type |
---|---|
url | string |
size | int |
thumbnail | string |
duration | int |
const message = new VideoMessage(url, size, [optionalThumbnail], [optionalDuration], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.size}, ${message.thumbnail}, ${message.duration}`);
Member | Type |
---|---|
latitude | float |
longitude | float |
const message = new LocationMessage(latitude, longitude, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.latitude}, ${message.longitude}`);
Member | Type |
---|---|
stickerId | int |
const message = new StickerMessage(stickerId, [optionalKeyboard], [optionalTrackingData]);
console.log(message.stickerId);