Skip to content

Instantly share code, notes, and snippets.

@iliakonnov
Created June 2, 2018 10:01
Show Gist options
  • Save iliakonnov/f1576523f726100ecd873e4d1a6ea21b to your computer and use it in GitHub Desktop.
Save iliakonnov/f1576523f726100ecd873e4d1a6ea21b to your computer and use it in GitHub Desktop.
# 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 бота
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