Chatbots are prevalent everywhere. Some conversations are confidential and hence chatbots have to verify authenticity of users. Sending an OTP via SMS is a popular way to identify a user.
In this code pattern we will provide steps to build a chatbot application that authenticates users through an SMS one time passcode (OTP). For example, a customer holding an insurance policy can use chatbot to get more information about his/her insurance policy. We will demonstrate the usage of Watson Assistant, Cloud Functions and Custom APIs to build this application.
When you have completed this code pattern, you will understand how to:
- Build conversational interfaces into any application, device, or channel.
- Run your application code without servers.
- Build APIs to authenticate users on your chatbot.
- Make external API calls through Watson Assistant.
- User registers for a policy on the portal.
- User data is stored in the database and policy details are sent to user’s phone number in an SMS through Twilio Messaging API.
- User interacts with chatbot and asks for confidential info related to the policy. The user is prompted to enter OTP by Watson Assistant.
- The query is sent to Watson Assistant which in turn invokes Cloud function to make an API call to the user defined backend API for retrieving info.
- The user’s phone number is searched in the database and OTP generated by backend API is sent to user through Twilio.
- User enters the OTP, in the chat application to authenticate himself/herself.
- Watson Assistant validates OTP by interacting with backend API.
- If the OTP is valid, the user requested confidential info is fetched from the database.
- Cloud function returns the confidential info to Watson Assistant.
- Watson Assistant displays the user requested confidential info.
- User can see the confidential info in the Web UI.
- IBM Cloud Account: Create an IBM Cloud account.
- IBM Cloud CLI: Download and Install IBM Cloud CLI tool.
- OpenShift ROKS Cluster: Create an OpenShift Cluster.
- OC CLI: Download and Install OpenShift CLI tool.
- Git Client: Download Git Client CLI.
- Clone the repo
- Setup Twilio messaging service
- 2.1. Create Twilio service
- 2.2. Create Twilio Trial Number
- 2.3. Verified Caller IDs
- Deploy Custom APIs
- Create a Cloud Function Action
- Create Watson Assistant Services
- Import Watson Assistant workspace
- Configure Watson Assistant with Cloud Function URL
- Deploy and Run the Web Application
Clone the authenticate-users-on-your-chatbot-with-sms-otp
repo locally. In a terminal, run:
git clone https://github.com/IBM/authenticate-users-on-your-chatbot-with-sms-otp.git
Twilio is a SaaS offering that provides APIs to make and receive calls or text messages. We will be using Twilio to send SMS to user programmatically from backend. Lets start by creating a free Twilio service.
- Create a free Twilio service here: https://www.twilio.com/try-twilio.
NOTE: - Once you create a Twilio service, you will have to verify your email id as well as your phone number.
-
Once email id is verified you will be prompted to enter your phone number, submit that and you will get an OTP on your registered number, enter that back to verify.
-
On successful verification you should see a welcome greeting message, additionally you will see some questions, select as described below.
Questions Answers Which Twilio product are you here to use? SMS What do you plan to build with Twilio? Alerts & Notifications How do you want to build with Twilio? With code What is your preferred coding language? Python Would you like Twilio to host your code? No, I want to use my own hosting service
-
You will need a Twilio
Trial Number
to send messages(OTP). Click on Get a Trial Number as shown. -
Click on Choose this Number to continue.
-
A confirmation will be displayed once the number is generated, click on Done.
- Twilio trial number doesn't send messages to your phone number if your phone number is not added to the
Verified Caller IDs
list. This is a limitation of a free trial number. Visit https://www.twilio.com/console/phone-numbers/verified and add your phone number to the verified caller ID list before you continue.
-
To establish connection between the APIs and Twilio we need to get the
trial_number
,account_sid
andauth_token
from Twilio. -
Visit https://www.twilio.com/console and expand the Project Info tab. You will see the
TRIAL NUMBER
,ACCOUNT SID
andAUTH TOKEN
, copy it in some notepad as it will be used in Step 3. -
At this point, you should have the
TRIAL NUMBER
,ACCOUNT SID
andAUTH TOKEN
from Twilio service. -
Now lets deploy the custom APIs and configure twilio credentials.
In this code pattern, custom APIs are developed to perform various tasks such as:
- Store users data in a Database
- Search users phone number and send out an OTP
- Validate OTP and Authenticate users
- Query users data
Custom APIs are developed in Python Flask and you can deploy it in OpenShift or IBM Cloud Foundry.
Steps to Build and Deploy on OpenShift
Note: If you want to deploy the Custom APIs without any modifications, you can skip the Build steps and directly follow the Deploy steps. If you want to make some modifications in the APIs and then deploy it then follow the Build step.
Note: Make sure you have docker cli installed and logged in to DockerHub
- In cloned repo, navigate to
custom-apis-for-authentication/
directory and build the docker image. In terminal run:
$ docker build -t <your-docker-username>/otp-apis:v1 .
Replace
<your-docker-username>
with your docker hub username
- Once the docker image is built, deploy the docker image to Dockerhub. In terminal run:
$ docker push <your-docker-username>/otp-apis:v1
-
At this point you have built the container image and successfully pushed to to a container repository dockerhub.
-
Copy the image tag
<your-docker-username>/otp-apis:v1
and replace it on line no18
indeployment-scripts/api-deploy.yaml
spec:
containers:
- name: otp-apis
image: < your-docker-username >/otp-apis:v1
ports:
- containerPort: 8080
- Login to your OpenShift cluster, In terminal run:
$ oc login -u <username> -p <password>
-
Alternatively you can also login with an auth token. Follow the Step here to login through an auth token.
-
Once you have logged into OpenShift from your terminal, you can run the
oc apply
command to deploy the Application on OpenShift. In cloned repo, navigate todeployment-scripts/
directory and in terminal run:
$ cd deployment-scripts/
$ oc apply -f api-deploy.yaml
deployment.apps/otp-apis created
service/otp-apis-service created
route.route.openshift.io/otp-apis-url created
- A deployment, service and a route will be created. To access the App, In terminal run:
$ oc get route -n default
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
otp-apis-url otp-apis-url-default.xxx.us-south.containers.appdomain.cloud / otp-apis-service 8080 None
- You will see the
PATH
for with service nameotp-apis-url
. - Make a note of this url, as
APIEndPoint
to be used in step 4.
Example: http://otp-apis-url-default.xxx.us-south.containers.appdomain.cloud
- At this point, you will have successfully deployed the Custom APIs on OpenShift. Now lets access it and see how it looks like.
Steps to Build and Deploy on IBM Public Cloud Foundry
-
Before you proceed, make sure you have installed IBM Cloud CLI in your deployment machine.
-
From the cloned repo, goto custom-apis-for-authentication directory in terminal, and run the following commands to deploy the Application to IBM Cloud Foundry.
$ cd custom-apis-for-authentication/
-
Log in to your IBM Cloud account, and select an API endpoint.
$ ibmcloud login
NOTE: If you have a federated user ID, instead use the following command to log in with your single sign-on ID.
$ ibmcloud login --sso
-
Target a Cloud Foundry org and space:
$ ibmcloud target --cf
-
From within the custom-apis-for-authentication directory push your app to IBM Cloud.
$ ibmcloud cf push otp-api
-
The manifest.yml file will be used here to deploy the application to IBM Cloud Foundry.
-
On Successful deployment of the application you will see something similar on your terminal as shown.
Invoking 'cf push'...
Shown below is a sample output
Pushing from manifest to org abc@in.ibm.com / space dev as abc@in.ibm.com...
...
Waiting for app to start...
name: otp-api
requested state: started
routes: otp-api.xx-xx.mybluemix.net
last uploaded: Sat 16 May 18:05:16 IST 2020
stack: cflinuxfs3
buildpacks: python
type: web
instances: 1/1
memory usage: 512M
start command: python app.py
state since cpu memory disk details
#0 running 2020-05-16T12:36:15Z 12.6% 116.5M of 512M 796.2M of 1
-
Once the app is deployed, from the output of the above command, you can visit the
routes
to launch the application. -
Make a note of this url, as
APIENDPOINT
to be used in step 4.
Example: http://otp-api.xx-xx.mybluemix.net if deployed on IBM Cloud Foundry, http://otp-apis-url-default.xxx.us-south.containers.appdomain.cloud if deployed on OpenShift
Note: Add
http://
to the OpenShift url if not present.
- At this point, you will have successfully deployed the Custom APIs on IBM Cloud. Now lets access it and see how it looks like.
Once you have deployed the Custom APIs, continue with the documentation:
-
Visit the
URL
in your browser to access the framework. -
Click on the Add Twilio Credentials button and enter the
TRIAL NUMBER
,ACCOUNT SID
andAUTH TOKEN
copied in Step 2. and click Submit -
Once the credentials are entered you will see the status as
Configured
as shown. -
At this point you will have successfully deployed and configured the custom APIs.
IBM Cloud Function is a Serverless Architecture where in a user can write a snippet of code and run it as API's without worrying about deploying it. Through webhook we will be using Cloud Function Actions to interact with our external database API and exchange data.
- Login to IBM Cloud, and Create a cloud function action.
- Click "Start Creating " button. Select "Action".
-
Enter a cloud function name and select Python 3.7 for runtime environment and click
create
. -
Copy the code from cloud-function-action/otp-auth.py and replace it in the canvas as shown.
-
This code acts as an intermediater between Watson Assistant and the Custom APIs. Any API calls requested by Watson Assistant will go through this Cloud Function code, and response will be returned back to Watson Assistant.
-
Replace the
APIENDPOINT
in the code with the URL that you copied to your notepad in Step 3.
Example: http://otp-api.xx-xx.mybluemix.net if deployed on IBM Cloud Foundry, http://otp-apis-url-default.xxx.us-south.containers.appdomain.cloud if deployed on OpenShift
NOTE: The Above URL should end with .json if it is not ending with .json please append .json at the end of the URL. NOTE: This URL is Important, please save it as CLOUD_FUNCTION_URL in any notepad since it will be used in subsequent steps.
-
Login to IBM Cloud, and create a Watson Assistant service by selecting the Lite plan and clicking on Create.
-
Inside Watson Assistant Console click Skills icon on the left panel and then click Create skill.
-
Select
Upload Skill
tab. Drag and drop (or click and browse) the filewatson-assistant-skills/skill-OTP-Authentication-New.json
from the project directory and click Upload. -
After this you will see that a new Watson Assistant skill has been created.
-
Click Assistant icon from left panel and click Create Assistant. In below images, we can cut images to remove the blank space from images.
-
Enter a Name and description(optional) for the Assistant and click Create.
-
Select the OTP Authentication New skill that we just uploaded.
-
Now you can see that skill has been added to the assistant. Now navigate back to Assistants page by clicking the back button as shown below.
-
Click the three dots at the side of OTP Auth skill to see the dropdown menu and select Settings.
-
Copy the Assistant ID, Assistant URL and the API key and store them in a file as they will be used in subsequent steps.
Note: From the Assistant URL, copy the url only till the end of hostname part and not the complete path. e.g
https://api.eu-gb.assistant.watson.cloud.ibm.com/
- Go to the Watson Assistant skills and select OTP Authentication New
- Select Options -> Webhooks from the left panel and paste the CLOUD_FUNCTION_URL(ending in .json) copied in Step 4 in the text box.
Build and Deploy on OpenShift
Note: If you want to deploy the Web Application without any modifications, you can skip the Build steps and directly follow the Deploy steps. If you want to make some modifications in the Application and deploy it follow the Build step.
Note: Make sure you have docker cli installed and logged in to DockerHub
- In cloned repo, navigate to
node-web-application/
directory and build the docker image. In terminal run:
$ docker build -t <your-docker-username>/otp-webapp:v1 .
Replace
<your-docker-username>
with your docker hub username
- Once the docker image is built, deploy the docker image to Dockerhub. In terminal run:
$ docker push <your-docker-username>/otp-webapp:v1
-
At this point you have built the container image and successfully pushed to to a container repository dockerhub.
-
Copy the image tag
<your-docker-username>/otp-webapp:v1
and replace it on line no18
indeployment-scripts/webapp-deploy.yaml
spec:
containers:
- name: otp-webapp
image: < your-docker-username >/otp-webapp:v1
ports:
- containerPort: 8080
- Login to your OpenShift cluster, In terminal run:
$ oc login -u <username> -p <password>
-
Alternatively you can also login with an auth token. Follow the Step here to login through an auth token.
-
Once you have logged into OpenShift from your terminal, you can run the
oc apply
command to deploy the Application on OpenShift. In cloned repo, navigate todeployment-scripts/
directory and in terminal run:
$ cd deployment-scripts/
$ oc apply -f webapp-deploy.yaml
deployment.apps/otp-webapp created
service/otp-webapp-service created
route.route.openshift.io/otp-webapp-url created
- A deployment, service and a route will be created. To access the App, In terminal run:
$ oc get route -n default
NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD
otp-apis-url otp-apis-url-default.xxx.us-south.containers.appdomain.cloud / otp-apis-service 8080 None
otp-webapp-url otp-webapp-url-default.xxx.us-south.containers.appdomain.cloud / otp-webapp-service 8080 None
- You will see the
PATH
for with service nameotp-webapp-url
.
Example: http://otp-webapp-url-default.xxx.us-south.containers.appdomain.cloud
- At this point, you will have successfully deployed the Web Application on OpenShift. Now lets access it and see how it looks like.
Build and Deploy Locally
-
Open the repository in your terminal and navigate to
node-web-application
directory. -
In terminal, run the following to build the Application.
$ npm install
- In terminal, run the following command to deploy and start the server.
$ node server.js
Note: The server host can be changed as required in the server.js file, and
PORT
can be set in the.env
file.
- At this point, you will have successfully deployed the Web Application locally. Now lets access it and see how it looks like.
Once you have deployed the Web Application, continue with the documentation:
-
Visit the OpenShift
otp-webapp-url
route orlocalhost:8080
if you have deployed locally. -
As the authentication has not been done yet, you will be redirected to
/auth
. -
Click Add Credentials and Enter Assistant ID, Assistant URL and the API Key that you copied in Step 6 and Custom API URL as copied in Step 3 and press Submit.
-
After successful authentication user will be redirected to the chatbot.
Note: The phone number should be the same as registered on Twilio.
-
After Successful registration you will see a success prompt and you will have received the policy details on your registered mobile number.
-
You can now interact with chatbot and know your confidential information in a secure manner.
In this Code Pattern you learned to create a chatbot using Watson Assistant which securely verifies user identity using SMS OTP authentication and interacts to display confidential information.
If you have any questions or issues you can create a new issue here.
Pull requests are very welcome! Make sure your patches are well tested. Ideally create a topic branch for every separate change you make. For example:
- Fork the repo
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
This code pattern is licensed under the Apache License, Version 2. Separate third-party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 and the Apache License, Version 2.