Найти в Дзене
DGO шпаргалка

С телеграмма во вконтакте. Управление досветкой сервисом из белого списка.

Всем привет! Уже давно я писал о том, как сделал подсветку для комнатных цветов, которые жена перевезла ко мне в мастерскую. Подоконники в квартире категорически закончились. Так вот. После многих месяцев аптайма электричество, таки, вырубили на несколько часов. Но я об этом не узнал. Интернет в мастерской с 3g модема, а интернет, нынче доступен не весь, мягко говоря. Вот и мой телеграм бот не нашёл способа донести мне прискорбные новости о том, что время сбилось, рабочая программа больше не выполняется и из света остался только светодиод на блоке питания. Но дома в праздники мне не сиделось и я пошёл в мастерскую лепить АЦП, печатать всякое на 3д принтере и всякое такое. И я решил не ждать, пока что-то изменится и быстренько переехать на бота вконтакте. Вконтакте позволяет делать ботов и взаимодействовать с ними через свой API. Для этого нужно раздобыть ключ доступа - токен. Он может давать доступ к аккаунту, что, например, используют неофициальные клиенты, например Kate mobile( по
Оглавление

Всем привет! Уже давно я писал о том, как сделал подсветку для комнатных цветов, которые жена перевезла ко мне в мастерскую. Подоконники в квартире категорически закончились.

Так вот. После многих месяцев аптайма электричество, таки, вырубили на несколько часов. Но я об этом не узнал. Интернет в мастерской с 3g модема, а интернет, нынче доступен не весь, мягко говоря. Вот и мой телеграм бот не нашёл способа донести мне прискорбные новости о том, что время сбилось, рабочая программа больше не выполняется и из света остался только светодиод на блоке питания.

Довольно костыльная система из пары плат, которые делал давным-давно для подсветки зеркала.
Довольно костыльная система из пары плат, которые делал давным-давно для подсветки зеркала.

Но дома в праздники мне не сиделось и я пошёл в мастерскую лепить АЦП, печатать всякое на 3д принтере и всякое такое. И я решил не ждать, пока что-то изменится и быстренько переехать на бота вконтакте.

Немного о ботах и ключах.

Вконтакте позволяет делать ботов и взаимодействовать с ними через свой API. Для этого нужно раздобыть ключ доступа - токен. Он может давать доступ к аккаунту, что, например, используют неофициальные клиенты, например Kate mobile( почти что официальный и мой любимый). Но это не особенно безопасно - мы даем доступ практически ко всему, что есть на аккаунте. Или можно использовать токен группы вконтакте. Это значительно лучше с точки зрения безопасности. Мы сможем переписываться с ботом не как с самим собой, а как с сообщениями группы.

Как получить токен?

  1. Создайте группу ВКонтакте - это можно сделать по кнопке справа на странице "сообщества"
  2. Управление →Настойки →дополнительно→ Работа с API → Создать ключ
  3. Отметьте права: messages, manage
  4. Скопируйте токен (начинается с vk1.a.)
  5. Узнайте Ваш VK ID - для того, чтобы бот понимал - пишут свои. Узнать можно нажав на Профиль → мои данные → Изменить в VK ID. И там он будет рядом с аватаркой.
Управление →Настойки →дополнительно
Управление →Настойки →дополнительно

Там жмем "создать ключ"

Выбираем разрешения.
Выбираем разрешения.

Далее вк удостоверится, что это точно Вы. И выдаст ключик.

Вон он  ключ-токен.
Вон он ключ-токен.

Можно было особенно не замазывать - ключ ооочень длинный набор рандомных символов, который выходит далеко за пределы окошка.

Что дальше?

А дальше нужно сделать новую программу на наш esp и во фреймворке arduino - почему бы и нет. У меня это ESP8266. Не перепаивать же плату, которая работает на более современный контроллер. Но если кому-то будет нужно - могу адаптировать под ESP32 или даже сделать конфигуратор.

Начнем.

Первое, что хотелось бы улучшить по сравнению со скетчем из старой версии - добавить возможность конфигурации точки доступа - удержанием какой-нибудь кнопки при старте контроллера - запускать простую точку доступа с названием flower и паролем 12345678

страница настроек.
страница настроек.

Какую-то такую.

Сначала нужно придумать где это всё хранить. Можно пойти сложным путем и подмонтировать файловую систему, а можно воспользоваться простым ардуиновским эмулятором EEPROM и сохранить всё в структуру. Так же время на ESP лучше обновлять не через сторонний сервис, а брать в том же VK API.

// Структура сохраняет все настройки в EEPROM
struct Settings {
char ssid[32]; // SSID WiFi (макс 31 символ + \0)
char password[64]; // Пароль WiFi (макс 63 символа + \0)
char vk_token[256]; // Токен VK (длинный, начинается с vk1.a...)
char user_id[16]; // ID пользователя VK (только цифры)
uint8_t checksum; // Контрольная сумма для проверки целостности
};

Например в такую. При старте без нажатой кнопки просто брать настройки из нее.

О том как читать и писать в EEPROM, создавать точку доступа или подключаться к ней, выводить HTML - написано очень много всего. Чтобы не растягивать статью сосредоточимся на работе с API VK. А мою реализацию можно будет посмотреть по ссылке внизу статьи. Когда я всё доделаю =). А пока создадим простого ЭХО-бота. Мы ему слова - он нам его же.

Эхо-бот.

//Подключаем библиотеки для подключения к вайфай и парсинга сообщений.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>

//Вводим свои настройки

#define WIFI_SSID "YourWiFi"
#define WIFI_PASS "YourPassword"
#define VK_TOKEN "vk1.a.your_token"
#define USER_ID "123456789"

// Создаем объект client для безопасного HTTPS соединения

WiFiClientSecure client;

// ID последнего обработанного сообщения (чтобы не отвечать дважды на одно сообщение)

int lastMsgId = 0;

// Функция setup()

void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) delay(500);

// Настраиваем клиент для HTTPS соединений. setInsecure() отключает проверку SSL сертификатов.Это нужно, потому что ESP8266 не умеет проверять сертификаты VK.В реальных проектах это небезопасно, но для теста подойдет.

client.setInsecure();

// Создаем объект http для отправки HTTP запросов

HTTPClient http;

// формируем сообщение

String url = "https://api.vk.com/method/messages.send?";
url += "access_token=" VK_TOKEN "&peer_id=" USER_ID;
url += "&message=Bot%20started&random_id=" + String(random(10000)) + "&v=5.199";
http.begin(client, url);

// Отправляем GET запрос

http.GET();

//закрываем соединение

http.end();
Serial.println("READY! Send message to VK");
}

//функция loop()

void loop() {

// Получаем сообщения

HTTPClient http;
String url = "https://api.vk.com/method/messages.getHistory?";

// '5.199' - это версия VK API

url += "access_token=" VK_TOKEN "&user_id=" USER_ID "&count=1&v=5.199";
http.begin(client, url);
if (http.GET() == 200) {
String json = http.getString();
JsonDocument doc;
deserializeJson(doc, json);

// Получаем ВСЕ данные о сообщении

int msgId = doc["response"]["items"][0]["id"];
String text = doc["response"]["items"][0]["text"].as<String>();

// 0 = входящее, 1 = исходящее

int out = doc["response"]["items"][0]["out"];

// Проверяем: 1) новое ли сообщение 2) входящее ли (не наше)

if (msgId > lastMsgId && out == 0) {
lastMsgId = msgId;
Serial.print("Новое входящее сообщение: ");
Serial.println(text);
// Проверяем, не ответ ли это на наше сообщение
if (!text.startsWith("You said:")) {

// Эхо

text.replace(" ", "%20");
String echoUrl = "https://api.vk.com/method/messages.send?";
echoUrl += "access_token=" VK_TOKEN "&peer_id=" USER_ID;
echoUrl += "&message=You%20said:%20" + text;
echoUrl += "&random_id=" + String(random(10000)) + "&v=5.199";

// Создаем еще один HTTP клиент для отправки ответа

HTTPClient echoHttp;

// Начинаем соединение и отправляем ответ

echoHttp.begin(client, echoUrl);
echoHttp.GET();

//закрываем соединение

echoHttp.end();

//пишем в порт что получилось

Serial.print("Ответ отправлен: ");
Serial.println(text);
} else {
Serial.println("Пропускаем, это ответ бота");
}
} else

// Выводим для отладки

if (out == 1) {
Serial.println("Это наше исходящее сообщение, пропускаем");
} else {
Serial.println("Сообщение уже обработано");
} } }
http.end();

// Ждем 2000 миллисекунд (2 секунды) перед следующей проверкой, чтобы не перегружать сервер.

delay(2000);
}

Ещё понадобится библиотека ArduinoJson. В Arduino IDE ее можно найти в менеджере библиотек.

Вот минимальная рабочая версия клиента. Может только в эхо. Очень много кода, который будет повторяться в более-менее крупном проекте. Нужно бы написать свою библиотеку-обертку. Ну и перейдем к тестам!

Загружаем, перезагружаем!

Заходим в наше сообщество.

страница сообщества вконтакте
страница сообщества вконтакте

Переходим в диалог

по этой ссылке
по этой ссылке

И тестируем.

Немного конспирации :)
Немного конспирации :)

Готово! Теперь у нас есть диалог с ботом в мессенджере вк. Хотя сообщение "Bot started" при старте системы и подключении к WiFi уже и само включило этот диалог. Всё работает через интернет, который раздается через телефон при доступных лишь белых списках.

Но! Эхо-бот - это не полноценная система управления. Даже больше - это вообще не она. И ещё этот скетч использует Short Poll - не особенно хороший метод. Мы спрашиваем у вк каждые две секунды не появилось ли новых сообщений. Не хорошо для управления чем-то. Да и слишком много спама. Гораздо лучше использовать Long Poll который так же поддерживается VK API, но реализуется чуть сложнее. Мы просим API ждать новое сообщение, но не дольше, например, 30 секунд, а потом просим опять и опять. Новые сообщения приходят мгновенно.

На этом сегодня всё. Исходник получился небольшим и его можно скопировать прям со страницы статьи для экспериментов. Если кому-то это будет интересно, то обсудить дальнейшее развитие проекта можно тут в комментариях или телеграм-чате группы. Всем спасибо за просмотр! Как обычно буду рад конструктивным комментариям. До свидания!