Extrait du précédent "J'ai essayé d'utiliser Slackbot après avoir étudié Python 3" Nous avons amélioré ou ajouté des fonctionnalités.
À l'aide de l'API Guru Navi, entrez un mot de recherche dans slack et renvoyez l'URL du hit. Si vous tapez "riz Shinagawa Yakitori", l'URL d'une boutique qui ressemble à un restaurant Yakitori à Shinagawa sera retournée. Comme je recherchais par adresse lors de la recherche par mot-clé d'emplacement, le résultat de l'emplacement différent de l'image réelle est renvoyé, j'ai donc changé pour la recherche à l'aide du maître de zone.
Il s'agit d'une recherche de nom de magasin à l'aide de l'API Guru Navi. Si vous tapez "Shop Shinagawa LOL", l'URL de Shinagawa LOL sera retournée. Il s'agit simplement d'une recherche par nom de magasin. Cependant, nous ne pouvons pas gérer les cas où il y a un espace entre eux.
Renvoie l'image radar du nuage de pluie à l'aide de l'API Geocoder de Yahoo et de l'API Static Map.
Si vous tapez "pluie Shinagawa", une image de carte avec des nuages de pluie près de Shinagawa sera renvoyée. Pour renvoyer l'image de la carte, utilisez l'API de Slack files.upload
.
J'ai utilisé Pillow pour travailler avec des fichiers image.
slackbot/ ├ plugins/ │ └ slackbot_restapi.py │ └ restapi.py │ └ gnaviapi.py │ └ run.py └ slackbot_settings.py └ Procfile (fichier pour Heroku) └ runtime.txt (fichier pour Heroku)
Cela n'a pas changé en particulier. Je modifie gnaviapi.py et slackbot_restapi.py. Cependant, la classification et l'organisation en quelque sorte ne sont pas divisées w Je pense que je peux l'écrire un peu plus magnifiquement.
Cette fois, seuls les changements. Contrairement à la dernière fois, c'est une explication pour chaque spécification.
slackbot_restapi.py
"""
Plugin Program
"""
from io import BytesIO
import requests
from requests.exceptions import RequestException
from PIL import Image
from slackbot.bot import listen_to
from plugins.restapi import RestApi
from plugins.gnaviapi import GnaviApi
import slackbot_settings
@listen_to('riz')
@listen_to('boutique')
def search_restraunt(message):
"""
Recherchez Guru Navi en fonction du message reçu et renvoyez l'URL.
Emplacement: Code maître de la zone M(areacode_m)ou adresse(address)
Mots-clés: mots libres(freeword)ou nom du magasin(name)
"""
url = 'https://api.gnavi.co.jp/RestSearchAPI/20150630/'
key = 'YOUR_GNAVI_API_TOKEN'
gnavi = GnaviApi(url, key)
search_word = message.body['text'].split()
if len(search_word) >= 3:
try:
params = gnavi.create_params(search_word)
gnavi.garea_middle_fech()
search_area = gnavi.garea_middle_search(search_word[1])
if len(search_area) == 0:
search_area = {'address': search_word[1]}
params.update(search_area)
gnavi.api_request(params)
for rest_url in gnavi.url_list():
message.send(rest_url)
except RequestException:
message.send('Je ne suis pas entré dans Guru Navi, alors cherchez-le à nouveau plus tard ...( ´Д`)y━ ・~~')
return
except Exception as other:
message.send(''.join(other.args))
return
else:
message.send('↓ Je veux que vous cherchiez comme ça ...( ̄Д ̄)Non')
message.send('Mot-clé Rice place (les caractères sont séparés par des espaces)')
message.send('Exemple) Rice Shinagawa Yakitori')
Avec params = gnavi.create_params (search_word)
, il juge "riz" ou "magasin" et change le paramètre à lancer à l'API en mot libre ou nom de magasin.
Utilisez garea_middle_fech ()
pour rechercher le maître de la zone M de Guru Navi et obtenir l'indicatif régional.
garea_middle_search (search_word [1])
renvoie le premier indicatif régional qui correspond au nom de lieu saisi dans Slack.
Si vous ne parvenez pas à obtenir l'indicatif régional, nous continuerons à rechercher l'adresse.
Le reste est le même que la dernière fois.
gnavapi.py
"""
API Guru Navi
"""
# -*- coding: utf-8 -*-
from requests.exceptions import RequestException
from plugins.restapi import RestApi
class GnaviApi(RestApi):
"""
Classe d'API Guru Navi
"""
def __init__(self, url, key):
super().__init__(url)
self.key = key
self.garea_s = None
def create_params(self, search_word):
"""
Modifiez les paramètres de l'API en fonction des mots clés saisis dans Slack.
"""
params = {
'format': 'json'
}
if search_word[0] == 'riz':
params['freeword'] = search_word[2]
elif search_word[0] == 'boutique':
params['name'] = search_word[2]
return params
def url_list(self):
"""
Créez une liste d'URL de restaurant à partir de Response et renvoyez-la.
"""
json_data = self.response_data.json()
if 'error' in json_data:
raise Exception('Je n'ai pas pu le trouver avec ce mot-clé ...(´ ・ ω ・ `)')
if json_data['total_hit_count'] == '1':
return [(json_data['rest'])['url']]
else:
return [rest_data['url'] for rest_data in json_data['rest']]
def garea_middle_fech(self):
"""
Obtenez le maître de zone M de l'API Guru Navi.
"""
garea = RestApi('https://api.gnavi.co.jp/master/GAreaMiddleSearchAPI/20150630/')
params = {
'keyid': self.key,
'format': 'json',
'lang': 'ja'
}
try:
garea.api_request(params)
self.garea_s = garea.response_data.json()
if 'error' in self.garea_s:
raise Exception('Je ne connais pas l'endroit ...(´ ・ ω ・ `)')
except RequestException:
raise RequestException()
def garea_middle_search(self, area_name):
"""
Depuis l'intérieur de la zone M maître, zone_Obtenez la valeur qui correspond au nom.
(Parce qu'il est strict s'il s'agit d'une correspondance exacte, il s'agit d'une correspondance partielle.)
"""
result_dict = {}
for area_s in self.garea_s['garea_middle']:
if area_s['areaname_m'].find(area_name) >= 0:
result_dict = {'areacode_m': area_s['areacode_m']}
break
return result_dict
↑ Une méthode de recherche d'un maître de zone a été ajoutée à la classe API Guru Navi.
slackbot_restapi.py
"""
Plugin Program
"""
from io import BytesIO
import requests
from requests.exceptions import RequestException
from PIL import Image
from slackbot.bot import listen_to
from plugins.restapi import RestApi
from plugins.gnaviapi import GnaviApi
import slackbot_settings
def search_restraunt(message):
"""
réduction!!!
"""
@listen_to('pluie')
def search_weather(message):
"""
Obtenez la latitude et la longitude de l'API Geocoder en fonction du message reçu.
Renvoie l'image radar du nuage de pluie de l'API de carte statique en fonction de la latitude et de la longitude.
Adresse de l'emplacement(query)
"""
url_geocoder = 'https://map.yahooapis.jp/geocode/V1/geoCoder'
url_staticmap = 'https://map.yahooapis.jp/map/V1/static'
key_yahoo = 'YOUR_YAHOO_API_TOKEN'
url_slackapi = 'https://slack.com/api/files.upload'
geocoder_api = RestApi(url_geocoder)
staticmap_api = RestApi(url_staticmap)
search_word = message.body['text'].split()
try:
geocoder_api_params = {
'appid': key_yahoo,
'query': search_word[1],
'output': 'json'
}
geocoder_api.api_request(geocoder_api_params)
geocoder_json = geocoder_api.response_data.json()
if 'Error' in geocoder_json:
raise Exception('Je ne connais pas l'endroit ...(´ ・ ω ・ `)')
coordinates = (((geocoder_json['Feature'])[0])['Geometry'])['Coordinates']
staticmap_api_params = {
'appid': key_yahoo,
'lon': (coordinates.split(','))[0],
'lat': (coordinates.split(','))[1],
'overlay': 'type:rainfall',
'output': 'jpg',
'z': '13'
}
staticmap_api.api_request(staticmap_api_params)
slackapi_params = {
'token': slackbot_settings.API_TOKEN,
'channels': 'C5CJE5YBA'
}
image_obj = Image.open(BytesIO(staticmap_api.response_data.content), 'r')
image_obj.save('/tmp/weather.jpg')
with open('/tmp/weather.jpg', 'rb') as weatherfile:
requests.post(url_slackapi, data=slackapi_params, files={
'file': ('weather.jpg', weatherfile, 'image/jpeg')})
except Exception as other:
message.send(''.join(other.args))
return
Contrairement à l'API Guru Navi, le maître de zone ne semble pas exister, donc la latitude et la longitude sont acquises en fonction de l'adresse. Une fois que vous avez la latitude et la longitude, le reste est facile. Il était facile d'obtenir les données d'image ** «obtenir» **. Jusque là ...
De là, j'en étais accro.
J'avais peur de ne pas pouvoir télécharger de données d'image sur Slack.
Au début, je pensais que j'irais si j'envoyais ʻimage_obj = Image.open (BytesIO (staticmap_api.response_data.content), 'r') , mais c'est totalement inutile. À la suite de divers essais, j'ai réussi à enregistrer une fois le fichier réel, à le lire avec kʻopen ()
et à envoyer les données.
Heroku semble être capable de sauvegarder des fichiers sous / tmp
, donc je l'ai sauvegardé sous ʻimage_obj.save ('/tmp/weather.jpg')` et je l'ai rechargé.
Puisque ʻimage_obj était un objet
JpgImageFile, ce serait le même que l'objet
file, est-ce la cause de la défaite? J'étais inquiet environ 3 jours après avoir configuré
PngImageFile ou ʻimage_obj = BytesIO (staticmap_api.response_data.content)
puis en utilisant getvalue ()
et getbuffer ()
.
Je vérifie les spécifications de requests.post ()
, mais je ne sais pas pourquoi le JpgImageFile
ne peut pas être envoyé. Je continuerai d'enquêter, mais si quelqu'un le sait, faites-le moi savoir.
Merci pour votre commentaire
Changer avant
image_obj = Image.open(BytesIO(staticmap_api.response_data.content), 'r')
image_obj.save('/tmp/weather.jpg')
with open('/tmp/weather.jpg', 'rb') as weatherfile:
requests.post(url_slackapi, data=slackapi_params, files={
'file': ('weather.jpg', weatherfile, 'image/jpeg')})
Cette partie,
Après le changement
output = BytesIO()
image_obj = Image.open(BytesIO(staticmap_api.response_data.content), 'r')
image_obj.save(output, 'jpeg')
requests.post(slackbot_settings.API_URL, data=slackapi_params, files={
'file': ('weather.jpg', output.getvalue(), 'image/jpeg')
})
Je l'ai corrigé et déplacé, et cela a fonctionné! Pourquoi cela n'a-t-il pas fonctionné tel quel? Bref, merci!
Recommended Posts