|
1 | | -#!/usr/bin/python |
2 | | - |
3 | | -# This is a simple bot script. You must create a Spark webhook that points to the server where this script runs |
4 | | -# ngrok can be used to tunnel traffic back to this server if you don't wish to expose your test machine publicly to the Internet |
5 | | -# By default this server will be reachable at port 8080 - append a different port when launching the script if desired |
6 | | -# Additional Spark webhook details can be found here - https://developer.ciscospark.com/webhooks-explained.html |
7 | | -# |
8 | | -# A bot must be created and pointed to this server in the My Apps section of https://developer.ciscospark.com |
9 | | -# The bot's Access Token should be placed in a directory on the system running this script and the file_name should be updated below |
10 | | -# |
11 | | -# Sample Webhook: |
12 | | -# { |
13 | | -# "id": "Y2lzY29..........mE4U1XXW3323", |
14 | | -# "name": "Example Webhook", |
15 | | -# "targetUrl": "http://<yourserverurl>.com:56811/sparkwebhook", |
16 | | -# "resource": "messages", |
17 | | -# "event": "created", |
18 | | -# "secret": "supersecret", |
19 | | -# "created": "2016-09-20T18:29:06.920Z" |
20 | | -# } |
21 | | -# |
| 1 | +#!/usr/bin/env python2 |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +"""A simple bot script. |
| 4 | +
|
| 5 | +This sample script leverages web.py (see http://webpy.org/). By default the |
| 6 | +web server will be reachable at port 8080 - append a different port when |
| 7 | +launching the script if desired. ngrok can be used to tunnel traffic back to |
| 8 | +your server if you don't wish to expose your machine publicly to the Internet. |
| 9 | +
|
| 10 | +You must create a Spark webhook that points to the URL where this script is |
| 11 | +hosted. You can do this via the CiscoSparkAPI.webhooks.create() method. |
| 12 | +
|
| 13 | +Additional Spark webhook details can be found here: |
| 14 | +https://developer.ciscospark.com/webhooks-explained.html |
| 15 | +
|
| 16 | +A bot must be created and pointed to this server in the My Apps section of |
| 17 | +https://developer.ciscospark.com. The bot's Access Token should be added as a |
| 18 | +'SPARK_ACCESS_TOKEN' environment variable on the web server hosting this |
| 19 | +script. |
| 20 | +
|
| 21 | +""" |
| 22 | + |
| 23 | + |
| 24 | +from __future__ import print_function |
| 25 | +from builtins import object |
22 | 26 |
|
23 | | -import web |
24 | 27 | import json |
| 28 | + |
| 29 | +import web |
25 | 30 | import requests |
26 | | -from ciscosparkapi import CiscoSparkAPI |
27 | 31 |
|
28 | | -# |
29 | | -# CHANGE this to your bot Access Token file |
30 | | -# |
31 | | -file_name="/home/brad/ciscosparkapiexamples/botat.txt" |
| 32 | +from ciscosparkapi import CiscoSparkAPI, Webhook |
32 | 33 |
|
33 | | -#this function gets a cat fact from appspot.com and returns it as a string |
34 | | -#functions for Soundhound, Google, IBM Watson, or other APIs can be added to build desired functionality into this bot |
35 | | -def get_catfact(): |
36 | | - URL = 'http://catfacts-api.appspot.com/api/facts?number=1' |
37 | | - resp = requests.get(URL, verify=False) |
38 | | - resp_dict = json.loads(resp.text) |
39 | | - return resp_dict["facts"][0] |
40 | | - |
41 | | - |
42 | | -fat=open (file_name,"r+") #open the file with the token |
43 | | - |
44 | | -access_token=fat.readline().rstrip() #strip whitespace, newline, etc. |
45 | | - |
46 | | -fat.close |
47 | | - |
48 | | - |
49 | | - |
50 | | -urls = ('/sparkwebhook', 'webhook') #webhook should point to http://<serverip>:8080/sparkwebhook |
51 | | - |
52 | | -app = web.application(urls, globals()) #create a web application instance |
53 | | - |
54 | | -api = CiscoSparkAPI(access_token) #invoke the API |
55 | | - |
56 | | -# This section defines what to do when a webhook is received from Spark |
57 | | -class webhook: |
58 | | - def POST(self): #webhook are received via HTTP POST |
59 | | - data = web.data() #grabs the data sent from Spark |
60 | | - |
61 | | - print |
62 | | - print 'DATA RECEIVED:' |
63 | | - print data |
64 | | - print |
65 | | - |
66 | | - json_data = json.loads(data) #loads the data as JSON format |
67 | | - room_id = json_data["data"]["roomId"] #grabs the roomId |
68 | | - message_id = json_data["data"]["id"] #grabs the messageId |
69 | | - |
70 | | - print room_id |
71 | | - print message_id |
72 | | - |
73 | | - message=api.messages.get(message_id) #grabs the actual message detail |
74 | | - |
75 | | - print message |
76 | | - |
77 | | - message_text = message.text #grabs the message text |
78 | | - |
79 | | - print message_text |
80 | | - |
81 | | -#THIS IS VERY IMPORTANT LOOP CONTROL |
82 | | -#if you respond to all messages you will respond to the bot and create a loop condition |
83 | | -#Alternatively you could look at the posting room member and filter your bot's messages |
84 | | - |
85 | | - if ((message_text.find("\CAT", 10, 20)) > -1): #looks for \CAT between position 10 and 20 in message string |
86 | | - |
87 | | - print "Found \CAT" |
88 | | - |
89 | | - cat_fact=get_catfact() #grabs a cat fact |
90 | | - message_post = api.messages.create(room_id,None,None,cat_fact)#posts the fact in the room where request received |
91 | | - |
92 | | - print message_post |
93 | | - |
94 | | - return 'OK' |
95 | 34 |
|
| 35 | +# Module constants |
| 36 | +CAT_FACTS_URL = 'http://catfacts-api.appspot.com/api/facts?number=1' |
96 | 37 |
|
97 | | - |
98 | | -if __name__ == '__main__': |
99 | | - app.run() #starts listening for incoming webhooks |
100 | 38 |
|
| 39 | +# Global variables |
| 40 | +urls = ('/sparkwebhook', 'webhook') # Your Spark webhook should point to http://<serverip>:8080/sparkwebhook |
| 41 | +app = web.application(urls, globals()) # Create the web application instance |
| 42 | +api = CiscoSparkAPI() # Create the Cisco Spark API connection object |
101 | 43 |
|
102 | 44 |
|
| 45 | +def get_catfact(): |
| 46 | + """Get a cat fact from appspot.com and return it as a string. |
| 47 | +
|
| 48 | + Functions for Soundhound, Google, IBM Watson, or other APIs can be added |
| 49 | + to create the desired functionality into this bot. |
| 50 | +
|
| 51 | + """ |
| 52 | + response = requests.get(CAT_FACTS_URL, verify=False) |
| 53 | + response_dict = json.loads(response.text) |
| 54 | + return response_dict['facts'][0] |
| 55 | + |
| 56 | + |
| 57 | +class webhook(object): |
| 58 | + def POST(self): |
| 59 | + """Respond to inbound webhook JSON HTTP POSTs from Cisco Spark.""" |
| 60 | + json_data = web.data() # Get the POST data sent from Spark |
| 61 | + print("\nWEBHOOK POST RECEIVED:") |
| 62 | + print(json_data, "\n") |
| 63 | + |
| 64 | + webhook_obj = Webhook(json_data) # Create a Webhook object from the JSON data |
| 65 | + room = api.rooms.get(webhook_obj.data.roomId) # Get the room details |
| 66 | + message = api.messages.get(webhook_obj.data.id) # Get the message details |
| 67 | + person = api.people.get(message.personId) # Get the sender's details |
| 68 | + |
| 69 | + print("NEW MESSAGE IN ROOM '{}'".format(room.title)) |
| 70 | + print("FROM '{}'".format(person.displayName)) |
| 71 | + print("MESSAGE '{}'\n".format(message.text)) |
| 72 | + |
| 73 | + # This is a VERY IMPORTANT loop prevention control step. |
| 74 | + # If you respond to all messages... You will respond to the messages |
| 75 | + # that the bot posts and thereby create a loop condition. |
| 76 | + me = api.people.me() |
| 77 | + if message.personId == me.id: |
| 78 | + # Message was sent by me (bot); do not respond. |
| 79 | + return 'OK' |
| 80 | + else: |
| 81 | + # Mesage was sent by someone else; parse message and respond. |
| 82 | + if "/CAT" in message.text: |
| 83 | + print("FOUND '/CAT'") |
| 84 | + cat_fact = get_catfact() # Get a cat fact |
| 85 | + print("SENDING CAT FACT '{}'".format(cat_fact)) |
| 86 | + response_message = api.messages.create(room.id, text=cat_fact) # Post the fact to the room where the request was received |
| 87 | + return 'OK' |
| 88 | + |
| 89 | + |
| 90 | +if __name__ == '__main__': |
| 91 | + # Start the web.py web server |
| 92 | + app.run() |
0 commit comments