interactive bots: Add FourSquare bot and documentation.
This commit is contained in:
parent
6972ce61c8
commit
75a9101f30
32
contrib_bots/lib/FourSquareBot/doc.md
Normal file
32
contrib_bots/lib/FourSquareBot/doc.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
# FourSquare Bot
|
||||
|
||||
* This is a bot that returns a list of restaurants from a user input of location,
|
||||
proximity and restaurant type in that exact order. The number of returned
|
||||
restaurants are capped at 3 per request.
|
||||
|
||||
* The list of restaurants are brought to Zulip using an API. The bot sends a GET
|
||||
request to https://api.foursquare.com/v2/. If the user does not correctly input
|
||||
a location, proximity and a restaurant type, the bot will return an error message.
|
||||
|
||||
* For example, if the user says "@foursquare 'Chicago, IL' 80000 seafood", the bot
|
||||
will return:
|
||||
|
||||
Food nearby 'Chicago, IL' coming right up:
|
||||
|
||||
Dee's Seafood Co.
|
||||
2723 S Poplar Ave, Chicago, IL 60608, United States
|
||||
Fish Markets
|
||||
|
||||
Seafood Harbor
|
||||
2131 S Archer Ave (at Wentworth Ave), Chicago, IL 60616, United States
|
||||
Seafood Restaurants
|
||||
|
||||
Joe's Seafood, Prime Steak & Stone Crab
|
||||
60 E Grand Ave (at N Rush St), Chicago, IL 60611, United States
|
||||
Seafood Restaurants
|
||||
|
||||
* If the user enters a wrong word, like "@foursquare 80000 donuts" or "@foursquare",
|
||||
then an error message saying invalid input will be displayed.
|
||||
|
||||
* To get the required API Key, visit: https://developer.foursquare.com/overview/auth
|
||||
for more information.
|
2
contrib_bots/lib/FourSquareBot/settings.ini
Normal file
2
contrib_bots/lib/FourSquareBot/settings.ini
Normal file
|
@ -0,0 +1,2 @@
|
|||
[Foursquare]
|
||||
api_key = abcdefghijksm
|
143
contrib_bots/lib/foursquare.py
Normal file
143
contrib_bots/lib/foursquare.py
Normal file
|
@ -0,0 +1,143 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import datetime as dt
|
||||
import re
|
||||
import requests
|
||||
from os.path import expanduser
|
||||
from six.moves import configparser as cp
|
||||
from six.moves import range
|
||||
|
||||
home = expanduser('~')
|
||||
CONFIG_PATH = home + '/zulip/contrib_bots/lib/FourSquareBot/settings.ini'
|
||||
|
||||
def get_api_key():
|
||||
# settings.ini must have been moved from
|
||||
# ~/zulip/contrib_bots/lib/FourSquareBot/settings.ini into
|
||||
# ~/settings.ini for program to work
|
||||
# see doc.md for more information
|
||||
with open(CONFIG_PATH) as settings:
|
||||
config = cp.ConfigParser()
|
||||
config.readfp(settings)
|
||||
return config.get('Foursquare', 'api_key')
|
||||
|
||||
class FoursquareHandler(object):
|
||||
def __init__(self):
|
||||
self.api_key = get_api_key()
|
||||
|
||||
def usage(self):
|
||||
return '''
|
||||
This plugin allows users to search for restaurants nearby an inputted
|
||||
location to a limit of 3 venues for every location. The name, address
|
||||
and description of the restaurant will be outputted.
|
||||
It looks for messages starting with '@foursquare'.
|
||||
If you need help, simply type:
|
||||
@foursquare /help into the Compose Message box
|
||||
|
||||
Sample input:
|
||||
@foursquare Chicago, IL
|
||||
@foursquare help
|
||||
'''
|
||||
|
||||
help_info = '''
|
||||
The Foursquare bot can receive keyword limiters that specify the location, distance (meters) and
|
||||
cusine of a restaurant in that exact order.
|
||||
Please note the required use of quotes in the search location.
|
||||
|
||||
Example Inputs:
|
||||
@foursquare 'Millenium Park' 8000 donuts
|
||||
@foursquare 'Melbourne, Australia' 40000 seafood
|
||||
'''
|
||||
|
||||
def triage_message(self, message, client):
|
||||
callers = ['@FourSquare', '@Foursquare', '@foursquare', '@4square', '@4sq']
|
||||
for call in callers:
|
||||
if call in message['content']:
|
||||
return True
|
||||
break
|
||||
return False
|
||||
|
||||
def format_json(self, venues):
|
||||
def format_venue(venue):
|
||||
name = venue['name']
|
||||
address = ', '.join(venue['location']['formattedAddress'])
|
||||
keyword = venue['categories'][0]['pluralName']
|
||||
blurb = '\n'.join([name, address, keyword])
|
||||
return blurb
|
||||
|
||||
return '\n'.join(format_venue(venue) for venue in venues)
|
||||
|
||||
def send_info(self, message, letter, client):
|
||||
if message['type'] == 'private':
|
||||
client.send_message(dict(
|
||||
type='private',
|
||||
to=message['sender_email'],
|
||||
content=letter,
|
||||
))
|
||||
else:
|
||||
client.send_message(dict(
|
||||
type='stream',
|
||||
subject=message['subject'],
|
||||
to=message['display_recipient'],
|
||||
content=letter,
|
||||
))
|
||||
|
||||
def handle_message(self, message, client, state_handler):
|
||||
words = message['content'].split()
|
||||
if "/help" in words:
|
||||
self.send_info(message, self.help_info, client)
|
||||
return
|
||||
|
||||
# These are required inputs for the HTTP request.
|
||||
try:
|
||||
params = {'limit': '3'}
|
||||
params['near'] = re.search('\'[A-Za-z]\w+[,]?[\s\w+]+?\'', message['content']).group(0)
|
||||
params['v'] = 20170108
|
||||
params['oauth_token'] = self.api_key
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# Optional params for HTTP request.
|
||||
if len(words) >= 2:
|
||||
try:
|
||||
params['radius'] = re.search('([0-9]){3,}', message['content']).group(0)
|
||||
except AttributeError:
|
||||
pass
|
||||
try:
|
||||
params['query'] = re.search('\s([A-Za-z]+)$', message['content']).group(0)[1:]
|
||||
except AttributeError:
|
||||
params['query'] = 'food'
|
||||
|
||||
response = requests.get('https://api.foursquare.com/v2/venues/search?',
|
||||
params=params)
|
||||
print(response.url)
|
||||
if response.status_code == 200:
|
||||
received_json = response.json()
|
||||
else:
|
||||
self.send_info(message,
|
||||
"Invalid Request\nIf stuck, try '@foursquare help'.",
|
||||
client)
|
||||
return
|
||||
|
||||
if received_json['meta']['code'] == 200:
|
||||
response_msg = ('Food nearby ' + params['near']
|
||||
+ ' coming right up:\n'
|
||||
+ self.format_json(received_json['response']['venues']))
|
||||
self.send_info(message, response_msg, client)
|
||||
return
|
||||
|
||||
self.send_info(message,
|
||||
"Invalid Request\nIf stuck, try '@foursquare help'.",
|
||||
client)
|
||||
return
|
||||
|
||||
handler_class = FoursquareHandler
|
||||
|
||||
def test_get_api_key():
|
||||
# must change to your own api key for test to work
|
||||
result = get_api_key()
|
||||
assert result == 'abcdefghijksm'
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_get_api_key()
|
||||
print('Success')
|
Loading…
Reference in a new issue