Когда ищешь long-polling в Skype API
Год назад Microsoft представила платформу для создания ботов под Skype. Платформа предоставляет удобный формат сообщений, можно отправлять карточки с кнопками, как в телеграмме, одним словом, выглядит все очень круто.
Недавно мне потребовалось написать бота для Skype. И несмотря на то, что тема подымалась на хабре ( например), я столкнулся с некоторыми сложностями, мне очень не хватало step-by-step гайда по работе с REST API.
На самом деле, бот для скайпа пишется довольно быстро, если знать о подводных камнях и знать где смотреть документацию. Основная идея, которую мне пришлось усвоить: Нет веб поллинга. Если Телеграмм на выбор предоставляет лонг-поллинг и вебхуки, то скайп обходится только вебхуками. Из этого вытекают следующие проблемы – общение с серверами скайпа происходят только по https, и только при наличии валидного сертификата. Придется находить доменное имя,
Как это сделать?
Итак, с самого начала. Допустим, что у нас есть голый
Теперь, когда все подготовлено к работе, начнем писать бота.
1. Многое описано в этой статье, нам нужны два момента: Вот здесь создаем свое приложение, и здесь регистрируем бота. При регистрации нужно указать endpoint, куда Microsoft будет отсылать сообщения. Он указывается в таком же виде, как и пишется в браузере. После endpoint’a можно указать порт, тогда он будет выглядеть вот так: “https://endpoint_url:port” После регистрации нужно будет сгенерировать пароль, и это все, что нам нужно было получить на данный момент. На данный момент у нас должен быть: application_id ( с которым мы регистрировали бота ) и пароль ( который мы получили только что ).
2. Вы еще не забыли про вебхуки? Настала пора подымать сервер, для которого мы ранее получали сертификаты. На питоне для этого подойдет фласк. Первым делом, определим глобальные переменные ( не очень красивое решение, но очень простое ), и начнем в отдельном потоке автоматически получать и обновлять токен:
FLASK = Flask(__name__)
APP_ID = ''
PASSWORD = '' # секрет от бота
context =('fullchain.pem', 'privkey.pem') # относительные или абсолютные пути к файлам, которые сгенерировал certbot
TOKEN = {}
def get_token():
global TOKEN
url = 'https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token'
payload = {'grant_type': 'client_credentials',
'client_id': APP_ID,
'client_secret': PASSWORD,
'scope': 'https://api.botframework.com/.default',
}
token = requests.post('https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token', data=payload).content
TOKEN = json.loads(str(token)[2:-1])
return json.loads(str(token)[2:-1])
def send_token_to_connector(token):
url = 'https://groupme.botframework.com/v3/conversations'
headers = {'Authorization': 'Bearer ' + token}
r = requests.post(url, headers=headers)
return r
def get_and_verify_token():
global TOKEN
while True:
get_token()
send_token_to_connector(TOKEN['access_token'])
time.sleep(TOKEN['expires_in']*0.9)
3. Напишем функцию-обработчик входящих сообщений:
@FLASK.route('/', methods=['GET', 'POST'])
def handle():
data = request.get_json()
talk_id = data['conversation']['id']
msg = {
"type": "message",
"from": {
"id": APP_ID,
"name": "habraechobot"
},
"conversation": {
"id": talk_id,
},
"text": data['text'],
}
url = data['serviceUrl'] + '/v3/conversations/{}/activities/'.format(data['conversation']['id'])
headers = {'Authorization': 'Bearer ' + TOKEN['access_token'],
'content-type': 'application/json; charset=utf8'}
r = requests.post(url, headers=headers, data=json.dumps(msg))
return 'success'
4. И, наконец, запустим сервер:
if __name__ == '__main__':
thread = Thread( target=get_and_verify_token )
thread.start()
FLASK.run(host='0.0.0.0', port=8080, ssl_context=context)
Вот и все – полный код бота можно взять отсюда, надеюсь, моя статья была полезна и сэкономит кому-то время и силы.
Автор: Crait