Skip to content

Commit 077ec28

Browse files
authored
Merge pull request #36 from jbogarin/master
Flask Bot example bug fix and Pyramid Spark Bot example!
2 parents d8ac448 + 23b0daf commit 077ec28

File tree

5 files changed

+194
-0
lines changed

5 files changed

+194
-0
lines changed

examples/pyramidSparkBot/README.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Documentation
2+
=============
3+
4+
Put a brief description of 'Pyramid Spark Bot application'.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
[app:main]
2+
use = egg:pyramidSparkBot
3+
4+
pyramid.reload_templates = true
5+
pyramid.debug_authorization = false
6+
pyramid.debug_notfound = false
7+
pyramid.debug_routematch = false
8+
pyramid.debug_templates = true
9+
pyramid.default_locale_name = en
10+
11+
[server:main]
12+
use = egg:waitress#main
13+
host = 0.0.0.0
14+
port = 6543
15+
16+
# Begin logging configuration
17+
18+
[loggers]
19+
keys = root, pyramidSparkBot
20+
21+
[handlers]
22+
keys = console
23+
24+
[formatters]
25+
keys = generic
26+
27+
[logger_root]
28+
level = INFO
29+
handlers = console
30+
31+
[logger_pyramidSparkBot]
32+
level = DEBUG
33+
handlers =
34+
qualname = pyramidSparkBot
35+
36+
[handler_console]
37+
class = StreamHandler
38+
args = (sys.stderr,)
39+
level = NOTSET
40+
formatter = generic
41+
42+
[formatter_generic]
43+
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
44+
45+
# End logging configuration
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
"""Main entry point
2+
"""
3+
from pyramid.config import Configurator
4+
5+
6+
def main(global_config, **settings):
7+
config = Configurator(settings=settings)
8+
config.include("cornice")
9+
config.scan("pyramidSparkBot.views")
10+
return config.make_wsgi_app()
11+
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""A simple bot script, built on Pyramid using Cornice
2+
3+
This sample script leverages the Pyramid web framework (https://trypyramid.com/) with
4+
Cornice (https://cornice.readthedocs.io). By default the web server will be reachable at
5+
port 6543 you can change this default if desired (see `pyramidSparkBot.ini`).
6+
7+
ngrok (https://ngrok.com/) can be used to tunnel traffic back to your server
8+
if your machine sits behind a firewall.
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+
This script supports Python versions 2 and 3.
22+
"""
23+
from __future__ import (absolute_import, division,
24+
print_function, unicode_literals)
25+
from cornice import Service
26+
27+
from builtins import *
28+
29+
import json
30+
31+
import requests
32+
33+
from ciscosparkapi import CiscoSparkAPI, Webhook
34+
35+
import logging
36+
log = logging.getLogger(__name__)
37+
38+
39+
# Module constants
40+
CHUCK_NORRIS_JOKES_URL = 'http://api.icndb.com/jokes/random'
41+
42+
43+
# Initialize the environment
44+
spark_api = CiscoSparkAPI() # Create the Cisco Spark API connection object
45+
46+
47+
# Helper functions
48+
def get_chuck_norris_joke():
49+
"""Get a Chuck Norris Joke from api.icndb.com and return it as a string.
50+
Functions for Soundhound, Google, IBM Watson, or other APIs can be added
51+
to create the desired functionality into this bot.
52+
"""
53+
response = requests.get(CHUCK_NORRIS_JOKES_URL, verify=False)
54+
response_dict = json.loads(response.text)
55+
return response_dict['value']['joke']
56+
57+
58+
sparkwebhook = Service(name='sparkwebhook', path='/sparkwebhook', description="Spark Webhook")
59+
60+
61+
@sparkwebhook.get()
62+
def get_sparkwebhook(request):
63+
log.info(get_chuck_norris_joke())
64+
return {"joke": get_chuck_norris_joke()}
65+
66+
@sparkwebhook.post()
67+
# Your Spark webhook should point to http://<serverip>:5000/sparkwebhook
68+
def post_sparkwebhook(request):
69+
"""Respond to inbound webhook JSON HTTP POST from Cisco Spark."""
70+
71+
json_data = request.json # Get the POST data sent from Cisco Spark
72+
log.info("\n")
73+
log.info("WEBHOOK POST RECEIVED:")
74+
log.info(json_data)
75+
log.info("\n")
76+
77+
webhook_obj = Webhook(json_data) # Create a Webhook object from the JSON data
78+
room = spark_api.rooms.get(webhook_obj.data.roomId) # Get the room details
79+
message = spark_api.messages.get(webhook_obj.data.id) # Get the message details
80+
person = spark_api.people.get(message.personId) # Get the sender's details
81+
82+
log.info("NEW MESSAGE IN ROOM '{}'".format(room.title))
83+
log.info("FROM '{}'".format(person.displayName))
84+
log.info("MESSAGE '{}'\n".format(message.text))
85+
86+
# This is a VERY IMPORTANT loop prevention control step.
87+
# If you respond to all messages... You will respond to the messages
88+
# that the bot posts and thereby create a loop condition.
89+
me = spark_api.people.me()
90+
if message.personId == me.id:
91+
# Message was sent by me (bot); do not respond.
92+
return {'Message': 'OK'}
93+
94+
else:
95+
# Message was sent by someone else; parse message and respond.
96+
if "/CHUCKNORRIS" in message.text:
97+
log.info("FOUND '/CHUCKNORRIS'")
98+
chuck_norris_joke = get_chuck_norris_joke() # Get a Chuck Norris Joke
99+
log.info("SENDING CHUCK NORRIS JOKE '{}'".format(chuck_norris_joke))
100+
spark_api.messages.create(room.id, text=chuck_norris_joke) # Post the fact to the room where the request was received
101+
return {'Message': 'OK'}
102+

examples/pyramidSparkBot/setup.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import os
2+
from setuptools import setup, find_packages
3+
4+
here = os.path.abspath(os.path.dirname(__file__))
5+
6+
with open(os.path.join(here, 'README.rst')) as f:
7+
README = f.read()
8+
9+
10+
setup(name='pyramidSparkBot',
11+
version=0.1,
12+
description='Pyramid Spark Bot application',
13+
long_description=README,
14+
classifiers=[
15+
"Programming Language :: Python",
16+
"Framework :: Pylons",
17+
"Topic :: Internet :: WWW/HTTP",
18+
"Topic :: Internet :: WWW/HTTP :: WSGI :: Application"
19+
],
20+
keywords="web services",
21+
author='',
22+
author_email='',
23+
url='',
24+
packages=find_packages(),
25+
include_package_data=True,
26+
zip_safe=False,
27+
install_requires=['cornice', 'waitress'],
28+
entry_points="""\
29+
[paste.app_factory]
30+
main=pyramidSparkBot:main
31+
""",
32+
paster_plugins=['pyramid'])

0 commit comments

Comments
 (0)