📜 ⬆️ ⬇️

Using VK Streaming API with Telegram Alert


Vkontakte has launched the Streaming API, a tool for obtaining public data from VKontakte on specified keywords.

VC itself sends a new suitable content as it appears. In this way, you can get records of interest without joining dozens of groups immediately after publication.

Let's write a bot for the telegram with the notification of records in VK.

Get the news


First you need to create an application in the VC and take the service key from the settings
')


For data transfer protocol is used WebSocket. We use the websocket library.

import websocket 

Before connecting, use the streaming.getServerUrl method. As a result, the method returns the URL for further requests in the endpoint (string) field and the access key in the key (string) field.

We get the URL and key

 def get_streaming_server_key(token): request_url = "https://api.vk.com/method/streaming.getServerUrl?access_token={}&v=5.64".format(token) r = requests.get(request_url) data = r.json() return {"server":data["response"]["endpoint"],"key":data["response"]["key"]} 

We listen to the server

 def listen_stream(): websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://{}/stream?key={} ".format(stream["server"], stream["key"]), on_message=on_message, on_error=on_error, on_close=on_close) ws.on_open = on_open ws.run_forever() def on_message(ws, message): print(">>>> receive message:", message) def on_error(ws, error): print(">>>> error thead:",error) def on_close(ws): print(">>>> close thead") def on_open(ws): print(">>>> open thead") stream = get_streaming_server_key(my_servise_token) listen_stream() 

After launch, the following should appear in the console
- request header - GET / stream? Key = e6290ba04916a314c398c331f60224d012fabeb1 HTTP / 1.1
Upgrade: websocket
Connection: Upgrade
Host: streaming.vk.com
Origin: streaming.vk.com
Sec-WebSocket-Key: vG40A5bwbPaVBS + DLBOyog ==
Sec-WebSocket-Version: 13
- - response header - HTTP / 1.1 101 Switching Protocols
Server: Apache
Date: Thu, 20 Jul 2017 22:06:55 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: QRJNqD8K7vWNMcQesYKo64q8MfA =
- >>>> open thead
send: b "\ x8a \ x80d ') \ x90"
send: b '\ x8a \ x80 \ xfcmp \ xe6'
send: b '\ x8a \ x80s \ x9f6 {'
send: b '\ x8a \ x80 \ xc9 \ xfa. \ xd4'
send: b '\ x8a \ x80fU <\ xed'
send: b '\ x8a \ x80 \ xc6Ji \ x19'
send: b '\ x8a \ x80 \ xd2D \ x08!'

Working with rules


Add

HTTP POST method
Content Type application / json
Request URL https: // {endpoint} / rules? Key = {key}

 def set_my_rules(value): rule_params = {"rule":{"value":value,"tag":'tag_'+str(random.randint(11111, 99999))}} headers = {'content-type': 'application/json'} r = requests.post("https://{}/rules?key={}".format(stream["server"], stream["key"]), data=json.dumps(rule_params), headers=headers) data = r.json() return data['code'] == 200 

Getting

HTTP GET method
Request URL https: // {endpoint} / rules? Key = {key}

 def get_my_rules(): r = requests.get("https://{}/rules?key={}".format(stream["server"], stream["key"])) data = r.json() if data['code'] != 200: return False return data['rules'] 

Deletion

HTTP DELETE method
Content Type application / json
Request URL https: // {endpoint} / rules? Key = {key}

 def del_my_rules(tag): headers = {'content-type': 'application/json'} rule_params = {"tag":tag} r = requests.delete("https://{}/rules?key={}".format(stream["server"], stream["key"]), data=json.dumps(rule_params), headers=headers) data = r.json() return data['code'] == 200 

Trying to get the news.

 stream = get_streaming_server_key(my_servise_token) set_my_rules('') listen_stream() 

About the following should appear in the console
send: b '\ x8a \ x80 \ xc9 \ xfa. \ xd4'
send: b '\ x8a \ x80fU <\ xed'
send: b '\ x8a \ x80 \ xc6Ji \ x19'
send: b '\ x8a \ x80 \ xd2D \ x08!'
{"Code": 100, "event": {"event_type": "post", "event_id": {"post_owner_id": - 35708825, "post_id": 4560}, "event_url": " vk.com/wall- 35708825_4560 "," text ":" vk.com/small.dolly
Lost the cat. In Elektrostal on Zagonova Street in the area of ​​16 schools. A young boy, 2 years neutered. Normal gray with stripes. There is a white spot on the chin and breast. A large cat about 7 kg. He disappeared on June 27th. If someone saw him please inform 89250506596 or 89251527466. We love him very much and want him to return home ”,“ creation_time ”: 1498942995,“ tags ”: [“ test_cats ”],“ author ”: {“ id ”: - 35708825}}} - our news

Telegram


We use the library "telebot".

 import telebot TELEGRAM_API_TOKEN = '3277332...' #      bot = telebot.TeleBot(TELEGRAM_API_TOKEN) 

Bot start


 def _send(msg): markup = types.ReplyKeyboardMarkup(row_width=1, resize_keyboard=True) markup.add(' ', '  ', '') msg = bot.send_message(chatID, msg, reply_markup=markup) #      bot.register_next_step_handler(msg, process_step) #      #   'help', 'start' @bot.message_handler(commands=['help', 'start']) def send_welcome(message): global chatID chatID = message.chat.id hello_test = ', %s!    VK Streaming API!' % message.from_user.first_name _send(hello_test) #     def process_step(message): if message.text == ' ': _send(get_rules_list()) if message.text == '  ': _send(clear_rules_list()) if message.text == '': msg = bot.send_message(chatID, " ?") bot.register_next_step_handler(msg, add_rule_handler) 

To add



 if message.text == '': msg = bot.send_message(chatID, " ?") bot.register_next_step_handler(msg, add_rule_handler) ..... def add_rule_handler(message): new_rule = set_my_rules(message.text) if new_rule: _send("Successful") else: logging.debug("Error add rules") _send("Error") 

My interests

 def get_rules_list(): rules = get_my_rules() if rules: return "\n".join([str(rule['value']) for rule in rules]) else: logging.debug("Error get rules list") return 'Error' 

Clear interest list

 def clear_rules_list(): rules = get_my_rules() if rules: for rule in rules: del_my_rules(rule['tag']) return "Successful" else: logging.debug("Error clear rules list") return 'Error' 

Sending news

 def on_message(ws, message): print(">>>> receive message:", message) message = json.loads(message) if not message['code']: return if not message['event']['event_type'] or message['event']['event_type'] != 'post': return # ,      post = message['event']['event_type'] +"\n"+message['event']['text'].replace("<br>", "\n") +"\n\n"+ message['event']['event_url'] _send_post(post) 

Run it all together


For correct operation, the sockets need to be run in a separate thread.

 def listen_stream(): websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://{}/stream?key={} ".format(stream["server"], stream["key"]), on_message=on_message, on_error=on_error, on_close=on_close) ws.on_open = on_open #ws.run_forever() wst = threading.Thread(target=ws.run_forever) wst.daemon = True wst.start() 

Run

 if __name__ == '__main__': try: chatID = 0 stream = get_streaming_server_key(my_servise_token) listen_stream() bot.polling(none_stop=True) except Exception as e: logging.exception("error start") 





That's all, thank you.

Full script code
Streaming API docs
Telegram API docs
Python websocket-client
Python TelegramBotAPI

Source: https://habr.com/ru/post/333942/


All Articles