ãã£ãããããã¯ãã§ã«éåžžã«äžè¬çã«ãªã£ãŠãããæ¯æ¥ãã¹ãŠã®ã€ã³ã¹ã¿ã³ãã¡ãã»ã³ãžã£ãŒã«è¡šç€ºãããŸãã
ãã®èšäºã§ã¯ãäžé£ã®åçŽãªã³ãã³ãã䜿çšããŠããããäœæããæ¹æ³ã段éçã«èŠãŠãå°æ¥çã«ãã®æ©èœãæ¡åŒµããæ¹æ³ãèŠã€ããŸãã ãã®èšäºã¯ããã£ããããããäœæããããšã®ãªãã»ãšãã©ã®åå¿è
ã«åœ¹ç«ã¡ãŸãã
ããããäœæããããšãã¯ãVKontakteã§äœ¿çšå¯èœãªãããã®äŸãæ€èšãããã®æ§é ãæå€§éã«åçŽåããããšã詊ã¿ãŸããã
ããããäœæããããã«ãPython 3.5ïŒ3çªç®ã®pythonã®ä»ã®ããŒãžã§ã³ãããããé©åã§ãïŒãšè¿œå ã®
Flaskããã³
VKã©ã€ãã©ãªã䜿çšããŸããã ããããã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã Flaskã®ã€ã³ã¹ããŒã«ã«é¢ãããã·ã¢èªã®èšäºã倿°ãããŸãã Pycharmããæã¡ã®å Žåã¯ãããããPycharmãšå
±ã«ã€ã³ã¹ããŒã«ãããŠããŸãã
APIèªäœããå§ããŸãããã ãããã«ã¯ãã°ã«ãŒãã¡ãã»ãŒãžã«äœ¿çšã§ããã³ãŒã«ããã¯APIã䜿çšããŸãã ãŸããæ¥ç¶ãããã¡ãã»ãŒãžãå«ãVKontakteã°ã«ãŒããäœæãããããã§ã«æã£ãŠããå¿
èŠããããŸãã
[
ã³ãã¥ããã£ç®¡ç] â[
APIã®æäœ]ã»ã¯ã·ã§ã³ã§ãã³ãã¥ããã£ã¡ãã»ãŒãžã«ã¢ã¯ã»ã¹ã§ããããŒãäœæããå¿
èŠããããŸãã
ã³ãŒã«ããã¯ã䜿çšããã«ã¯ãAPIããã€ãã³ãã®ãªã¯ãšã¹ããåä¿¡ããããããåŠçããã¬ã¹ãã³ã¹ãªã¯ãšã¹ããéä¿¡ããWebãµãŒããŒãå¿
èŠã§ãã ã€ãŸããéä¿¡ããããªã¯ãšã¹ãã«ã®ã¿å¿çããéä¿¡ããããŠã§ããµã€ãããäœæããŸãã
pythonã§èšè¿°ããŠããããã䜿çšã§ããæãç°¡åãªãã®ã¯pythonã®ãã¹ãã£ã³ã°ã§ãã Pythonã®ç¡æ
ãã¹ãã£ã³ã°ã䜿çšããŸããã ããã§ç»é²ããFlaskã§Python 3.5çšã®ã¢ããªã±ãŒã·ã§ã³ãäœæããå¿
èŠããããŸãïŒWebã»ã¯ã·ã§ã³ã§äœæã§ããŸãïŒã åæãã¡ã€ã«ãäœæãããŸãïŒ
çŸåšãã¡ã€ã«ã«ããå¯äžã®æ©èœã¯ãç»é²æã«æå®ãããã¢ãã¬ã¹ã§ããŒãžãåããããšã«è²¬ä»»ããããŸãã username.pythonanywhere.comã®ãã©ãŠã¶ïŒããã¯ããŒã ã䜿çšïŒã«ã¢ã¯ã»ã¹ãããšããHello from FlaskïŒããšããããã¹ãã®ã¿ã衚瀺ãããŸãã
å°æ¥çã«ã¯ãã³ãŒãã¯ãããã¯ã§è¡šç€ºããããããã¯å
šäœã®å®äºåŸã«ãã§ãã¯ããããšãå¯èœã«ãªãããã®ããã»ã¹ã§ã³ãŒããç°å¢ã«ãã£ãŠãšã©ãŒãšããŠããŒã¯ãããå¯èœæ§ããããŸãã æãããªãã§ããããã¯ãæåŸãŸã§çµããããã»ããããã§ãã
ãããã£ãŠã
ãããã¯1ã§ãã
ãµã€ãã«éä¿¡ããããªã¯ãšã¹ããåŠçããã«ã¯ãããã¥ã¡ã³ãã®æåŸã«æ¬¡ã®ã³ãŒãã远å ããŸãã
@app.route('/', methods=['POST']) def processing(): return 'xxxxxxxx'
Xã®ä»£ããã«ãããµãŒããŒãè¿ãå¿
èŠã®ããæååãã代å
¥ããŸãã ããã¯ãã³ãŒã«ããã¯APIã»ã¯ã·ã§ã³ã®ã°ã«ãŒã管çã«ãªã¹ããããŠããŸãã
ãã®æ©èœã«ãããã°ã«ãŒãã«éç¥ããããã«ãµã€ããæ¥ç¶ã§ããŸãã
ããã§äœæ¥ã確èªã§ããŸãã ã¢ããªã±ãŒã·ã§ã³ãåèµ·åããã ãã§ãã ãµã€ããæ°ããããŒã¿ã§äœæ¥ãéå§ã§ããããã«ãã¡ã€ã«ã倿ŽããŠä¿åããåŸã®ãã¹ãã£ã³ã°ã§ã¯ã[Web]ã¿ãã§ããããªããŒãããå¿
èŠããããŸãã ãã®ã³ãŒãã远å ããåŸãVKontakteã°ã«ãŒãã®ãµãŒããŒã¢ãã¬ã¹ããŒã«å¯Ÿå¿ããã¢ãã¬ã¹username.pythonanywhere.comãå
¥åãã[確èª]ãã¯ãªãã¯ããŸãã
ãµãŒããŒã¢ãã¬ã¹ãæ£åžžã«æ¥ç¶ãããããšã瀺ãç·è²ã®éç¥ã衚瀺ãããŸãã
[確èª]ãã¯ãªãã¯ãããšãVKontakteã¯ãµãŒããŒã«æ¥ç¶ãããããå®éã«ã°ã«ãŒãææè
ã«å±ããŠããããšã確èªãããµãŒããŒãèŠæ±ã«å¿ããŠç¢ºèªã³ãŒããè¿ãã®ããåŸ
æ©ãããŸãã
ãããã¯2次ã®ã¹ãããã«é²ãããšãã§ããŸãã ã³ãã¥ããã£ã«ä»£ãã£ãŠã¡ãã»ãŒãžãæžãèŸŒãæ©èœã远å ããŸãã ãã¹ãã£ã³ã°ã«VKã©ã€ãã©ãªãã€ã³ã¹ããŒã«ããŸãã ãã³ã³ãœãŒã«ãã»ã¯ã·ã§ã³ã§ãbashã³ã³ãœãŒã«ãèµ·åããã³ãã³ãïŒãŸãã¯éžæããããŒãžã§ã³ã®pythonã«é©ããã³ãã³ãïŒãå®è¡ããŸãã
pip3.5 install --user vk
ã¢ãžã¥ãŒã«ã®ã€ã³ã¹ããŒã«æ¹æ³ã«ã€ããŠã¯ã
ããã§èª¬æã
ãŸã ã
åä¿¡ãªã¯ãšã¹ããåŠçããããã®é¢æ°ã®ã³ãŒãã倿ŽããŸãã
@app.route('/', methods=['POST']) def processing(): # json POST- data = json.loads(request.data) # if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': session = vk.Session() api = vk.API(session, v=5.0) user_id = data['object']['user_id'] api.messages.send(access_token=token, user_id=str(user_id), message=', !') # , return 'ok'
VKontakteãµãŒããŒã«ã¯ãåŠçãæåãããšããã¡ãã»ãŒãžãå¿
èŠã§ãã ãšã©ãŒãçºçããå ŽåããŸãã¯ä»ã®åçãå°çããå ŽåããµãŒããŒã¯äžå®ã®ééã§ïŒåŠçãããŸã§ïŒçä¿¡ã¡ãã»ãŒãžã«é¢ããéç¥ãéä¿¡ãç¶ããŸãã
æ°ããã¡ãã»ãŒãžã«ã€ããŠéç¥ããçä¿¡èŠæ±ã®æ§é ã¯æ¬¡ã®ãšããã§ãã
{"type":"message_new","object":{"id":43, "date":1492522323, "out":0, "user_id":xxxxxxxx, "read_state":0, "title":" ... ", "body":""}, "group_id":xxxxxxxxxxx}
Vkontakteã¯ããµã€ãã«3ã€ã®ãªããžã§ã¯ããtypeãããobjectãããgroup_idããæž¡ããã¡ãã»ãŒãžã«é¢ããæ
å ±ã¯ãobjectãå
ã«ä¿åãããŸãã
ãã¹ãŠã®ãªã¯ãšã¹ãã¯VKontakteã®
ããã¥ã¡ã³ãã«èšèŒãããŠã
ãŸããŸããæ°ãããã€ã³ããŒããããã¡ã€ã«ã®å
é ã«è¿œå ããŸãã
from flask import Flask, request, json from settings import * import vk
åãsettings.pyãã©ã«ããŒã«æ°ãããã¡ã€ã«ãäœæããããã«å¿
èŠãªãã°ã€ã³ããŒã¿ãä¿åããŸãã
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' confirmation_token = 'xxxxxxxx'
ãããã¯ããŒã¯ã³ã«çœ®ãæããå¿
èŠããããŸãã æåã¯èšäºã®åé ã§äœæãã2çªç®ã¯ã°ã«ãŒãããµãŒããŒã«æ¥ç¶ããããã®ç¢ºèªã³ãŒãã§ãã
ããã§ãããã¯çä¿¡ã¡ãã»ãŒãžã«æšæ¶ããã³ãŒããäžããã°ã«ãŒãã«å±ããŠããããšã確èªã§ããŸãã
ããã確èªããŠã¡ãââã»ãŒãžãæžã蟌ãããšãã§ããŸããCallbackAPIã»ã¯ã·ã§ã³ã®ã°ã«ãŒãèšå®ã§çä¿¡ã¡ãã»ãŒãžã«é¢ããéç¥ãæå¹ã«ããã ãã§ãã
ããããã¡ãã»ãŒãžãéä¿¡ããã«ã¯ãã¢ããªã±ãŒã·ã§ã³ãåèµ·åããå¿
èŠããããŸãã ãã®åŸããããã«å床æžã蟌ã¿ããã¹ãŠãæ£åžžã«è¡ãããå Žåãæ¬¡ã®ã¹ãããã«é²ã¿ãŸãã
ãããã¯3ãã¹ãŠãããŸããããã¡ãã»ãŒãžã«å¿ããŠããããããªãã«æšæ¶ããå Žåãæ¬¡ã®ã¹ãããã«é²ã¿ãŸãã vkã©ã€ãã©ãªãšã®ãã¹ãŠã®å¯Ÿè©±ãå¥ã®ãã¡ã€ã«ã«å
¥ããŸãããvkapiãšåŒã³ãŸãã
import vk session = vk.Session() api = vk.API(session, v=5.0) def send_message(user_id, token, message, attachment=""): api.messages.send(access_token=token, user_id=str(user_id), message=message, attachment=attachment)
VKontakteã»ãã·ã§ã³ã®é¢æ°ãšåæåã¯1ã€ã ãã§ãããä»ã®ã»ãã·ã§ã³ã远å ããŸãã æœåšçã«ã颿°ã¯æ·»ä»ãã¡ã€ã«ãéä¿¡ããããšãã§ããŸãã åŸã§ãã®æ©äŒãå©çšããŸãã
次ã«ãã¡ãã»ãŒãžãã³ãã©ãã¡ã€ã«ãéå§ããŸãã çä¿¡ã¡ãã»ãŒãžãåŠçãã衚瀺ããããšãã«é©åãªã³ãã³ããæ±ºå®ããå¿
èŠãªåçãçºè¡ããŸãã
ãã¡ã€ã«ãmessageHandler.pyãïŒ
import vkapi def get_answer(body): message = ", !" return message def create_answer(data, token): user_id = data['user_id'] message = get_answer(data['body'].lower()) vkapi.send_message(user_id, token, message)
æ°ãããã¡ã€ã«ãã¡ã€ã³ã®ãã¡ã€ã«ã«æ¥ç¶ããŸãã ã¡ã€ã³ãã¡ã€ã«ã®ãªã¯ãšã¹ãåŠç颿°ã倿ŽããŸãã
@app.route('/', methods=['POST']) def processing(): data = json.loads(request.data) if 'type' not in data.keys(): return 'not vk' if data['type'] == 'confirmation': return confirmation_token elif data['type'] == 'message_new': messageHandler.create_answer(data['object'], token) return 'ok'
ãããŠãé©åãªã€ã³ããŒãããã¡ã€ã«ã®å
é ã«è¿œå ããŸãã
import messageHandler
ã¢ããªã±ãŒã·ã§ã³ãåèµ·åããããšã§ãå®è¡ããããšã確èªã§ããŸãã
ãããã¯4ããŒã ã®äœæãå§ããŸãããã ã³ãã³ãã®ã¯ã©ã¹ãäœæããŸãã
ãã¡ã€ã«ãcommand_system.pyãïŒ
command_list = [] class Command: def __init__(self): self.__keys = [] self.description = '' command_list.append(self) @property def keys(self): return self.__keys @keys.setter def keys(self, mas): for k in mas: self.__keys.append(k.lower()) def process(self): pass
ã¯ã©ã¹ã«ã¯keysããããã£ãããããã®ã³ãã³ãã«ã¢ã¯ã»ã¹ã§ããããŒãä¿åãããŸãã ããããã£ãèšå®ãããšãããã¹ãŠã®ããŒã¯å°æåã§ä¿åãããŸãããŸããã³ãã³ãã³ãŒã«ã®æåã«ã¬ãžã¹ã¿ã圱é¿ããªãããã«ãå°æåã«å€æããããŠãŒã¶ãŒã¡ãã»ãŒãžãšæ¯èŒããå¿
èŠããããŸãã
説æãã£ãŒã«ãã¯ããããã³ãã³ãã«é¢ããæ
å ±ãçºè¡ããããã«äœ¿çšãããŸãã ããã»ã¹é¢æ°ãå®è¡ãããå¿çã¡ãã»ãŒãžãçæãããŸãã
åæåæã«ãã¹ãŠã®ã³ãã³ããä¿åãããäžè¬çãªãªã¹ãããããŸãã åœŒã¯æå®€ã®å€ã«ããŸãã ãã®ãªã¹ãã䜿çšããŠããŠãŒã¶ãŒãã¡ãã»ãŒãžã§èŠæ±ããã³ãã³ããèŠã€ããŸãã
ããã§ã¯ããããçšã®ããŒã ãããã€ãäœæããŸãããã ããŒãã®äŸ¿å®äžãã³ãã³ããåæåãããã¡ã€ã«ããcommandsããã©ã«ããŒã«é
眮ããŸãã
è€æ°ã®ãã¡ã€ã«ãäœæããŸãããã³ãã³ãã1ã€ã®ãã¡ã€ã«ã«é
眮ããããšãã§ããŸã
ãHello.pyã
import command_system def hello(): message = ', !\n -.' return message, '' hello_command = command_system.Command() hello_command.keys = ['', 'hello', '', '', ''] hello_command.description = ' ' hello_command.process = hello
ãCat.pyã
import command_system import vkapi import settings def cat():
ç«ãéãããŒã ã«ã¯ãã°ã«ãŒããŸãã¯ãŠãŒã¶ãŒã®å£ããã©ã³ãã ãªç»åãè¿ããvkapiããã¡ã€ã«ã®æ°ããããŒã¯ã³ãšæ°ãã颿°ãå¿
èŠã§ãã ãã®å Žåãç§ãã¡ã¯ç«ãšäžç·ã«å
¬è¡ã®å£ããã©ã³ãã ãªåçãåãåããŸãã
ããŒã¯ã³ãååŸããããšããå§ããŸãããã ãµãŒãã¹ã¢ã¯ã»ã¹ããŒãå¿
èŠã§ãã ãããè¡ãã«ã¯ãæ°ããã¹ã¿ã³ãã¢ãã³ã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
åç
§ã«ãã£ãŠäœæã§ããŸãã æ¬¡ã«ãã¢ããªã±ãŒã·ã§ã³ãäœæãããããã®èšå®ã«ç§»åããŠã[ãµãŒãã¹ã¢ã¯ã»ã¹ããŒ]ãã£ãŒã«ãã®å
容ãã³ããŒããå¿
èŠããããŸãã
ãããããŒã¯ã³ãã¡ã€ã«ã«è¿œå ããå¿
èŠããããŸãã
ãSettings.pyã
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' confirmation_token = 'xxxxxxxx' access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
ããã§ã¯ãæ°ããvkapiã¡ãœããã®äœæã«ç§»ããŸãããã ããã§ã¯ã䜿çšããAPIã¡ãœããã®ç¯å²ãå°ãæ¡å€§ããŸãã
ãã®ã¡ãœããã¯æ¬¡ã®ããã«ãªããŸãã
def get_random_wall_picture(group_id, token): max_num = api.photos.get(owner_id=group_id, album_id='wall', count=0, access_token=token)['count'] num = random.randint(1, max_num) photo = api.photos.get(owner_id=str(group_id), album_id='wall', count=1, offset=num, access_token=token)['items'][0]['id'] attachment = 'photo' + str(group_id) + '_' + str(photo) return attachment
ãvkapiããã¡ã€ã«ã«è¿œå ããŸãã ãŸããå¿
èŠãªã€ã³ããŒãããvkapiããã¡ã€ã«ã®å
é ã«è¿œå ããŸãã
import random
ãããŠæåŸã®ããŒã
ãInfo.pyã
import command_system def info(): message = '' for c in command_system.command_list: message += c.keys[0] + ' - ' + c.description + '\n' return message, '' info_command = command_system.Command() info_command.keys = ['', '', 'help'] info_command.desciption = ' ' info_command.process = info
æçµçãªãã¡ã€ã«éå±€ïŒ

botFlaskã¯ãçä¿¡èŠæ±ãåãå
¥ããã¡ã€ã³ãã¡ã€ã«ã§ãã
ã³ãã³ãã®èª¬æãçµãã£ãã®ã§ãã³ãã³ãã·ãŒãããã£ã±ãã«ãªã£ãŠããããšã確èªããå¿
èŠããããŸãããŸããcommand_listã¯ç¹å®ã®ã³ãã³ãã§ãã¡ã€ã«ãèµ·åãããšãã«ã®ã¿å
¥åãããããããŠãŒã¶ãŒãã¢ã¯ã»ã¹ããã³ãã³ããçè§£ã§ããŸãã
ãããã®èµ·åæã«ããcommandsããã©ã«ããŒãããã¹ãŠã®ãã¡ã€ã«ãèªåçã«èµ·åããŸãã
ãããè¡ãã«ã¯ãmessageHandler.pyãã¡ã€ã«ã«é¢æ°ã远å ããŸãã
def load_modules():
ãã®é¢æ°ã§ã¯ãã³ãã³ãã䜿çšããŠãã£ã¬ã¯ããªãããã¡ã€ã«ã®ãªã¹ããããŒãããPythonãã¡ã€ã«ã®ã¿ããã£ã«ã¿ãŒåŠçããŠããã°ã©ã ã«ã€ã³ããŒãããŸããããã«ããããªã¹ãã«ã³ãã³ããå
¥åãããŸãã
ãã®é¢æ°ã®åŒã³åºããcreate_answerã«è¿œå ãããŸãã æ¬¡ã«ã察å¿ããå¿çãåŒã³åºãããã«get_answer颿°ã倿ŽããŸãããã
ãã¡ã€ã«ã®æçµåœ¢åŒïŒ
import vkapi import os import importlib from command_system import command_list def load_modules():
ãããã®æºåãã§ããŸããïŒ ããã§ããããã®ããŒã¹ãäœæãããã®ããã®æ°ããããŒã ã远å ããæ¹æ³ãããããŸããã
ãããã¯5èšäºã®æ®ãã®éšåã§ã¯ãå¿
èŠã ãšæã1ã€ã®æ¹åã«ã€ããŠèª¬æããŸãã ãã ãããããã¯ãããªãã§åäœããŸãã
ããããã®ã³ãã³ãèªèãŠãŒã¶ãŒã1ã€ã®æåãééããå Žåãæãé¡äŒŒããã³ãã³ãã念é ã«çœ®ããŠããå¯èœæ§ãé«ãã§ãã ãããã£ãŠããããããŸã çããåºãããç§ã¯ããªããçè§£ããŠããŸããããšèšããªãã£ããããã§ãããã
ããããã®èªèã®ããã«ãDamerau-Levenshteinè·é¢ã䜿çšããŸãã æåãåé€ãæ¿å
¥ã眮æãç§»åããæäœããããè¡ããå¥ã®è¡ã«ç§»åã§ããåæ°ã瀺ããŠããŸãã
ãã®è·é¢ãèŠã€ããããã®ã¢ã«ãŽãªãºã ã¯ãäŸãã°ãŠã£ãããã£ã¢ã§èª¬æãããŠããŸãã
颿°ãmessageHandler.pyãã¡ã€ã«ã«è¿œå ããŸãã
def damerau_levenshtein_distance(s1, s2): d = {} lenstr1 = len(s1) lenstr2 = len(s2) for i in range(-1, lenstr1 + 1): d[(i, -1)] = i + 1 for j in range(-1, lenstr2 + 1): d[(-1, j)] = j + 1 for i in range(lenstr1): for j in range(lenstr2): if s1[i] == s2[j]: cost = 0 else: cost = 1 d[(i, j)] = min( d[(i - 1, j)] + 1,
ãã®è·é¢ãèŠã€ããããã®ã¢ã«ãŽãªãºã ãå®è£
ãããŠãããå¿
èŠã«å¿ããŠå€æŽãŸãã¯æ¹åã§ããŸãã
ãããã®è¡ã«ãããšã1ã€ãå¥ã®å€ã«å€æããããã®æäœã®æ°ãäžããããŸãã get_answerã¡ãœããã倿ŽããŸãã
def get_answer(body): message = ", . '', " attachment = '' distance = len(body) command = None key = '' for c in command_list: for k in c.keys: d = damerau_levenshtein_distance(body, k) if d < distance: distance = d command = c key = k if distance == 0: message, attachment = c.process() return message, attachment if distance < len(body)*0.4: message, attachment = command.process() message = ' "%s"\n\n' % key + message return message, attachment
ãã®é¢æ°ã§ã¯ãã¡ãã»ãŒãžãšåããŒã®è·é¢ãèšç®ããŸãã äžèŽãäžæ£ç¢ºãªå Žåãéä¿¡ãããåã³ãã³ããããããã©ã®ããã«èªèããããèšè¿°ããŸãã è·é¢ãéä¿¡ãããã¡ãã»ãŒãžã®é·ãã®40ïŒ
ãè¶
ããå ŽåããŠãŒã¶ãŒã誀解ããããŠãããšèŠãªããããã©ã«ãã¡ãã»ãŒãžãè¿ããŸãã
ããã ãã§ããïŒãã®èšäºãæžããŠããæç¹ã§ïŒåäœããã³ãŒãã¯
githubã«æçš¿ãããŠããŸãã
VKçšã®ç¬èªã®ããããäœæããããšã«æ±ºããå Žåããã®èšäºãããªãã®äººçãå°ã楜ã«ããããšãé¡ã£ãŠããŸãã