Good News! We’ve launched an all new Chat Resource Center.
We recommend checking out our new Chat Resource Center, which includes overviews, tutorials, and design patterns for building and deploying mobile and web chat.
Gupshup is an advanced bot and messaging platform. It enables developers to quickly and easily build, test, deploy and manage chat bots across all messaging channels.
In this article, we dive into a simple example of how to build a chatbot and enable bot integration in a web app with the minimal 22-line Gupshup BLOCK and 85 lines of HTML and JavaScript. Chatbot integration can be useful in a variety situations, such as connected car/home, customer service, new user registration, image/video media content uploads, e-commerce, or any application where you want the system to be able to respond to user requests.
So, what exactly is this “chatbot integration” we speak of? In this case, Chatbot Integration refers to creating a custom application that can understand and respond to user requests. Bot integration has a number of issues to consider, including differences in integration across services, creating a pleasant conversational user experience, dealing with outages, graceful degradation and error handling, and management and versioning of complex conversation capabilities.
As we prepare to explore our sample Angular2 web application with bot integration features, let’s check out the underlying Gupshup Bot Integration API.
Bot services are quite challenging to build and operate on your own; they require substantial effort and engineering resources to create friendly user interfaces, maintain integration points, and operate asynchronous services at scale. In the meantime, Gupshup APIs make it easy to enable your applications with custom bot behaviors.
Looking closer at the APIs, simple bot integration is just the beginning. There are a lot of API methods available for integration across a variety of communication services. It really is a powerful tool for integrating actions across the entire mobile landscape. In this article though, we’ll keep it simple and implement a basic bot integration that gets the current time on the server.
Since you’re reading this at PubNub, we’ll presume you have a real-time application use case in mind, such as customer service, ride-hailing, messaging, IoT or other. In the sections below, we’ll dive into the bot integration use case, saving other web service use cases for the future.
You’ll first need your PubNub publish/subscribe keys. If you haven’t already, sign up for PubNub. Once you’ve done so, go to the PubNub Admin Portal to get your unique keys. The publish and subscribe keys look like UUIDs and start with “pub-c-” and “sub-c-” prefixes respectively. Keep those handy – you’ll need to plug them in when initializing the PubNub object in your HTML5 app below.
PubNub plays together really well with JavaScript because the PubNub JavaScript SDK is extremely robust and has been battle-tested over the years across a huge number of mobile and backend installations. The SDK is currently on its 4th major release, which features a number of improvements such as isomorphic JavaScript, new network components, unified message/presence/status notifiers, and much more. NOTE: In this article, we use the PubNub Angular2 SDK, so our UI code can use the PubNub JavaScript v4 API syntax!
The PubNub JavaScript SDK is distributed via Bower or the PubNub CDN (for Web) and NPM (for Node), so it’s easy to integrate with your application using the native mechanism for your platform. In our case, it’s as easy as including the CDN link from a script
tag.
That note about API versions bears repeating: the user interfaces in this series of articles use the v4 API (since they use the new Angular2 API, which runs on v4). In the meantime, please stay alert when jumping between different versions of JS code!
The next thing you’ll need to get started with bot services is a Gupshup account to take advantage of the Bot API.
HttpEndpointHandler
function to respond to HTTPS requests from the BLOCK.All in all, not too shabby!
With PubNub BLOCKS, it’s really easy to create code to run in the network. Here’s how to make it happen:
That’s all it takes to create your serverless code running in the cloud!
You’ll want to grab the 24 lines of BLOCK JavaScript and save them to a file, say, pubnub_gupshup_block.js
. It’s available as a Gist on GitHub for your convenience.
First up, we declare our dependency on xhr (for HTTP requests) and create a function to handle incoming messages.
export default (request) => { const xhr = require('xhr');
Next, we set up variables for accessing the service (the bot name, inbound message text and webhook url).
const botname = 'YOUR_BOT_NAME'; const message = JSON.stringify(request.message.text); const url = "https://www.gupshup.io/developer/bot/" + botname + "/public";
Next, we set up the HTTP params for the bot API request. We use a POST request to submit the data. We use the JSON content of the message as the POST form body.
const http_options = { "method": "POST", "body": "message=" + message };
Finally, we call the webhook endpoint with the given data, decorate the message with a bot_reply
value containing the text response data, and catch any errors and log to the BLOCKS console. Pretty easy!
return xhr.fetch(url, http_options).then((response) => { request.message.bot_reply = response.body; return request; }).catch((reason) => { console.log(reason); return request; }); };
All in all, it doesn’t take a lot of code to add bot integration to our application. We like that!
OK, let’s move on to the UI!
You’ll want to grab these 85 lines of HTML & JavaScript and save them to a file, say, pubnub_gupshup_ui.html
.
The first thing you should do after saving the code is to replace two values in the JavaScript:
If you don’t, the UI will not be able to communicate with anything and probably clutter your console log with entirely too many errors.
For your convenience, this code is also available as a Gist on GitHub, and a Codepen as well. Enjoy!
First up, we have the JavaScript code & CSS dependencies of our application.
<!DOCTYPE html> <html> <head> <title>Angular 2</title> <script src="https://unpkg.com/core-js@2.4.1/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.7.2/dist/zone.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.9/Reflect.js"></script> <script src="https://unpkg.com/rxjs@5.0.1/bundles/Rx.js"></script> <script src="https://unpkg.com/@angular/core/bundles/core.umd.js"></script> <script src="https://unpkg.com/@angular/common/bundles/common.umd.js"></script> <script src="https://unpkg.com/@angular/compiler/bundles/compiler.umd.js"></script> <script src="https://unpkg.com/@angular/platform-browser/bundles/platform-browser.umd.js"></script> <script src="https://unpkg.com/@angular/forms/bundles/forms.umd.js"></script> <script src="https://unpkg.com/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js"></script> <script src="https://unpkg.com/pubnub@4.3.3/dist/web/pubnub.js"></script> <script src="https://unpkg.com/pubnub-angular2@1.0.0-beta.8/dist/pubnub-angular2.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" /> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" /> </head>
For folks who have done front-end implementation with Angular2 before, these should be the usual suspects:
In addition, we bring in the CSS features:
Overall, we were pretty pleased that we could build a nifty UI with so few dependencies. And with that… on to the UI!
Here’s what we intend the UI to look like:
The UI is pretty straightforward – everything is inside a main-component
tag that is managed by a single component that we’ll set up in the Angular2 code.
<body> <main-component> Loading... </main-component>
Let’s skip forward and show that Angular2 component template. The h3
heading should be pretty self-explanatory. We provide a simple button to trigger the user command to send to the PubNub channel via the publish()
action.
<div class="container"> <pre> NOTE: make sure to update the PubNub keys below with your keys, and ensure that the BLOCK settings are configured properly! </pre> <h3>MyApp Bot Integration</h3> <hr/> <button class="btn btn-primary" (click)="publish()">Get Time from Bot!</button> <br/> <br/> <ol> <li *ngFor="let item of messages.slice()">command="{{item.message.text}}", response="{{item.message.bot_reply}}"</li> </ol> </div>
The component UI consists of a simple list of messages. We iterate over the messages in the controller scope using a trusty ngFor
. Each message includes the original command as well as the bot webhook response.
And that’s it – a functioning real-time UI in just a handful of code (thanks, Angular2)!
Right on! Now we’re ready to dive into the Angular2 code. It’s not a ton of JavaScript, so this should hopefully be pretty straightforward.
The first lines we encounter set up our application (with a necessary dependency on the PubNub AngularJS service) and a single component (which we dub main-component
).
<script> var app = window.app = {}; app.main_component = ng.core.Component({ selector: 'main-component', template: `...see previous...`
The component has a constructor that takes care of initializing the PubNub service, and configuring the channel name. NOTE: make sure this matches the channel specified by your BLOCK configuration and the BLOCK itself!
}).Class({ constructor: [PubNubAngular, function(pubnubService){ var self = this; self.pubnubService = pubnubService; self.channelName = 'gupshup-channel'; pubnubService.init({ publishKey: 'YOUR_PUB_KEY', subscribeKey: 'YOUR_SUB_KEY', ssl:true });
We subscribe to the relevant channel and create a dynamic attribute for the messages collection.
pubnubService.subscribe({channels: [self.channelName], triggerEvents: true}); self.messages = pubnubService.getMessage(this.channelName,function(msg){ // no handler necessary, dynamic collection of msg objects });
We also create a publish()
event handler that performs the action of publishing the message containing the command to the PubNub channel.
}], publish: function(){ this.pubnubService.publish({channel: this.channelName,message:{text:"get time"}}); } });
Now that we have a new component, we can create a main module for the Angular2 app that uses it. This is pretty standard boilerplate that configures dependencies on the Browser and Forms modules and the PubNubAngular service.
app.main_module = ng.core.NgModule({ imports: [ng.platformBrowser.BrowserModule, ng.forms.FormsModule], declarations: [app.main_component], providers: [PubNubAngular], bootstrap: [app.main_component] }).Class({ constructor: function(){} });
Finally, we bind the application bootstrap initialization to the browser DOM content loaded event.
document.addEventListener('DOMContentLoaded', function(){ ng.platformBrowserDynamic.platformBrowserDynamic().bootstrapModule(app.main_module); });
We mustn’t forget close out the HTML tags accordingly.
}); </script> </body> </html>
Not too shabby for about 85 lines of HTML & JavaScript!
There are a couple other endpoints worth mentioning in the Gupshup API.
You can find detailed API documentation here.
All in all, we found it pretty easy to get started with bot integration using the API, and we look forward to using more of the deeper integration features!
Thank you so much for joining us in the Bot Integration article of our BLOCKS and web services series! Hopefully it’s been a useful experience learning about bot-enabled technologies. In future articles, we’ll dive deeper into additional web service APIs and use cases for other nifty services in real time web applications.
Stay tuned, and please reach out anytime if you feel especially inspired or need any help!
There are common underlying technologies for a dating app, and in this post, we’ll talk about the major technologies and designs...
Michael Carroll
How to use geohashing, JavaScript, Google Maps API, and BART API to build a real-time public transit schedule app.
Michael Carroll
How to track and stream real-time vehicle location on a live-updating map using EON, JavaScript, and the Mapbox API.
Michael Carroll