Всем привет! Сегодня я расскажу вам немного о Пайтоновском API для соц. сети ВКонтакте.
Пост предназначен в первую очередь для школьников начинающих разработчиков, которые хотят сделать простейшее приложение.
Поскольку я сама не особо сильна в Пайтоне, о различных аспектах этого прекраснейшего языка (ООП, функциональное программирование и т.д.) я умолчу.
Давайте начнём.
Получение Python
Пайтоновскую виртуальную машину под винду вместе с небогатой средой разработки IDLE можно скачать здесь.
Не советую качать версию 3.5, ибо под ней некоторые модули (ещё не обновившиеся) могут не работать.
И если вы только начинаете знакомиться с этим языком, не советую также качать версии ниже третьей.
Если вы юзаете UNIX то должны сами знать где гуглить. Под Убунтой просто обновитесь (типа sudo apt-get update).
Также рекомендую поставить pip под вашу версию языка.
Получение модуля
В командной строке или терминале введите pip install vk (pip3 install vk)
Или можете воспользоваться этой ссылкой.
Также присутствует документация с примерами.
Что надо сделать ВКонтакте?
Авторизуемся ВКонтакте и заходим на страничку разработчиков.
Тыкаем там на кнопку "Создать приложение"
Дополнительно можно также загрузить свою иконку, поменять имя и т.д.
Авторизация
Теперь самое интересное. Нужно получить токен авторизации.
В принципе, модуль vk вполне работает и без него. Некоторые методы могут быть вызваны вообще без авторизации на сайте. Кроме того, вы можете в самом приложении авторизоваться через свой логин и пароль (как показано в этом примере).
В принципе, говоря по-хорошему, оба способа небезопасны. Так или иначе разработчик модуля может получить доступ к вашим данным -- токену или паре логин-пароль.
Прикол в том, что токен авторизации выдаётся конкретному приложению с конкретными правами доступа и конкретным ID. Т.е. в принципе, разрабу модуля он бесполезен.
А вот ваши данные авторизации могут быть вполне полезны. Потому я считаю что лучше юзать токен. По крайней мере, если у вас возникнут какие-то подозрения, не придётся менять пароль и засвеченную почту (номер телефона).
Ещё одним плюсом токена для параноиков является то, что он может быть выдан на определённый срок. В общем, юзайте лучше токены. Это немного сложнее, но безопаснее.
Как получить токен авторизации для Standalone-приложения описано здесь. Вам (или пользователю приложения) нужно перейти по ссылке определённого вида, авторизоваться ВКонтакте (если вы это ещё не сделали), в открывшемся фрейме внимательно прочесть какие разрешения запрашивает приложение, выдать приложению доступ, и из перенаправленной ссылки вытащить токен авторизации.
Вот пример ссылки:
https://oauth.vk.com/authorize?client_id={ID приложения}&display=page&redirect_uri=https://oauth.vk.com/blank.html&scope=friends,photos ,audio,video,docs,notes,pages,status,wall,groups,messages,notifications,offline&response_type=token
Это запрос к сайту на выдачу токена авторизации для нашего Standalone-приложения. Разберём подробнее.
client_id={ID приложения} -- вместо {ID приложения} подставьте ID вашего приложения.
redirect_uri=https://oauth.vk.com/blank.html -- в случае Standalone-приложений ВКонтакте обязывает использовать именно такой адрес перенаправления.
scope=friends,photos ,audio,video,docs,notes,pages,status,wall,groups,messages,notifications,offline -- самое интересное. Это список запрашиваемых разрешений. Полный список возможных разрешений можно найти здесь.
Будьте крайне внимательны при составлении этого списка. Фактически, он определяет все возможности, доступные обладателю токена. Особо обратите внимание на последний параметр offline -- при его использовании будет выдан бессрочный токен авторизации.
После того, как юзер даст приложению доступ со страницы ВК, его перебросит на пустую страницу с URL вида
https://oauth.vk.com/blank.html#access_token={токен авторизации}
С некоторыми дополнительными параметрами. Для авторизации приложению необходим токен, стоящий в параметре access_token. Вам необходимо его вытащить.
После этого необходимо авторизоваться в самой программе. На сайте разработчика модуля приводится такой простой пример:
import vk
session = vk.Session(access_token='{токен авторизации}')
api = vk.API(session)
После этого у объекта api вы можете вызывать все методы, перечисленные на этой странице.
К примеру, написание первого поста:
api.wall.post(message = 'Hello, World!')
Приведёт к появлению на вашей стене текстового поста.
Лирическое отступление относительно токенов и добросовестности
Как видите, процедура получения токена довольно проста, а его наличие даёт практически неограниченный контроль над страницей пользователя (практически такой же, как и с веб-интерфейса).
Естественно, это накладывает определённые требования к добросовестности пользователей. Любой из вас может обмануть доверчивого друга или соседа, прислав ему ссылку и попросив скопировать ответ (хотя на странице-редиректе и стоит напоминание о том, что ссылку с токеном нельзя никому присылать) либо получив на короткое время доступ к незапароленному компьютеру.
Притом после получения токена с неограниченным сроком годности, его можно использовать для скрытого чтения чужих сообщений, накрутки лайков, общения в соцсети от чужого имени и прочих противоправных действий.
Я искренне надеюсь что вы не станете так делать.
Продолжим.
Написание простейшей программы с использованием API
Давайте напишем какую-нибудь полезную программу, использующую API ВКонтакте.
Вот пример такой программы, предназначенной для своевременного получения обновлений сообщений (к сожалению, после сохранения поста всё форматирование пропадает, потому вместо символов табуляции я буду использовать escape-последовательность \t):
import vk
import time
import SendEmail
def searchForUser(user_list, ID):
\tfor user in user_list:
\t\tif type(user) is int:
\t\t\tcontinue
\t\tif user['uid'] == ID:
\t\t\treturn user['first_name'] + ' ' + user['last_name'] + '\n'
def checkMessages(message_list):
\tIDS = []
\tfor message in message_list:
\t\tif type(message) is int:
\t\t\tcontinue
\t\tif message['read_state'] == 0:
\t\t\tif 'chat_id' not in message:
\t\t\t\tIDS.append(str(message['uid']))
\tuser_list = api.users.get(user_ids = ','.join(IDS))
\ttext = ''
\tfor message in message_list:
\t\tif type(message) is int:
\t\t\tcontinue
\t\tif message['read_state'] == 0:
\t\t\tif 'chat_id' not in message:
\t\t\t\ttext = text + searchForUser(user_list, message['uid']) + message['body'] + '\n'
\t\t\telse:
\t\t\t\ttext = text + 'Сообщение из чата\n' + message['body'] + '\n'
\tprint(text)
\treturn text
session = vk.Session(access_token = '{токен авторизации}')
api = vk.API(session)
while True:
\tmessage = api.messages.get(time_offset = 0)
\tif len(message) != 1 and message[1]['read_state'] == 0:
\t\tSendEmail.sendEMail(checkMessages(message))
\telse:
\t\tprint('No new messages!')
\t\tSendEmail.sendEMail('No new messages!')
\t\ttime.sleep(600)
Разберём построчно что делает этот код.
В первых трёх строчках мы импортируем необходимые нам модули. Модуль time используется для того, чтобы отправлять процесс в сон. Модуль SendEmail -- это пользовательский модуль, предназначенный для отправки сообщений на определённый ящик.
Функция searchForUser(user_list, ID) ищет пользователя по его ID в списке user_list объектов user. Когда она его находит, то возвращает строку с именем и фамилией юзера. Проверка на тип сделана т.к. API ВКонтакте частенько возвращает первым элементом списка объектов длину этого списка.
Фунция checkMessages(message_list) просматривает список сообщений (опять же, пропуская элемент списка, содержащий число сообщений в списке) и формирует список из ID тех юзеров, сообщения которых ещё не прочитаны. Далее по этому списку ID у API запрашивается список юзеров. И наконец потом формируется единая строка, в которой через строчку указан отправитель (полученный функцией searchForUser(user_list, ID)) и текст его сообщения.
Если сообщение был отправлено из чата, то это дополнительно указывается.
И наконец основная часть программы. Сначала мы авторизуемся (токен можно записать прямо в Пайтоновский файл либо читать из текстового файла), затем в бесконечном цикле делаем следующее:
1) Проверяем, есть ли сообщения и прочтено ли последнее сообщение
2) Если есть, то вытаскиваем функцией checkMessages(message_list) строку вида
Юзер Юзеров
Сообщение от юзера 1
Юзер Юзеров
Сообщение от юзера 2
Другой Юзер Юзеров
Сообщение от юзера 1
И отправляем её себе на Email функцией SendEmail.sendEMail(text). Вместо отправки на почту можно выводить сообщение в консоль или записывать в файл.
2а) Если сообщений не было, то отправляем уведомление об этом (его цель, в основном, дать вам понять что программа не вылетела из-за какого-нибудь эксепшена).
3) Вызовом time.sleep(600) ждём ещё 10 минут.
Естественно, эта простенькая программа не является верхом совершенства. Изредка вызов API может приводить к поднятию эксепшена, что в данном случае попросту валит всю программу. Кроме того, приложение никак не запоминает что оно уже отправило вам уведомление о неких сообщениях, т.е. если вы не прочтёте новые сообщения, оно вас снова уведомит. И снова. И так до тех пор, пока в очередном вызове не вылетит эксепшен.
Если вы планируете писать своё приложение, обращайте также внимание на ограничения по частоте запросов к API (в конце страницы).
Всем спасибо за внимание, до новых встреч!