├── .gitattributes ├── .gitignore ├── PyVKBot.py ├── README.md ├── config.ini └── images └── attach.jpg /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | lib/ 17 | lib64/ 18 | parts/ 19 | sdist/ 20 | var/ 21 | *.egg-info/ 22 | .installed.cfg 23 | *.egg 24 | 25 | # PyInstaller 26 | # Usually these files are written by a python script from a template 27 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 28 | *.manifest 29 | *.spec 30 | 31 | # Installer logs 32 | pip-log.txt 33 | pip-delete-this-directory.txt 34 | 35 | # Unit test / coverage reports 36 | htmlcov/ 37 | .tox/ 38 | .coverage 39 | .cache 40 | nosetests.xml 41 | coverage.xml 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | 56 | # ========================= 57 | # Operating System Files 58 | # ========================= 59 | 60 | # OSX 61 | # ========================= 62 | 63 | .DS_Store 64 | .AppleDouble 65 | .LSOverride 66 | 67 | # Thumbnails 68 | ._* 69 | 70 | # Files that might appear on external disk 71 | .Spotlight-V100 72 | .Trashes 73 | 74 | # Directories potentially created on remote AFP share 75 | .AppleDB 76 | .AppleDesktop 77 | Network Trash Folder 78 | Temporary Items 79 | .apdisk 80 | 81 | # Windows 82 | # ========================= 83 | 84 | # Windows image file caches 85 | Thumbs.db 86 | ehthumbs.db 87 | 88 | # Folder config file 89 | Desktop.ini 90 | 91 | # Recycle Bin used on file shares 92 | $RECYCLE.BIN/ 93 | 94 | # Windows Installer files 95 | *.cab 96 | *.msi 97 | *.msm 98 | *.msp 99 | 100 | # Windows shortcuts 101 | *.lnk 102 | -------------------------------------------------------------------------------- /PyVKBot.py: -------------------------------------------------------------------------------- 1 | import vk 2 | import re 3 | import sys 4 | import time 5 | import json 6 | import socket 7 | import random 8 | import requests 9 | import linecache 10 | import urllib.parse 11 | import configparser 12 | import urllib.request 13 | 14 | 15 | def printexception(botvkid): 16 | exc_type, exc_obj, tb = sys.exc_info() 17 | f = tb.tb_frame 18 | lineno = tb.tb_lineno 19 | filename = f.f_code.co_filename 20 | linecache.checkcache(filename) 21 | line = linecache.getline(filename, lineno, f.f_globals) 22 | print('EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj)) 23 | requests.post("http://bot.mew.su/service/listenerror.php", 24 | data={'botid': botvkid, 25 | 'text': 'LINE {} "{}"): {}'.format(lineno, 26 | line.strip(), 27 | exc_obj)}, 28 | verify=False) 29 | 30 | 31 | version = '0.0.3.1' 32 | 33 | # Берем данные из конфига 34 | config = configparser.ConfigParser() 35 | config.read('config.ini') 36 | 37 | # Inputs and shit 38 | if (config['main']['token']) and (config['main']['botid']): 39 | print("Прошлые данные были восстановлены. Если желаете их изменить - отредактируйте config.ini") 40 | at = config['main']['token'] 41 | bid = config['main']['botid'] 42 | elif (config['main']['token'] == '') and (config['main']['botid'] == ''): 43 | at = input("Введите свой ACCESS_TOKEN (о том как его получить - http://bot.mew.su):") 44 | bid = input("Введите ID своего бота с сайта iii.ru (или оставьте пустым для использования бота VIU-PIU):") 45 | # Пишем в файл 46 | config.set('main', 'token', at) 47 | config.set('main', 'botid', bid) 48 | elif config['main']['token'] == '': 49 | at = input("Введите свой ACCESS_TOKEN (о том как его получить - http://bot.mew.su):") 50 | bid = config['main']['botid'] 51 | # Пишем в файл 52 | config.set('main', 'token', at) 53 | elif config['main']['botid'] == '': 54 | at = config['main']['token'] 55 | bid = input("Введите ID своего бота с сайта iii.ru (или оставьте пустым для использования бота VIU-PIU):") 56 | 57 | if bid == '': 58 | bid = '[DEFAULT]' 59 | # Пишем в файл 60 | config.set('main', 'botid', bid) 61 | else: 62 | at = config['main']['token'] 63 | bid = config['main']['botid'] 64 | 65 | with open('config.ini', 'w') as configfile: 66 | config.write(configfile) 67 | 68 | vkapi = vk.API(access_token=at) 69 | jsn = vkapi.users.get().pop() 70 | firstname = str(jsn['first_name']) 71 | 72 | # TEST AREA 73 | 74 | # 75 | 76 | i = 0 77 | while True: # Infinite loop 78 | try: 79 | if i == 0: 80 | # TODO: Проверка старых неотвеченых сообщений 81 | longpoll = vkapi.messages.getLongPollServer(need_pts=1, use_ssl=0) 82 | ts1 = longpoll['ts'] 83 | pts1 = longpoll['pts'] 84 | print("Принимаем сообщения...") 85 | else: 86 | time.sleep(1) 87 | longpoll = vkapi.messages.getLongPollServer(need_pts=1, use_ssl=0) 88 | ts1 = longpoll['ts'] 89 | pts1 = newpts['new_pts'] 90 | 91 | newpts = vkapi.messages.getLongPollHistory(pts=pts1, ts=ts1) 92 | 93 | if i % 30 == 0: 94 | vkapi.account.setOnline(voip=0) 95 | # print(newpts) 96 | i += 1 97 | 98 | if not len(newpts['profiles']) == 0: 99 | info = newpts['profiles'].pop() 100 | history = newpts['messages']['items'] 101 | 102 | parseitems = json.loads(json.dumps(history)) 103 | jshistory = newpts 104 | 105 | inte = 0 106 | while inte < newpts['messages']['count']: 107 | if 'chat_id' not in parseitems[inte]: 108 | 109 | if parseitems[inte]['out'] == 0: 110 | 111 | # ЭТА ЧАСТЬ ДЛЯ ПЕРСОНАЛЬНОГО ЧАТА 112 | showme = re.search(r'(покажи|как выглядит)\s(.*)?[\?]', parseitems[inte]['body'], 113 | re.IGNORECASE) 114 | kurs = re.search(r'курс', parseitems[inte]['body'], re.IGNORECASE) 115 | infa = re.search(r'(сколько инфа|какая вероятность|какова вероятность)[ того]?\s(.*)', 116 | parseitems[inte]['body'], re.IGNORECASE) 117 | iliili = re.search(r'(.*)\s(или)(.*)?\?', parseitems[inte]['body'], re.IGNORECASE) 118 | 119 | if bool(showme): 120 | text = urllib.parse.quote(showme.group(2)) 121 | jsondata = urllib.request.urlopen( 122 | "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&userip=" 123 | + socket.gethostname() + 124 | "&rsz=1&safe=off&imgsz=large&q=" 125 | + text + 126 | "&start=0") 127 | decoded = json.loads(jsondata.readall().decode('utf-8')) 128 | dec = decoded['responseData']['results'].pop() 129 | urllib.request.urlretrieve(dec['unescapedUrl'], "images/attach.jpg") 130 | photoserver = vkapi.photos.getMessagesUploadServer() 131 | photo = {'photo': ('images/attach.jpg', open('images/attach.jpg', 'rb'))} 132 | r = requests.post(photoserver['upload_url'], files=photo, verify=False) 133 | rjs = json.loads(r.text) 134 | attachment = vkapi.photos.saveMessagesPhoto(photo=rjs['photo'], server=rjs['server'], 135 | hash=rjs['hash']).pop() 136 | phrases = (["Я думаю это то, что ты искал по запросу %s", 137 | "Я на правильном пути? %s это картинка ниже?", "Это оно? %s?", 138 | "Я считаю что вот то, что тебе нужно. Запрос: %s", "%s - вот же"]) 139 | random.shuffle(phrases) 140 | 141 | vkapi.messages.setActivity(user_id=info['id'], type="typing") 142 | time.sleep(2) 143 | vkapi.messages.send(message=(phrases.pop() % showme.group(2)), 144 | user_id=parseitems[inte]['user_id'], 145 | attachment="photo" + str(attachment['owner_id']) + "_" + str( 146 | attachment['id'])) # Отвечаем 147 | elif bool(kurs): 148 | jsondata = urllib.request.urlopen( 149 | "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5") 150 | decoded = json.loads(jsondata.readall().decode('utf-8')) 151 | message = decoded[0]['ccy'] + " prodaut za " + decoded[0]['sale'] + ", a " + decoded[1][ 152 | 'ccy'] + " prodaut za " + decoded[1]['sale'] 153 | vkapi.messages.setActivity(user_id=info['id'], type="typing") 154 | time.sleep(2) 155 | vkapi.messages.send(message=message, user_id=parseitems[inte]['user_id']) # Отвечаем 156 | elif bool(infa): 157 | random.seed(infa.group(2)) 158 | percent = random.randint(0, 100) 159 | message = infa.group(2) + " инфа " + str(percent) + "%" 160 | vkapi.messages.send(message=message, user_id=parseitems[inte]['user_id']) # Отвечаем 161 | elif bool(iliili): 162 | iliphrases = (["Ну... Наверное %s", 163 | "Вот честно тебе сказать, я думаю, что все-таки %s", 164 | "Конечно же %s", "%s - абсолютно без сомнений"]) 165 | ilipick = ([iliili.group(1), iliili.group(3)]) 166 | random.shuffle(ilipick) 167 | random.shuffle(iliphrases) 168 | message = iliphrases.pop() % ilipick.pop() 169 | vkapi.messages.send(message=message, user_id=parseitems[inte]['user_id']) # Отвечаем 170 | else: 171 | session = requests.post("http://bot.mew.su/service/getsession.php", 172 | data={'id': str(info['id']), 'botid': bid}, verify=False) 173 | print("=== Сообщение в ЛС =======") 174 | # print(session.text) 175 | resp = requests.post("http://bot.mew.su/service/speak.php", 176 | data={'session': session.text, 'botid': str(jsn['id']), 177 | 'sender': str(info['id']), 'ischat': '0', 178 | 'text': parseitems[inte]['body'], 'version': version}, 179 | verify=False) 180 | print(info['first_name'], info['last_name'], "-", info['id']) 181 | print(parseitems[inte]['body']) 182 | print("Ответ:", resp.text) 183 | print("==========================") 184 | vkapi.messages.setActivity(user_id=info['id'], type="typing") 185 | time.sleep(2) 186 | vkapi.messages.send(message=resp.text, user_id=parseitems[inte]['user_id']) # Отвечаем 187 | else: 188 | if parseitems[inte]['out'] == 0: 189 | 190 | # ЭТА ЧАСТЬ ДЛЯ ЧАТА 191 | namecheck = re.search(r'(' + firstname + '|лорочка|ларисонька|уеба)[\s|,|\.](.*)', 192 | parseitems[inte]['body'], re.IGNORECASE) 193 | if namecheck: 194 | showme = re.search(r'(покажи мне|как выглядит|покажи)\s(.*)', namecheck.group(2), 195 | re.IGNORECASE) 196 | kurs = re.search(r'какой курс', namecheck.group(2), re.IGNORECASE) 197 | infa = re.search(r'(сколько инфа|какая вероятность|какова вероятность)[ того]?\s(.*)', 198 | namecheck.group(2), re.IGNORECASE) 199 | iliili = re.search(r'(.*)\s(или)(.*)?\?', namecheck.group(2), re.IGNORECASE) 200 | 201 | mes = parseitems[inte]['chat_id'] 202 | # TODO: Ловить все запросы к доп. функциям 203 | if bool(namecheck): 204 | if bool(showme): 205 | text = urllib.parse.quote(showme.group(2)) 206 | jsondata = urllib.request.urlopen( 207 | "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&userip=" 208 | + socket.gethostname() + 209 | "&rsz=1&safe=off&imgsz=large&q=" 210 | + text + 211 | "&start=0") 212 | decoded = json.loads(jsondata.readall().decode('utf-8')) 213 | dec = decoded['responseData']['results'].pop() 214 | urllib.request.urlretrieve(dec['unescapedUrl'], "images/attach.jpg") 215 | photoserver = vkapi.photos.getMessagesUploadServer() 216 | photo = {'photo': ('images/attach.jpg', open('images/attach.jpg', 'rb'))} 217 | r = requests.post(photoserver['upload_url'], files=photo, verify=False) 218 | rjs = json.loads(r.text) 219 | attachment = vkapi.photos.saveMessagesPhoto(photo=rjs['photo'], server=rjs['server'], 220 | hash=rjs['hash']).pop() 221 | phrases = (["Я думаю это то, что ты искал по запросу %s", 222 | "Я на правильном пути? %s это картинка ниже?", "Это оно? %s?", 223 | "Я считаю что вот то, что тебе нужно. Запрос: %s", "%s - вот же"]) 224 | random.shuffle(phrases) 225 | vkapi.messages.setActivity(chat_id=str(mes), type="typing") 226 | time.sleep(2) 227 | vkapi.messages.send(message=(phrases.pop() % showme.group(2)), chat_id=mes, 228 | attachment="photo" + str(attachment['owner_id']) + "_" + str( 229 | attachment['id'])) # Отвечаем 230 | elif bool(kurs): 231 | jsondata = urllib.request.urlopen( 232 | "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5") 233 | decoded = json.loads(jsondata.readall().decode('utf-8')) 234 | message = decoded[0]['ccy'] + " prodaut za " + decoded[0]['sale'] + ", a " + decoded[1][ 235 | 'ccy'] + " prodaut za " + decoded[1]['sale'] 236 | vkapi.messages.send(message=message, chat_id=mes) # Отвечаем 237 | elif bool(infa): 238 | random.seed(infa.group(2)) 239 | percent = random.randint(0, 100) 240 | message = infa.group(2), "инфа", str(percent), "%" 241 | vkapi.messages.send(message=message, chat_id=mes) # Отвечаем 242 | elif bool(iliili): 243 | iliphrases = (["Ну... Наверное %s", 244 | "Вот честно тебе сказать, я думаю, что все-таки %s", 245 | "Конечно же %s", "%s - абсолютно без сомнений"]) 246 | ilipick = ([iliili.group(1), iliili.group(3)]) 247 | random.shuffle(ilipick) 248 | random.shuffle(iliphrases) 249 | message = iliphrases.pop() % ilipick.pop() 250 | vkapi.messages.send(message=message, chat_id=mes) # Отвечаем 251 | 252 | else: 253 | session = requests.post("http://bot.mew.su/service/getsession.php", 254 | data={'id': str(info['id']), 'botid': bid}, verify=False) 255 | resp = requests.post("http://bot.mew.su/service/speak.php", 256 | data={'session': session.text, 'botid': str(jsn['id']), 257 | 'sender': str(info['id']), 'ischat': '1', 258 | 'text': namecheck.group(2)}, verify=False) 259 | print("==== Сообщение в ЧАТ =====") 260 | print(info['first_name'], info['last_name'], "-", mes) 261 | print(parseitems[inte]['body']) 262 | print("Ответ:", resp.text) 263 | print("==========================") 264 | vkapi.messages.send(message=resp.text, chat_id=mes) # Отвечаем 265 | time.sleep(1) 266 | inte += 1 # adding to loop 267 | 268 | except: 269 | printexception(jsn['id']) 270 | pass -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyVKBot 2 | 3 | [![Join the chat at https://gitter.im/z00k/PyVKBot](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/z00k/PyVKBot?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | Chat bot for social network VK.COM written on Python 6 | 7 | Вся дополнительная инфомрация доступна в [https://github.com/z00k/PyVKBot/wiki](Wiki) 8 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [main] 2 | token = 3 | botid = 4 | 5 | -------------------------------------------------------------------------------- /images/attach.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi5z/PyVKBot/a088b9b23eb300643ca5629dda081d4daf941e6f/images/attach.jpg --------------------------------------------------------------------------------