Created
June 2, 2018 10:01
-
-
Save iliakonnov/f1576523f726100ecd873e4d1a6ea21b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://oauth.vk.com/authorize?client_id=6263031&display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=photos,messages,offline,docs&response_type=token | |
vkToken = токен вконтакте | |
userId = айди пользователя вк # ID бота | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import privateConf | |
import requests | |
import re | |
API = 'ключ апи яндекс SpeechKit' | |
class TTSBot(object): | |
def _getLongpollServer(self): | |
serverInfo = requests.get( | |
'https://api.vk.com/method/messages.getLongPollServer', | |
params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'lp_version': 2, | |
'need_pts': 0 | |
} | |
).json() | |
return { | |
'server': serverInfo['response']['server'], | |
'ts': serverInfo['response']['ts'], | |
'key': serverInfo['response']['key'] | |
} | |
def _getLongpoll(self, keyOutdated, tsOutdated, ts, server, key): | |
if keyOutdated or tsOutdated: # Подключение к Longpoll | |
serverInfo = self._getLongpollServer() | |
if keyOutdated: | |
key = serverInfo['key'] | |
keyOutdated = False | |
if tsOutdated: | |
ts = serverInfo['ts'] | |
tsOutdated = False | |
server = serverInfo['server'] | |
response = requests.get( # Запрос к Longpoll | |
'https://' + server, | |
params={ | |
'act': 'a_check', | |
'key': key, | |
'ts': ts, | |
'mode': 0, | |
'wait': 25, | |
'version': 2, | |
} | |
).json() | |
# Если что-то пошло не так (https://vk.com/dev/using_longpoll?f=2.%20Формат%20ответа) | |
if 'failed' in response: | |
if response['failed'] == 1: | |
ts = response['ts'] | |
elif response['failed'] == 2: | |
keyOutdated = True | |
elif response['failed'] == 3: | |
keyOutdated = True | |
tsOutdated = True | |
return (keyOutdated, tsOutdated, ts, server, key), None | |
ts = response['ts'] | |
return (keyOutdated, tsOutdated, ts, server, key), response | |
def main(self): | |
longpollParams = (True, True, None, None, None) | |
while True: | |
longpollParams, response = self._getLongpoll(*longpollParams) | |
if response is None: | |
continue | |
for update in response['updates']: | |
# Не новое сообщение | |
if update[0] != 4: | |
continue | |
# Не все нужные поля (https://vk.cc/7myKAm) | |
if len(update) < 5: | |
continue | |
msgId = update[1] | |
chatId = update[3] | |
text = update[5] | |
messageInfo = requests.get( | |
'https://api.vk.com/method/messages.getById', | |
params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'message_ids': msgId | |
} | |
).json() | |
if '/stt' in text: | |
self.stt(messageInfo, chatId) | |
elif '/tts' in text: | |
self.tts(messageInfo, chatId) | |
@staticmethod | |
def stt(msgInfo, chatId): | |
print(msgInfo, chatId) | |
msg = msgInfo['response']['items'][0] | |
if "fwd_messages" not in msg: | |
return | |
if "attachments" not in msg["fwd_messages"][0]: | |
return | |
if "/stt" not in msg["body"]: | |
return | |
attachments = msg["fwd_messages"][0]["attachments"] | |
if not attachments: | |
return | |
url = None | |
for i in attachments: | |
if i["type"] == "doc": | |
if "preview" in i["doc"]: | |
if "audio_msg" in i["doc"]["preview"]: | |
url = i["doc"]["preview"]["audio_msg"]["link_ogg"] | |
if url is None: | |
return | |
if msg['out'] != 1: | |
return | |
voice = requests.get(url, stream=True) | |
recognize = requests.post( | |
'http://asr.yandex.net/asr_xml', | |
params={ | |
'uuid': uuid апи яндекса, | |
'key': API, | |
'topic': 'queries', | |
'lang': 'ru-RU', | |
'disableAntimat': True | |
}, | |
headers={'Content-Type': 'audio/ogg;codecs=opus'}, | |
data=voice | |
) | |
print(recognize.text) | |
result = re.findall(r'<variant confidence=".*?">(.*?)</variant>', recognize.text) | |
resMsg = 'Распознать не удалось =(' | |
if result: | |
if len(result) == 1: | |
resMsg = result[0] | |
else: | |
resMsg = '{' + '},\n\n{'.join(result) + '}' | |
resMsgSplitted = [resMsg[i:i + 4096] for i in range(0, len(resMsg), 4096)] | |
for i in resMsgSplitted: | |
print(i) | |
print(requests.post('https://api.vk.com/method/messages.send', data={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'peer_id': chatId, | |
'message': i, | |
'forward_messages': msg['id'] | |
}).text) | |
print('Done!') | |
@staticmethod | |
def tts(msgInfo, chatId): | |
print(msgInfo, chatId) | |
msg = msgInfo['response']['items'][0] | |
print('Checking') | |
if "/tts" not in msg["body"]: | |
return | |
if msg['out'] != 1: | |
return | |
print('Ok') | |
print('Synthesing ("{}")'.format(msg["body"].replace("/tts", ""))) | |
voice = requests.get( | |
'https://tts.voicetech.yandex.net/generate', | |
params={ | |
'key': API, | |
'text': msg["body"].replace("/tts", ""), | |
'format': 'opus', | |
'lang': 'ru-RU', | |
'speaker': 'ermil' | |
}, | |
stream=True | |
) | |
print('Prepairing') | |
uploadUrl = requests.get( | |
'https://api.vk.com/method/docs.getUploadServer', | |
params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'type': 'audio_message' | |
} | |
).json()['response']['upload_url'] | |
print('Uploading ({})'.format(uploadUrl)) | |
fileParams = requests.post( | |
uploadUrl, | |
files={'file': ('voice.ogg', voice.raw)} | |
).json() | |
print('Saving ({})'.format(fileParams)) | |
fileId = requests.post( | |
'https://api.vk.com/method/docs.save', | |
params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
**fileParams | |
} | |
).json()['response'][0] | |
print('Sending ({})'.format(fileId)) | |
print(requests.get('https://api.vk.com/method/messages.send', params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'peer_id': chatId, | |
'attachment': 'doc{oid}_{mid}'.format(oid=fileId['owner_id'], mid=fileId['id']) | |
}).json()) | |
print('Deleting original') | |
print(requests.get('https://api.vk.com/method/messages.delete', params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'message_ids': msg['id'], | |
'delete_for_all': 1 | |
}).json()) | |
if __name__ == "__main__": | |
''' | |
TTSBot.doWork(requests.get( | |
'https://api.vk.com/method/messages.getById', | |
params={ | |
'v': '5.69', | |
'access_token': privateConf.vkToken, | |
'message_ids': 98394 | |
} | |
).json(), privateConf.chatId) | |
''' | |
TTSBot().main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment