[PYTHON] How to make a Cisco Webex Teams BOT with Flask

Recently, when developing a system using Cisco Webex Teams, I had the opportunity to create a chatbot for Webex Teams and leave a note for myself.

Also, for the demonstration this time, ngrok will be used to publish the server.

The flow this time is as follows. · Get a Cisco Webex Developers account ・ Acquisition of access token ・ Installation of various Python libraries ・ Preparation of ngrok ·Implementation ・ Operation check

The development environment used this time is as follows. ・ Raspberry Pi3 B + ・ Python3 ・ Ngrok ・ Flask

Get a Cisco Webex Developers account

First, access this site. https://developer.webex.com/

スクリーンショット 2020-01-02 3.57.37.png

Click Sign up displayed in the upper right to proceed with registration.

Obtaining an access token

https://developer.webex.com/docs/api/getting-started Go to the getting-started page and get a token

スクリーンショット 2020-01-02 4.19.06.png

During the demo stage, you will have to retake this token every 12 hours.

スクリーンショット 2020-01-02 4.18.56.png

Click My Webex Teams Apps. スクリーンショット 2020-01-02 4.26.44.png

Select a bot. スクリーンショット 2020-01-02 4.21.14.png

スクリーンショット 2020-01-02 4.21.29.png

After filling in the various forms, click Addbot. スクリーンショット 2020-01-02 4.21.42.png

Installation of various Python libraries

terminal


$ pip3 install requests

terminal


$ pip3 install flask

Preparing ngrok

https://qiita.com/kaba/items/82de7e53d99ad9c74cc0 I referred to this site.

Implementation

This time, as an example, let's create a bot that only returns hello world! When talking to Hi and the bot. Paste the implemented code.

First, substitute the token you obtained earlier into YourToken.

token = 'YourToken'

Define a function to post a message.

def post_message(room_id,txt,token):
    global ms_flag
    if ms_flag == True:
        ms_flag = False
        m = MultipartEncoder({'roomId': room_id,'text': txt})
        r = requests.post('https://api.ciscospark.com/v1/messages', data=m,headers={'Authorization': 'Bearer %s' % token,'Content-Type': m.content_type})
    else:
        time.sleep(5)
        ms_flag = True

At this time, it is handled multiple times depending on the behavior when detecting the message, so once this function is called, it passes for a certain period of time. If anyone knows about this behavior, please teach me.

Here, it is the part that displays mainpage.html when accessing / panel. It's a good idea to write an explanation of how to use it.

@app.route("/panel",methods=['GET'])    
def main_page():
    return render_template("mainpage.html")

Collect message ID, person ID, email and room ID from the received message information

@app.route("/",methods=['POST'])   
def handle_message():
    json = request.json
    
    message_id = json["data"]["id"]
    user_id = json["data"]["personId"]
    email = json["data"]["personEmail"]
    room_id = json["data"]["roomId"]
    bot_id = "yourbotid"

    print(message_id, file = sys.stdout)
    print(user_id, file=sys.stdout)
    print(email, file=sys.stdout)
    print(room_id, file=sys.stdout)

Here, we are looking at whether the user ID that received the message is the bot itself. Also, the post_message defined earlier is called so that when Hi is received, hello world! Is returned.

    if user_id != bot_id:
        global token
        header = {"Authorization": "Bearer %s" % token}
        get_rooms_url = "https://api.ciscospark.com/v1/messages/" + message_id
        api_response = requests.get(get_rooms_url, headers=header, verify=False)
        response_json = api_response.json()
        message = response_json["text"]
        print(message, file= sys.stdout)
        if message == "Hi" or message == "bot Hi":
            post_message(room_id,"hello world!",token)
       
        return "Success"
    else:
        return "Pass"

Also, since the IP address of ngrok changes every time it is started, it reads the IP address.

term_output_json = os.popen('curl http://127.0.0.1:4040/api/tunnels').read() 
tunnel_info = json.loads(term_output_json)
public_url = tunnel_info['tunnels'][0]['public_url']

Error handling.

if api_response.status_code != 200:
    print('Webhook registration Error !')
    exit(0)

The final result is as follows.

main.py


from __future__ import print_function 
import requests
import sys
import json
import os
import time
from flask import *
from requests_toolbelt.multipart.encoder import MultipartEncoder
import functools

token = 'YourToken'
ms_flag = True

app = Flask(__name__)

def post_message(room_id,txt,token):
    global ms_flag
    if ms_flag == True:
        ms_flag = False
        m = MultipartEncoder({'roomId': room_id,'text': txt})
        r = requests.post('https://api.ciscospark.com/v1/messages', data=m,headers={'Authorization': 'Bearer %s' % token,'Content-Type': m.content_type})
    else:
        time.sleep(5)
        ms_flag = True

@app.route("/panel",methods=['GET'])    
def main_page():
    return render_template("mainpage.html")


@app.route("/",methods=['POST'])   
def handle_message():
    json = request.json
    
    message_id = json["data"]["id"]
    user_id    = json["data"]["personId"]
    email      = json["data"]["personEmail"]
    room_id    = json["data"]["roomId"]
    bot_id     = "yourbotid"

    print(message_id, file = sys.stdout)
    print(user_id, file=sys.stdout)
    print(email, file=sys.stdout)
    print(room_id, file=sys.stdout)


    if user_id != bot_id:
        global token
        header = {"Authorization": "Bearer %s" % token}
        get_rooms_url = "https://api.ciscospark.com/v1/messages/" + message_id
        api_response = requests.get(get_rooms_url, headers=header, verify=False)
        response_json = api_response.json()
        message = response_json["text"]
        print(message, file= sys.stdout)
        if message == "Hi" or message == "bot Hi":
            post_message(room_id,"hello world!",token)
       
        return "Success"
    else:
        return "Pass"


term_output_json = os.popen('curl http://127.0.0.1:4040/api/tunnels').read() 
tunnel_info = json.loads(term_output_json)
public_url = tunnel_info['tunnels'][0]['public_url']

#Webhook record
header = {"Authorization": "Bearer %s" % token, "content-type": "application/json"}
requests.packages.urllib3.disable_warnings() #Remove SSL warning
post_message_url = "https://api.ciscospark.com/v1/webhooks"

payload = {
    "resource": "messages",
    "event": "all",
    "targetUrl": public_url,
    "name": "BotDemoWebHook"
}

api_response = requests.post(post_message_url, json=payload, headers=header, verify=False) #webhook record

if api_response.status_code != 200:
    print('Webhook registration Error !')
    exit(0)

if __name__ == '__main__':
    app.run(host='localhost', use_reloader=True, debug=True)

Operation check

terminal


$ ngrok http 5000

terminal


$ python3 main.py

Recommended Posts

How to make a Cisco Webex Teams BOT with Flask
How to make a slack bot
How to make a dictionary with a hierarchical structure.
How to make an artificial intelligence LINE bot with Flask + LINE Messaging API
Python beginners decided to make a LINE bot with Flask (Flask rough commentary)
Make a morphological analysis bot loosely with LINE + Flask
How to make a shooting game with toio (Part 1)
How to deploy a web app made with Flask to Heroku
How to make a Japanese-English translation
How to make a crawler --Advanced
How to make a recursive function
How to make a simple Flappy Bird game with pygame
How to make a deadman's switch
[Blender] How to make a Blender plugin
How to make a crawler --Basic
How to make a command to read the configuration file with pyramid
How to make a surveillance camera (Security Camera) with Opencv and Python
[Introduction] I want to make a Mastodon Bot with Python! 【Beginners】
How to add a package with PyCharm
[Python] How to make a class iterable
Make a rare gacha simulator with Flask
How to make a Backtrader custom indicator
How to make a Pelican site map
Let's make a Twitter Bot with Python!
Tweet in Chama Slack Bot ~ How to make a Slack Bot using AWS Lambda ~
How to make a rock-paper-scissors bot that can be easily moved (commentary)
I tried to make "Sakurai-san" a LINE BOT with API Gateway + Lambda
How to upload with Heroku, Flask, Python, Git (4)
How to make a dialogue system dedicated to beginners
How to read a CSV file with Python 2/3
How to send a message to LINE with curl
A memorandum to make WebDAV only with nginx
Make a Twitter trend bot with heroku + Python
How to draw a 2-axis graph with pyplot
How to develop a cart app with Django
Make a simple pixel art generator with Flask
I want to make a game with Python
Try to make a "cryptanalysis" cipher with Python
How to make a QGIS plugin (package generation)
Steps to create a Twitter bot with python
I read "How to make a hacking lab"
Try to make a dihedral group with Python
How to create a multi-platform app with kivy
Make a LINE WORKS bot with Amazon Lex
How to make Linux compatible with Japanese keyboard
I made a Mattermost bot with Python (+ Flask)
Let's make an A to B conversion web application with Flask! From scratch ...
If you want to make a discord bot with python, let's use a framework
A new form of app that works with GitHub: How to make GitHub Apps
How to process camera images with Teams or Zoom
How to convert / restore a string with [] in python
[Python] How to draw a line graph with Matplotlib
I want to transition with a button in flask
Try to make a command standby tool with python
Explain in detail how to make sounds with python
How to create a submenu with the [Blender] plugin
How to get a logged-in user with Django's forms.py
How to convert a class object to a dictionary with SQLAlchemy
How to upload with Heroku, Flask, Python, Git (Part 3)
Try to make RESTful API with MVC using Flask 1.0.2
Make a function to describe Japanese fonts with OpenCV