From f8837fa88e99f3b854bd9089bc84167df450691d Mon Sep 17 00:00:00 2001 From: witnessmenow Date: Sun, 12 Feb 2017 11:00:05 +0000 Subject: [PATCH 01/22] WIP initial working version of supporting channel post #37 --- src/UniversalTelegramBot.cpp | 70 +++++++++++++++++++++++++++--------- src/UniversalTelegramBot.h | 3 ++ 2 files changed, 56 insertions(+), 17 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 593e9f7..fdff248 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -312,24 +312,10 @@ int UniversalTelegramBot::getUpdates(long offset) { int resultArrayLength = root["result"].size(); if (resultArrayLength > 0) { int newMessageIndex = 0; + //Step through all results for (int i=0; i < resultArrayLength; i++) { - JsonObject& message = root["result"][i]["message"]; - int update_id = root["result"][i]["update_id"]; - if (last_message_received != update_id) { - last_message_received = update_id; - String text = message["text"]; - String date = message["date"]; - String chat_id = message["chat"]["id"]; - String from_id = message["from"]["id"]; - String from_name = message["from"]["first_name"]; - - messages[newMessageIndex].update_id = update_id; - messages[newMessageIndex].text = text; - messages[newMessageIndex].date = date; - messages[newMessageIndex].chat_id = chat_id; - messages[newMessageIndex].from_id = from_id; - messages[newMessageIndex].from_name = from_name; - + JsonObject& result = root["result"][i]; + if (processResult(result, newMessageIndex)) { newMessageIndex++; } } @@ -349,6 +335,56 @@ int UniversalTelegramBot::getUpdates(long offset) { } } +bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { + int update_id = result["update_id"]; + // Check have we already dealt with this message (this shouldn't happen!) + if (last_message_received != update_id) { + last_message_received = update_id; + + String text; + String date; + String chat_id; + String chat_title; + String from_id; + String from_name; + String type; + + + if (result.containsKey("message")) { + JsonObject& message = result["message"]; + type = "message"; + from_id = message["from"]["id"].as(); + from_name = message["from"]["first_name"].as(); + + text = message["text"].as(); + date = message["date"].as(); + chat_id = message["chat"]["id"].as(); + chat_title = message["chat"]["title"].as(); + } + else if (result.containsKey("channel_post")) { + JsonObject& message = result["channel_post"]; + type = "channel_post"; + + text = message["text"].as(); + date = message["date"].as(); + chat_id = message["chat"]["id"].as(); + chat_title = message["chat"]["title"].as(); + } + + messages[messageIndex].update_id = update_id; + messages[messageIndex].text = text; + messages[messageIndex].date = date; + messages[messageIndex].chat_id = chat_id; + messages[messageIndex].chat_title = chat_title; + messages[messageIndex].from_id = from_id; + messages[messageIndex].from_name = from_name; + messages[messageIndex].type = type; + + return true; + } + return false; +} + /*********************************************************************** * SendMessage - function to send message to telegram * * (Arguments to pass: chat_id, text to transmit and markup(optional)) * diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index d80a903..56f2263 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -37,9 +37,11 @@ typedef byte (*GetNextByte)(); struct telegramMessage{ String text; String chat_id; + String chat_title; String from_id; String from_name; String date; + String type; int update_id; }; @@ -86,6 +88,7 @@ class UniversalTelegramBot //JsonObject * parseUpdates(String response); String _token; Client *client; + bool processResult(JsonObject& result, int messageIndex); const int maxMessageLength = 1300; bool _debug = false; }; From 25c0c296a362969f38443225997ce74802618af8 Mon Sep 17 00:00:00 2001 From: witnessmenow Date: Mon, 16 Oct 2017 21:17:13 +0100 Subject: [PATCH 02/22] Changes for new RC --- .travis.yml | 2 + README.md | 8 +- examples/ESP8266/ChannelPost/ChannelPost.ino | 68 +++++++++ .../InlineKeyboardMarkup.ino | 58 ++++---- examples/ESP8266/Location/Location.ino | 88 ++++++++++++ examples/ESP8266/LongPoll/LongPoll.ino | 68 +++++++++ library.properties | 2 +- src/UniversalTelegramBot.cpp | 129 +++++++++++------- src/UniversalTelegramBot.h | 5 +- 9 files changed, 350 insertions(+), 78 deletions(-) create mode 100644 examples/ESP8266/ChannelPost/ChannelPost.ino create mode 100644 examples/ESP8266/Location/Location.ino create mode 100644 examples/ESP8266/LongPoll/LongPoll.ino diff --git a/.travis.yml b/.travis.yml index 3d93c8c..8fb1cd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,8 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromSD EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromURL EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini + - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini + - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini install: diff --git a/README.md b/README.md index 3774034..8e70e79 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,13 @@ Here is a list of features that this library covers. (Note: The examples link to |*Receiving Messages*|Your bot can read messages that are sent to it. This is useful for sending commands to your arduino such as toggle and LED|`int getUpdates(long offset)`

Gets any pending messages from Telegram and stores them in **bot.messages** . Offset should be set to **bot.last_message_received** + 1. Returns the numbers new messages received.| [FlashLED](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/FlashLED/FlashLED.ino) or any other example| |*Sending messages*|Your bot can send messages to any Telegram or group. This can be useful to get the arduino to notify you of an event e.g. Button pressed etc (Note: bots can only message you if you messaged them first)|`bool sendMessage(String chat_id, String text, String parse_mode = "")`

Sends the message to the chat_id. Returns if the message sent or not.| [EchoBot](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/EchoBot/EchoBot.ino#L51) or any other example| |*Reply Keyboards*|Your bot can send [reply keyboards](https://camo.githubusercontent.com/2116a60fa614bf2348074a9d7148f7d0a7664d36/687474703a2f2f692e696d6775722e636f6d2f325268366c42672e6a70673f32) that can be used as a type of menu.|`bool sendMessageWithReplyKeyboard(String chat_id, String text, String parse_mode, String keyboard, bool resize = false, bool oneTime = false, bool selective = false)`

Send a keyboard to the specified chat_id. parse_mode can be left blank. Will return true if the message sends successfully.| [ReplyKeyboard](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/CustomKeyboard/ReplyKeyboardMarkup/ReplyKeyboardMarkup.ino)| -|*Inline Keyboards*|Your bot can send [inline keyboards](https://camo.githubusercontent.com/55dde972426e5bc77120ea17a9c06bff37856eb6/68747470733a2f2f636f72652e74656c656772616d2e6f72672f66696c652f3831313134303939392f312f324a536f55566c574b61302f346661643265323734336463386564613034).

Note: Only URLS are supported currently|`bool sendMessageWithInlineKeyboard(String chat_id, String text, String parse_mode, String keyboard)`

Send a keyboard to the specified chat_id. parse_mode can be left blank. Will return true if the message sends successfully.| [InlineKeyboard](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino)| +|*Inline Keyboards*|Your bot can send [inline keyboards](https://camo.githubusercontent.com/55dde972426e5bc77120ea17a9c06bff37856eb6/68747470733a2f2f636f72652e74656c656772616d2e6f72672f66696c652f3831313134303939392f312f324a536f55566c574b61302f346661643265323734336463386564613034).

Note: URLS & callbacks are supported currently|`bool sendMessageWithInlineKeyboard(String chat_id, String text, String parse_mode, String keyboard)`

Send a keyboard to the specified chat_id. parse_mode can be left blank. Will return true if the message sends successfully.| [InlineKeyboard](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino)| |*Send Photos*|It is possible to send phtos from your bot. You can send images from the web or from the arduino directly (Only sending from an SD card has been tested, but it should be able to send from a camera module)|Check the examples for more info| [From URL](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/SendPhoto/PhotoFromURL/PhotoFromURL.ino)

[Binary from SD](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/SendPhoto/PhotoFromSD/PhotoFromSD.ino)

[From File Id](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/blob/master/examples/ESP8266/SendPhoto/PhotoFromFileID/PhotoFromFileID.ino)| -|*Chat Actions*|Your bot can send chat actions, such as *typing* or *sending photo* to let the user know that the bot is doing something. |`bool sendChatAction(String chat_id, String chat_action)`

Send a the chat action to the specified chat_id. There is a set list of chat actions that Telegram support, see the example for details. Will return true if the chat actions sends successfully.| [InlineKeyboard](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/ChatAction)| +|*Chat Actions*|Your bot can send chat actions, such as *typing* or *sending photo* to let the user know that the bot is doing something. |`bool sendChatAction(String chat_id, String chat_action)`

Send a the chat action to the specified chat_id. There is a set list of chat actions that Telegram support, see the example for details. Will return true if the chat actions sends successfully.| +|*Location*|Your bot can receive location data, either from a single location data point or live location data. |Check the example.| [Location](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/Location/Location.ino)| +|*Channel Post*|Reads posts from channels. |Check the example.| [ChannelPost](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/ChannelPost/ChannelPost.ino)| +|*Channel Post*|Reads posts from channels. |Check the example.| [ChannelPost](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/ChannelPost/ChannelPost.ino)| +|*Long Poll*|Set how long the bot will wait checking for a new message before returning now messages.

This will decrease the amount of requests and data used by the bot, but it will tie up the arduino while it waits for messages |`bot.LongPoll = 60;`

Where 60 is the amount of seconds it should wait | [LongPoll](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/LongPoll/LongPoll.ino)| The full Telegram Bot API documentation can be read [here](https://core.telegram.org/bots/api). If there is a feature you would like added to the library please either raise a Github issue or please feel free to raise a Pull Request. diff --git a/examples/ESP8266/ChannelPost/ChannelPost.ino b/examples/ESP8266/ChannelPost/ChannelPost.ino new file mode 100644 index 0000000..05ba421 --- /dev/null +++ b/examples/ESP8266/ChannelPost/ChannelPost.ino @@ -0,0 +1,68 @@ +/******************************************************************* +* An example of bot that echos back any messages received, +* including ones from channels +* +* written by Brian Lough +*******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void setup() { + Serial.begin(115200); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + for (int i=0; i #include @@ -22,27 +22,35 @@ int Bot_mtbs = 1000; //mean time between scan messages long Bot_lasttime; //last time messages' scan has been done void handleNewMessages(int numNewMessages) { - Serial.println("handleNewMessages"); - Serial.println(String(numNewMessages)); - - for (int i=0; i Bot_lasttime + Bot_mtbs) { int numNewMessages = bot.getUpdates(bot.last_message_received + 1); - while(numNewMessages) { + while (numNewMessages) { Serial.println("got response"); handleNewMessages(numNewMessages); numNewMessages = bot.getUpdates(bot.last_message_received + 1); diff --git a/examples/ESP8266/Location/Location.ino b/examples/ESP8266/Location/Location.ino new file mode 100644 index 0000000..55ee574 --- /dev/null +++ b/examples/ESP8266/Location/Location.ino @@ -0,0 +1,88 @@ +/******************************************************************* + * An example of recieving location Data + * + * + * By Brian Lough + *******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "SSID"; // your network SSID (name) +char password[] = "password"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void handleNewMessages(int numNewMessages) { + + for (int i = 0; i < numNewMessages; i++) { + + String chat_id = String(bot.messages[i].chat_id); + String text = bot.messages[i].text; + + String from_name = bot.messages[i].from_name; + if (from_name == "") from_name = "Guest"; + + if (bot.messages[i].longitude != 0 || bot.messages[i].latitude != 0) { + Serial.print("Long: "); + Serial.println(String(bot.messages[i].longitude, 6)); + Serial.print("Lat: "); + Serial.println(String(bot.messages[i].latitude, 6)); + + String message = "Long: " + String(bot.messages[i].longitude, 6) + "\n"; + message += "Lat: " + String(bot.messages[i].latitude, 6) + "\n"; + bot.sendMessage(chat_id, message, "Markdown"); + } else if (text == "/start") { + String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; + welcome += "Share a location or a live location and the bot will respond with the co-ords\n"; + + bot.sendMessage(chat_id, welcome, "Markdown"); + } + } +} + +void setup() { + Serial.begin(115200); + + // Set WiFi to station mode and disconnect from an AP if it was Previously connected + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + + // attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while (numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP8266/LongPoll/LongPoll.ino b/examples/ESP8266/LongPoll/LongPoll.ino new file mode 100644 index 0000000..9840ba0 --- /dev/null +++ b/examples/ESP8266/LongPoll/LongPoll.ino @@ -0,0 +1,68 @@ +/******************************************************************* +* An example of setting a long poll, this will mean the request +* for new messages will wait the specified amount of time before +* returning with no messages +* +* This should reduce amount of data used by the bot +* +* written by Brian Lough +*******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void setup() { + Serial.begin(115200); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.disconnect(); + delay(100); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + bot.longPoll = 60; + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + for (int i=0; i sentence=Arduino Telegram Bot library for multiple different architectures. diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index fdff248..80d655d 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -34,14 +34,16 @@ String UniversalTelegramBot::sendGetToTelegram(String command) { // Connect with api.telegram.org if (client->connect(HOST, SSL_PORT)) { - if (_debug) Serial.println(".... connected to server"); + + if (_debug) Serial.println(F(".... connected to server")); + String a=""; char c; int ch_count=0; client->println("GET /"+command); now=millis(); avail=false; - while (millis() - now<1500) { + while (millis() - now < longPoll * 1000 + 1500) { while (client->available()) { char c = client->read(); //Serial.write(c); @@ -75,15 +77,15 @@ String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject& payl // Connect with api.telegram.org if (client->connect(HOST, SSL_PORT)) { // POST URI - client->print("POST /" + command); client->println(" HTTP/1.1"); + client->print("POST /" + command); client->println(F(" HTTP/1.1")); // Host header - client->print("Host:"); client->println(HOST); + client->print(F("Host:")); client->println(HOST); // JSON content type - client->println("Content-Type: application/json"); + client->println(F("Content-Type: application/json")); // Content length int length = payload.measureLength(); - client->print("Content-Length:"); client->println(length); + client->print(F("Content-Length:")); client->println(length); // End of headers client->println(); // POST message body @@ -150,7 +152,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str String headers = ""; long now; bool responseReceived; - String boundry = "------------------------b8f610217e83e29b"; + String boundry = F("------------------------b8f610217e83e29b"); // Connect with api.telegram.org if (client->connect(HOST, SSL_PORT)) { @@ -171,11 +173,11 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str end_request = end_request + "\r\n"; end_request = end_request + "--" + boundry + "--" + "\r\n"; - client->print("POST /bot"+_token+"/" + command); client->println(" HTTP/1.1"); + client->print("POST /bot"+_token+"/" + command); client->println(F(" HTTP/1.1")); // Host header - client->print("Host: "); client->println(HOST); - client->println("User-Agent: arduino/1.0"); - client->println("Accept: */*"); + client->print(F("Host: ")); client->println(HOST); + client->println(F("User-Agent: arduino/1.0")); + client->println(F("Accept: */*")); int contentLength = fileSize + start_request.length() + end_request.length(); if (_debug) Serial.println("Content-Length: " + String(contentLength)); @@ -198,7 +200,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str if(count == 512){ //yield(); if (_debug) { - Serial.println("Sending full buffer"); + Serial.println(F("Sending full buffer")); } client->write((const uint8_t *)buffer, 512); count = 0; @@ -207,7 +209,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str if(count > 0) { if (_debug) { - Serial.println("Sending remaining buffer"); + Serial.println(F("Sending remaining buffer")); } client->write((const uint8_t *)buffer, count); } @@ -292,6 +294,9 @@ int UniversalTelegramBot::getUpdates(long offset) { if (_debug) Serial.println("GET Update Messages"); String command = "bot"+_token+"/getUpdates?offset="+String(offset)+"&limit="+String(HANDLE_MESSAGES); + if(longPoll > 0) { + command = command + "&timeout=" + String(longPoll); + } String response = sendGetToTelegram(command); //receive reply from telegram.org if (response != "") { @@ -321,14 +326,14 @@ int UniversalTelegramBot::getUpdates(long offset) { } return newMessageIndex; } else { - if (_debug) Serial.println("no new messages"); + if (_debug) Serial.println(F("no new messages")); } } else { - if (_debug) Serial.println("Response contained no 'result'"); + if (_debug) Serial.println(F("Response contained no 'result'")); } } else { // Buffer may not be big enough, increase buffer or reduce max number of messages - if (_debug) Serial.println("Failed to parse update, the message could be too big for the buffer"); + if (_debug) Serial.println(F("Failed to parse update, the message could be too big for the buffer")); } return 0; @@ -340,46 +345,72 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { // Check have we already dealt with this message (this shouldn't happen!) if (last_message_received != update_id) { last_message_received = update_id; + messages[messageIndex].update_id = update_id; - String text; - String date; - String chat_id; - String chat_title; - String from_id; - String from_name; - String type; - + messages[messageIndex].text = F(""); + messages[messageIndex].from_id = F(""); + messages[messageIndex].from_name = F(""); + messages[messageIndex].longitude = 0; + messages[messageIndex].latitude = 0; if (result.containsKey("message")) { JsonObject& message = result["message"]; - type = "message"; - from_id = message["from"]["id"].as(); - from_name = message["from"]["first_name"].as(); - - text = message["text"].as(); - date = message["date"].as(); - chat_id = message["chat"]["id"].as(); - chat_title = message["chat"]["title"].as(); + messages[messageIndex].type = F("message"); + messages[messageIndex].from_id = message["from"]["id"].as(); + messages[messageIndex].from_name = message["from"]["first_name"].as(); + + messages[messageIndex].date = message["date"].as(); + messages[messageIndex].chat_id = message["chat"]["id"].as(); + messages[messageIndex].chat_title = message["chat"]["title"].as(); + + if (message.containsKey("text")) { + messages[messageIndex].text = message["text"].as(); + + } else if (message.containsKey("location")) { + messages[messageIndex].longitude = message["location"]["longitude"].as(); + messages[messageIndex].latitude = message["location"]["latitude"].as(); + + } } else if (result.containsKey("channel_post")) { JsonObject& message = result["channel_post"]; - type = "channel_post"; + messages[messageIndex].type = F("channel_post"); + + messages[messageIndex].text = message["text"].as(); + messages[messageIndex].date = message["date"].as(); + messages[messageIndex].chat_id = message["chat"]["id"].as(); + messages[messageIndex].chat_title = message["chat"]["title"].as(); + + } else if (result.containsKey("callback_query")) { + JsonObject& message = result["callback_query"]; + messages[messageIndex].type = F("callback_query"); + messages[messageIndex].from_id = message["from"]["id"].as(); + messages[messageIndex].from_name = message["from"]["first_name"].as(); + + messages[messageIndex].text = message["data"].as(); + messages[messageIndex].date = message["date"].as(); + messages[messageIndex].chat_id = F(""); + messages[messageIndex].chat_title = F(""); + } else if (result.containsKey("edited_message")) { + JsonObject& message = result["edited_message"]; + messages[messageIndex].type = F("edited_message"); + messages[messageIndex].from_id = message["from"]["id"].as(); + messages[messageIndex].from_name = message["from"]["first_name"].as(); + + messages[messageIndex].date = message["date"].as(); + messages[messageIndex].chat_id = message["chat"]["id"].as(); + messages[messageIndex].chat_title = message["chat"]["title"].as(); + + if (message.containsKey("text")) { + messages[messageIndex].text = message["text"].as(); + + } else if (message.containsKey("location")) { + messages[messageIndex].longitude = message["location"]["longitude"].as(); + messages[messageIndex].latitude = message["location"]["latitude"].as(); - text = message["text"].as(); - date = message["date"].as(); - chat_id = message["chat"]["id"].as(); - chat_title = message["chat"]["title"].as(); + } } - messages[messageIndex].update_id = update_id; - messages[messageIndex].text = text; - messages[messageIndex].date = date; - messages[messageIndex].chat_id = chat_id; - messages[messageIndex].chat_title = chat_title; - messages[messageIndex].from_id = from_id; - messages[messageIndex].from_name = from_name; - messages[messageIndex].type = type; - return true; } return false; @@ -490,7 +521,7 @@ bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, String bool UniversalTelegramBot::sendPostMessage(JsonObject& payload) { bool sent=false; - if (_debug) Serial.println("SEND Post Message"); + if (_debug) Serial.println(F("SEND Post Message")); long sttime=millis(); if (payload.containsKey("text")) { @@ -512,7 +543,7 @@ String UniversalTelegramBot::sendPostPhoto(JsonObject& payload) { bool sent=false; String response = ""; - if (_debug) Serial.println("SEND Post Photo"); + if (_debug) Serial.println(F("SEND Post Photo")); long sttime=millis(); if (payload.containsKey("photo")) { @@ -590,7 +621,7 @@ bool UniversalTelegramBot::checkForOkResponse(String response) { bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { bool sent = false; - if (_debug) Serial.println("SEND Chat Action Message"); + if (_debug) Serial.println(F("SEND Chat Action Message")); long sttime = millis(); if (text != "") { diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 56f2263..f0852f7 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -42,6 +42,8 @@ struct telegramMessage{ String from_name; String date; String type; + float longitude; + float latitude; int update_id; }; @@ -83,6 +85,8 @@ class UniversalTelegramBot long last_message_received; String name; String userName; + int longPoll = 0; + bool _debug = false; private: //JsonObject * parseUpdates(String response); @@ -90,7 +94,6 @@ class UniversalTelegramBot Client *client; bool processResult(JsonObject& result, int messageIndex); const int maxMessageLength = 1300; - bool _debug = false; }; #endif From 87a417dc4ef80e6bae1ff98b5055ce1ba6c68af9 Mon Sep 17 00:00:00 2001 From: witnessmenow Date: Mon, 16 Oct 2017 22:04:45 +0100 Subject: [PATCH 03/22] update readme --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8e70e79..25d4914 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,7 @@ Here is a list of features that this library covers. (Note: The examples link to |*Chat Actions*|Your bot can send chat actions, such as *typing* or *sending photo* to let the user know that the bot is doing something. |`bool sendChatAction(String chat_id, String chat_action)`

Send a the chat action to the specified chat_id. There is a set list of chat actions that Telegram support, see the example for details. Will return true if the chat actions sends successfully.| |*Location*|Your bot can receive location data, either from a single location data point or live location data. |Check the example.| [Location](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/Location/Location.ino)| |*Channel Post*|Reads posts from channels. |Check the example.| [ChannelPost](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/ChannelPost/ChannelPost.ino)| -|*Channel Post*|Reads posts from channels. |Check the example.| [ChannelPost](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/ChannelPost/ChannelPost.ino)| -|*Long Poll*|Set how long the bot will wait checking for a new message before returning now messages.

This will decrease the amount of requests and data used by the bot, but it will tie up the arduino while it waits for messages |`bot.LongPoll = 60;`

Where 60 is the amount of seconds it should wait | [LongPoll](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/LongPoll/LongPoll.ino)| +|*Long Poll*|Set how long the bot will wait checking for a new message before returning now messages.

This will decrease the amount of requests and data used by the bot, but it will tie up the arduino while it waits for messages |`bot.longPoll = 60;`

Where 60 is the amount of seconds it should wait | [LongPoll](https://github.com/witnessmenow/Universal-Arduino-Telegram-Bot/tree/master/examples/ESP8266/LongPoll/LongPoll.ino)| The full Telegram Bot API documentation can be read [here](https://core.telegram.org/bots/api). If there is a feature you would like added to the library please either raise a Github issue or please feel free to raise a Pull Request. From e0ddfd2f2d5968e8eaa613c8f28b3e7f5fec1213 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 20:35:01 +0530 Subject: [PATCH 04/22] Bugfix: Invalid return when response is an empty string --- src/UniversalTelegramBot.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 80d655d..3f7814f 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -299,7 +299,11 @@ int UniversalTelegramBot::getUpdates(long offset) { } String response = sendGetToTelegram(command); //receive reply from telegram.org - if (response != "") { + if (response == "") { + if(_debug) Serial.println(F("Received empty string in response!")); + return 0; + } + else { if (_debug) { Serial.print("incoming message length"); Serial.println(response.length()); From 90904d84078886b9ed6c356f0610ce6c26174819 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 20:38:49 +0530 Subject: [PATCH 05/22] Added client handling for ESP32 --- src/UniversalTelegramBot.cpp | 78 +++++++++++++++++++++++++++++++----- src/UniversalTelegramBot.h | 1 + 2 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 3f7814f..3458d66 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -20,6 +20,19 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/* **** Note Regarding Client Connection Keeping **** + Client connection is established in functions that directly involve use of client, + i.e sendGetToTelegram, sendPostToTelegram, and sendMultipartFormDataToTelegram. + It is closed at the end of sendMultipartFormDataToTelegram, but not at the + end of sendGetToTelegram and sendPostToTelegram as these may need to keep the + connection alive for respose / response checking. Re-establishing a connection + then wastes time which is noticeable in user experience. + Due to this, it is important that connection be closed manually after calling + sendGetToTelegram or sendPostToTelegram by calling closeClient(); + Failure to close connection causes memory leakage, and SSL errors on ESP32 + Note: closeClient() only closes connections on ESP32 (#ifdef ESP32). +*/ + #include "UniversalTelegramBot.h" UniversalTelegramBot::UniversalTelegramBot(String token, Client &client) { @@ -32,8 +45,14 @@ String UniversalTelegramBot::sendGetToTelegram(String command) { long now; bool avail; - // Connect with api.telegram.org - if (client->connect(HOST, SSL_PORT)) { + // Connect with api.telegram.org if not already connected + if(!client->connected()){ + if (_debug) Serial.println(F("[BOT]Connecting to server")); + if(!client->connect(HOST, SSL_PORT)){ + if (_debug) Serial.println(F("[BOT]Conection error")); + } + } + if (client->connected()) { if (_debug) Serial.println(F(".... connected to server")); @@ -74,8 +93,14 @@ String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject& payl long now; bool responseReceived; - // Connect with api.telegram.org - if (client->connect(HOST, SSL_PORT)) { + // Connect with api.telegram.org if not already connected + if(!client->connected()){ + if (_debug) Serial.println(F("[BOT Client]Connecting to server")); + if(!client->connect(HOST, SSL_PORT)){ + if (_debug) Serial.println(F("[BOT Client]Conection error")); + } + } + if (client->connected()) { // POST URI client->print("POST /" + command); client->println(F(" HTTP/1.1")); // Host header @@ -153,8 +178,15 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str long now; bool responseReceived; String boundry = F("------------------------b8f610217e83e29b"); - // Connect with api.telegram.org - if (client->connect(HOST, SSL_PORT)) { + + // Connect with api.telegram.org if not already connected + if(!client->connected()){ + if (_debug) Serial.println(F("[BOT Client]Connecting to server")); + if(!client->connect(HOST, SSL_PORT)){ + if (_debug) Serial.println(F("[BOT Client]Conection error")); + } + } + if (client->connected()) { String start_request = ""; String end_request = ""; @@ -262,6 +294,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str } } + closeClient(); return body; } @@ -271,6 +304,8 @@ bool UniversalTelegramBot::getMe() { DynamicJsonBuffer jsonBuffer; JsonObject& root = jsonBuffer.parseObject(response); + closeClient(); + if(root.success()) { if (root.containsKey("result")) { String _name = root["result"]["first_name"]; @@ -301,6 +336,8 @@ int UniversalTelegramBot::getUpdates(long offset) { if (response == "") { if(_debug) Serial.println(F("Received empty string in response!")); + // close the client as there's nothing to do with an empty string + closeClient(); return 0; } else { @@ -328,6 +365,7 @@ int UniversalTelegramBot::getUpdates(long offset) { newMessageIndex++; } } + // We will keep the client open because there may be a response to be given return newMessageIndex; } else { if (_debug) Serial.println(F("no new messages")); @@ -335,11 +373,17 @@ int UniversalTelegramBot::getUpdates(long offset) { } else { if (_debug) Serial.println(F("Response contained no 'result'")); } - } else { - // Buffer may not be big enough, increase buffer or reduce max number of messages - if (_debug) Serial.println(F("Failed to parse update, the message could be too big for the buffer")); + } else { // Parsing failed + if(response.length() < 2){ // Too short a message. Maybe connection issue + if (_debug) Serial.println(F("Parsing error: Message too short")); + } + else{ + // Buffer may not be big enough, increase buffer or reduce max number of messages + if (_debug) Serial.println(F("Failed to parse update, the message could be too big for the buffer")); + } } - + // Close the client as no response is to be given + closeClient(); return 0; } } @@ -441,7 +485,7 @@ bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, String } } } - + closeClient(); return sent; } @@ -540,6 +584,7 @@ bool UniversalTelegramBot::sendPostMessage(JsonObject& payload) { } } + closeClient(); return sent; } @@ -562,6 +607,7 @@ String UniversalTelegramBot::sendPostPhoto(JsonObject& payload) { } } + closeClient(); return response; } @@ -642,5 +688,15 @@ bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { } } + closeClient(); return sent; } + +void UniversalTelegramBot::closeClient(){ +#ifdef ESP32 + if(client->connected()){ + if(_debug){Serial.println(F("Closing client")); } + client->stop(); + } +#endif +} diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index f0852f7..9603069 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -93,6 +93,7 @@ class UniversalTelegramBot String _token; Client *client; bool processResult(JsonObject& result, int messageIndex); + void closeClient(); const int maxMessageLength = 1300; }; From 80bdf8bd58b08406ba98c4563c7706f6d76cc1cb Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 20:40:26 +0530 Subject: [PATCH 06/22] Bugfix: Empty chat_id when response is callback_query --- src/UniversalTelegramBot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 3458d66..05129d8 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -437,7 +437,7 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { messages[messageIndex].text = message["data"].as(); messages[messageIndex].date = message["date"].as(); - messages[messageIndex].chat_id = F(""); + messages[messageIndex].chat_id = message["message"]["chat"]["id"].as(); messages[messageIndex].chat_title = F(""); } else if (result.containsKey("edited_message")) { JsonObject& message = result["edited_message"]; From 740ef9442faa268b1b9d0e4086fa9e593e3dbc3a Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 23:00:19 +0530 Subject: [PATCH 07/22] Added example: AdvanceLED_platformio --- .../ESP32/AdvancedLED_platformio/.gitignore | 4 + .../ESP32/AdvancedLED_platformio/.travis.yml | 55 +++++ .../ESP32/AdvancedLED_platformio/README.md | 39 ++++ .../AdvancedLED_platformio/platformio.ini | 15 ++ .../ESP32/AdvancedLED_platformio/src/main.cpp | 202 ++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 examples/ESP32/AdvancedLED_platformio/.gitignore create mode 100644 examples/ESP32/AdvancedLED_platformio/.travis.yml create mode 100644 examples/ESP32/AdvancedLED_platformio/README.md create mode 100644 examples/ESP32/AdvancedLED_platformio/platformio.ini create mode 100644 examples/ESP32/AdvancedLED_platformio/src/main.cpp diff --git a/examples/ESP32/AdvancedLED_platformio/.gitignore b/examples/ESP32/AdvancedLED_platformio/.gitignore new file mode 100644 index 0000000..5dac9f5 --- /dev/null +++ b/examples/ESP32/AdvancedLED_platformio/.gitignore @@ -0,0 +1,4 @@ +.pioenvs +.piolibdeps +.clang_complete +.gcc-flags.json diff --git a/examples/ESP32/AdvancedLED_platformio/.travis.yml b/examples/ESP32/AdvancedLED_platformio/.travis.yml new file mode 100644 index 0000000..52072ef --- /dev/null +++ b/examples/ESP32/AdvancedLED_platformio/.travis.yml @@ -0,0 +1,55 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < http://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < http://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < http://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choice one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# install: +# - pip install -U platformio +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to by used as a library with examples +# + +# language: python +# python: +# - "2.7" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/examples/ESP32/AdvancedLED_platformio/README.md b/examples/ESP32/AdvancedLED_platformio/README.md new file mode 100644 index 0000000..6f8124e --- /dev/null +++ b/examples/ESP32/AdvancedLED_platformio/README.md @@ -0,0 +1,39 @@ +## ESP32 - AdvancedLED PlatformIO +PlatformIO example for controlling an LED from a Telegram Bot. +This example sets up an ESP32 to be controlled through a Telegram Bot. +As of January 3rd, 2018, the platform (in platformio.ini) must be set to espressif32_stage. + +#### Pre-requisites +* You must have a Telegram Bot for this example to work. To make one, + 1. Open Telegram (on mobile, web, or desktop) + 2. Start a chat with BotFather (@BotFather) + 3. Send `/start` to BotFather, followed by `/newbot` + 4. Send a friendly name for your bot (this isn't the username of bot) + 5. Type in and send the username for your bot (ending in bot) + 6. Copy the token provided by BotFather and paste it at BOTtoken below +* Modify `ssid` and `password` to match your WiFi network settings +* Modify `BOTtoken` with the correct bot token acquired from Botfather +* Modify `ledPin` to match the GPIO pin on which the LED on your board is connected + +#### Available commands for the bot: +* /start - Displays an intro message in chat and provides a custom keyboard with available commands +* /options - Displays a custom keyboard with available commands +* /ledon - Turns on the LED specified by `ledPin` +* /ledoff - Turns off the LED specified by `ledPin` +* /blink - Starts blinking the LED specified by `ledPin` +* /PWM - Provides an inline keyboard for setting a PWM value for the LED specified by `ledPin` + +#### Notes +* Clicking on a button on an inline keyboard sends back a message of type="callback_query". +* Blink is implemented using low frequency PWM, as fetching message updates can take enough time to cause a noticeable lag in blinking period. +* LED implementation is based on inverse polarity of LED. +* Telegram Bot API documentation available at https://core.telegram.org/bots/api + +## Credit +Application originally written by [Giancarlo Bacchio](giancarlo.bacchio@gmail.com) for [ESP8266-TelegramBot library](https://github.com/Gianbacchio/ESP8266-TelegramBot) +Adapted by [Brian Lough](https://github.com/witnessmenow) for UniversalTelegramBot Library +Adapted for ESP32, and modified for advance features by [Pranav Sharma](https://github.com/pro2xy) + +## License + +You may copy, distribute and modify the software provided that modifications are described and licensed for free under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html). Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html), but applications that use the library don't have to be. diff --git a/examples/ESP32/AdvancedLED_platformio/platformio.ini b/examples/ESP32/AdvancedLED_platformio/platformio.ini new file mode 100644 index 0000000..7f7a5ca --- /dev/null +++ b/examples/ESP32/AdvancedLED_platformio/platformio.ini @@ -0,0 +1,15 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/page/projectconf.html + +[env:esp32dev] +platform = espressif32_stage +board = esp32dev +framework = arduino +build_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL diff --git a/examples/ESP32/AdvancedLED_platformio/src/main.cpp b/examples/ESP32/AdvancedLED_platformio/src/main.cpp new file mode 100644 index 0000000..1e621ba --- /dev/null +++ b/examples/ESP32/AdvancedLED_platformio/src/main.cpp @@ -0,0 +1,202 @@ +/******************************************************************* +Example for controlling an LED from a Telegram Bot + +You must have a Telegram Bot for this example to work. To make one, +1. Open Telegram (on mobile, web, or desktop) +2. Start a chat with BotFather (@BotFather) +3. Send /start to BotFather, followed by /newbot +4. Send a friendly name for your bot (this isn't the username of bot) +5. Type in and send the username for your bot (ending in bot) +6. Copy the token provided by BotFather and paste it at BOTtoken below + +Telegram Bot API documentation available at https://core.telegram.org/bots/api + +Note: As of 3rd Jan. 2018, it is necessary to use espressif32_stage +platform for PlatformIO + +written by Giacarlo Bacchio (Gianbacchio on Github) +adapted by Brian Lough ( witnessmenow ) for UniversalTelegramBot library +adapted by Pranav Sharma ( PRO2XY ) for ESP32 on PlatformIO +Library related discussions on https://t.me/arduino_telegram_library + +*******************************************************************/ +#include +#include +#include +#include + + +// WiFi parameters +const char *ssid = "SSID"; // your network SSID (name) +const char *password = "PASS"; // your network key + +// Bot parameters +#define BOTtoken "xxxxxxxxxx:xxxxxxxxxxxxxxxxxxxxxxxxxx" // your Bot Token (Get from Botfather) +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +// LED parameters +const int ledPin = 16; // Internal Red LED on Karyni (2 on NodeMCU-32S) +enum ledModes {ON = 0, OFF, BLINK, PWM}; // define modes of operation for LED (inverse polarity) +enum ledModes ledmode = OFF; // Start with off + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +// Function prototypes (PlatformIO doesn't make these for you automatically) +void handleNewMessages(int numNewMessages); // parses new messages and sends them to msgInterpretation +void msgInterpretation(String from_name, String text, String chat_id, String message_type); + + +void setup() { + Serial.begin(115200); + //bot._debug=true; // uncomment to see debug messages from bot library + + // attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + // Start WiFi in Station mode + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + // Wait for WiFi to connect + while (WiFi.status() != WL_CONNECTED) { + Serial.print('.'); + delay(500); + } + + Serial.println("\r\nConnected!"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); + + pinMode(ledPin, OUTPUT); // initialize ledPin as an output. + digitalWrite(ledPin, HIGH); // initialize pin as high (LED Off) +} + +void loop() { + // Every "Bot_mtbs" the bot checks if any messages have arrived + if (millis() > Bot_lasttime + Bot_mtbs) { + Bot_lasttime = millis(); + Serial.print(F("Checking for messages.. ")); + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + Serial.print(numNewMessages); Serial.println(" new messages"); + + if(numNewMessages > 0){ + handleNewMessages(numNewMessages); + } + } +} + +// Parse new messages and send them for interpretation +void handleNewMessages(int numNewMessages) { + // Extract info from the message + for (int i = 0; i < numNewMessages; i++) { + Serial.print(F("Handling message ")); Serial.println(i+1); + String chat_id = String(bot.messages[i].chat_id); + String text = bot.messages[i].text; + + String from_name = bot.messages[i].from_name; + if (from_name == "") from_name = "Guest"; + // Call the function for understand the message + msgInterpretation(from_name, text, chat_id, bot.messages[i].type); + } +} + +void msgInterpretation(String from_name, String text, String chat_id, String message_type) { + Serial.print(F("Interpreting message: ")); Serial.println(text); + Serial.print(F("Type: ")); Serial.println(message_type); + Serial.print(F("From: ")); Serial.println(from_name); + + if (text == "/start") { // First interaction of user + String welcome = "Hi " + from_name + "!\n"; + welcome += "I am your Telegram Bot running on ESP32.\n\n"; + welcome += "Select one of the /options below!\n\n"; + String keyboardJson = "[[\"/ledon\", \"/ledoff\"],[\"/blink\", \"/PWM\"],[\"/status\"]]"; + bot.sendMessageWithReplyKeyboard(chat_id, welcome, "Markdown", keyboardJson, true); + } + + if (text == "/options") { // List out the custom keyboard + String keyboardJson = "[[\"/ledon\", \"/ledoff\"],[\"/blink\", \"/PWM\"],[\"/status\"]]"; + bot.sendMessageWithReplyKeyboard(chat_id, "Choose from one of the following options", "", keyboardJson, true); + } + + if (text == "/status") { // Report present ledmode to user + String response = "LED is "; + switch (ledmode){ + case ON: + response += "on"; + break; + case OFF: + response += "off"; + break; + case BLINK: + response += "blinking"; + break; + case PWM: + response += "PWMing"; + break; + } + bot.sendMessage(chat_id, response, ""); + } + + if (text == "/ledon") { + ledmode = ON; + ledcDetachPin(ledPin); // detach pin from ledc + digitalWrite(ledPin, LOW); // turn the LED on (drive pin LOW) + Serial.println(F("Turning LED on")); + bot.sendMessage(chat_id, "Turning LED on", ""); + } + + if (text == "/ledoff") { + ledmode = OFF; + ledcDetachPin(ledPin); // detach pin from ledc + digitalWrite(ledPin, HIGH); // turn the LED off (drive pin HIGH) + Serial.println(F("Turning LED off")); + bot.sendMessage(chat_id, "Turning LED off", ""); + } + + if (text == "/blink") { + ledmode = BLINK; + // We use ledc for blinking by setting PWM at a low frequency + ledcSetup(0, 1, 8); // Channel, Freq., Resolution + ledcAttachPin(ledPin, 0); // Pin, Channel + ledcWrite(0, 192); // Channel, Duty (stay off for 90% time) (remember inverse polarity!) + Serial.println(F("Blink set")); + bot.sendMessage(chat_id, "Blink set", ""); + } + + if (text == "/PWM") { // Send an inline keyboard for seleting PWM values (percentage) + // For inline keyboard markup, see https://core.telegram.org/bots/api#inlinekeyboardmarkup + String keyboardJson = "[[{ \"text\" : \"0\", \"callback_data\" : \"0\" }],"; + keyboardJson += "[{ \"text\" : \"10\", \"callback_data\" : \"10\" },"; + keyboardJson += "{ \"text\" : \"20\", \"callback_data\" : \"20\" },"; + keyboardJson += "{ \"text\" : \"30\", \"callback_data\" : \"30\" }],"; + keyboardJson += "[{ \"text\" : \"40\", \"callback_data\" : \"40\" },"; + keyboardJson += "{ \"text\" : \"50\", \"callback_data\" : \"50\" },"; + keyboardJson += "{ \"text\" : \"60\", \"callback_data\" : \"60\" }],"; + keyboardJson += "[{ \"text\" : \"70\", \"callback_data\" : \"70\" },"; + keyboardJson += "{ \"text\" : \"80\", \"callback_data\" : \"80\" },"; + keyboardJson += "{ \"text\" : \"90\", \"callback_data\" : \"90\" }],"; + keyboardJson += "[{ \"text\" : \"100\", \"callback_data\" : \"100\" }]]"; + Serial.println(F("Sending PWM keyboard")); + bot.sendMessageWithInlineKeyboard(chat_id, "Set PWM level", "", keyboardJson); + } + + if(message_type=="callback_query") { // Received when user taps a button on inline keyboard + // In our case, callback_query is only received for PWM values. In other cases you may + // want to append an identifier to the values sent in 'callback_data' (e.g. 'duty=10') + // and then check for it here using text.startsWith("duty=") or something similar. + ledmode = PWM; // set proper LED mode + uint8_t duty = text.toInt(); // Convert value to int + duty = duty*2.55; // For duty between 0 - 100%, actual duty would be between 0 - 255 + + // We use ledc for PWM + ledcSetup(0, 5000, 8); // Channel, Freq., Resolution + ledcAttachPin(ledPin, 0); // Pin, Channel + ledcWrite(0, 255-duty); // Channel, Duty (255 - x to inverse polarity) + Serial.println(F("PWM set")); + String message = "PWM set with duty "; + message += String(duty); + bot.sendMessage(chat_id, message, ""); + } +} From 036926fb5f259e10da66ea4f416a3c24c534e29f Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 23:15:48 +0530 Subject: [PATCH 08/22] Added reference to ESP32 in documentation --- src/UniversalTelegramBot.cpp | 2 +- src/UniversalTelegramBot.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 05129d8..587106e 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -2,7 +2,7 @@ Copyright (c) 2015 Giancarlo Bacchio. All right reserved. TelegramBot - Library to create your own Telegram Bot using -ESP8266 on Arduino IDE. +ESP8266 or ESP32 on Arduino IDE. Ref. Library at https:github/esp8266/Arduino This library is free software; you can redistribute it and/or diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 9603069..3a2193b 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -2,7 +2,7 @@ Copyright (c) 2015 Giancarlo Bacchio. All right reserved. TelegramBot - Library to create your own Telegram Bot using -ESP8266 on Arduino IDE. +ESP8266 or ESP32 on Arduino IDE. Ref. Library at https:github/esp8266/Arduino This library is free software; you can redistribute it and/or From eaeb1a26d8c1a579f675a5558e4c7b696c9beed0 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 23:41:22 +0530 Subject: [PATCH 09/22] Attempting Travis update and added esp32dev env to platformio.ini --- .travis.yml | 1 + platformio.ini | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8fb1cd3..2304594 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,6 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini + - SCRIPT=platformioSingle EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: diff --git a/platformio.ini b/platformio.ini index 2280717..f555b13 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,3 +15,9 @@ platform = espressif8266 board = d1_mini framework = arduino lib_deps = WifiManager, ${common.lib_deps_external} + +[env:esp32dev] +platform = espressif32_stage +board = esp32dev +framework = arduino +lib_deps = WifiManager, ${common.lib_deps_external} From f28f01d004c3279a88e5b4e5b240466f65222f7c Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Wed, 3 Jan 2018 23:53:02 +0530 Subject: [PATCH 10/22] Removing entry from Travis. I don't understand it. Help would be appreciated --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2304594..a6877cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - - SCRIPT=platformioSingle EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + #- SCRIPT=platformioSingle EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: From fa81d6a260935fb4238718c7ca0cbd2483c32399 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Thu, 4 Jan 2018 00:05:52 +0530 Subject: [PATCH 11/22] Trying Travis again --- .travis.yml | 2 +- examples/ESP32/AdvancedLED_platformio/platformio.ini | 4 +++- scripts/travis/platformio.sh | 3 +++ 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 scripts/travis/platformio.sh diff --git a/.travis.yml b/.travis.yml index a6877cb..b669142 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - #- SCRIPT=platformioSingle EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: diff --git a/examples/ESP32/AdvancedLED_platformio/platformio.ini b/examples/ESP32/AdvancedLED_platformio/platformio.ini index 7f7a5ca..9c494b3 100644 --- a/examples/ESP32/AdvancedLED_platformio/platformio.ini +++ b/examples/ESP32/AdvancedLED_platformio/platformio.ini @@ -7,9 +7,11 @@ ; ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html +[common] +lib_deps_external = ArduinoJson, UniversalTelegramBot [env:esp32dev] platform = espressif32_stage board = esp32dev framework = arduino -build_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL +lib_deps = ${common.lib_deps_external} diff --git a/scripts/travis/platformio.sh b/scripts/travis/platformio.sh new file mode 100644 index 0000000..d977a23 --- /dev/null +++ b/scripts/travis/platformio.sh @@ -0,0 +1,3 @@ +#!/bin/sh -eux + +platformio ci $PWD/examples/$BOARDTYPE$EXAMPLE_FOLDER$EXAMPLE_NAME/ -b $BOARD From 37d0495871d002ddd53bdc5dbdf109569c252c3c Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Thu, 4 Jan 2018 00:11:01 +0530 Subject: [PATCH 12/22] Ugh! I give up on Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b669142..f340fa4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - - SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + #- SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: From 94f9dc8e78959e7039187a113d6b1a9baab26dbb Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Thu, 4 Jan 2018 00:25:25 +0530 Subject: [PATCH 13/22] Trying Travis once more --- .travis.yml | 2 +- examples/ESP32/AdvancedLED_platformio/platformio.ini | 2 +- scripts/travis/platformio.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index f340fa4..b669142 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - #- SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: diff --git a/examples/ESP32/AdvancedLED_platformio/platformio.ini b/examples/ESP32/AdvancedLED_platformio/platformio.ini index 9c494b3..b29152d 100644 --- a/examples/ESP32/AdvancedLED_platformio/platformio.ini +++ b/examples/ESP32/AdvancedLED_platformio/platformio.ini @@ -8,7 +8,7 @@ ; Please visit documentation for the other options and examples ; http://docs.platformio.org/page/projectconf.html [common] -lib_deps_external = ArduinoJson, UniversalTelegramBot +lib_deps_external = ArduinoJson [env:esp32dev] platform = espressif32_stage diff --git a/scripts/travis/platformio.sh b/scripts/travis/platformio.sh index d977a23..f778850 100644 --- a/scripts/travis/platformio.sh +++ b/scripts/travis/platformio.sh @@ -1,3 +1,3 @@ #!/bin/sh -eux -platformio ci $PWD/examples/$BOARDTYPE$EXAMPLE_FOLDER$EXAMPLE_NAME/ -b $BOARD +platformio ci $PWD/examples/$BOARDTYPE$EXAMPLE_FOLDER$EXAMPLE_NAME/ -b $BOARD --lib="." From fa5d1e8188769cb10f1b6e9432e69880adca57a2 Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Thu, 4 Jan 2018 00:33:02 +0530 Subject: [PATCH 14/22] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b669142..2011be7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - - SCRIPT=platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformio PLATFORMIO_CI_SRC=examples/ESP32/AdvancedLED_platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: From 551271ee16d943cf7eea4ee0a93b058250987b0f Mon Sep 17 00:00:00 2001 From: Pranav Sharma Date: Thu, 4 Jan 2018 13:30:05 +0530 Subject: [PATCH 15/22] Uodate .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2011be7..c7fda83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,7 +20,7 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - - SCRIPT=platformio PLATFORMIO_CI_SRC=examples/ESP32/AdvancedLED_platformio EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformio PLATFORMIO_CI_SRC=src EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: From 63166ee2d6adcd538be724c43eb3e3fb8682bee8 Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Thu, 15 Feb 2018 21:01:15 +0000 Subject: [PATCH 16/22] Tidying up branch --- .travis.yml | 13 +- examples/ESP32/ChannelPost/ChannelPost.ino | 66 ++++++++++ examples/ESP32/ChatAction/ChatAction.ino | 99 +++++++++++++++ examples/ESP32/ChatAction/README.md | 13 ++ .../InlineKeyboardMarkup.ino | 93 ++++++++++++++ examples/ESP32/CustomKeyboard/README.md | 28 +++++ .../ReplyKeyboardMarkup.ino | 114 ++++++++++++++++++ examples/ESP32/EchoBot/EchoBot.ino | 61 ++++++++++ examples/ESP32/EchoBot/README.md | 15 +++ examples/ESP32/FlashLED/FlashLED.ino | 111 +++++++++++++++++ examples/ESP32/FlashLED/README.md | 15 +++ examples/ESP32/Location/Location.ino | 87 +++++++++++++ examples/ESP32/LongPoll/LongPoll.ino | 66 ++++++++++ platformio.ini | 2 +- .../AdvancedLED}/.gitignore | 0 .../AdvancedLED}/.travis.yml | 0 .../AdvancedLED}/README.md | 0 .../AdvancedLED}/platformio.ini | 0 .../AdvancedLED}/src/main.cpp | 0 19 files changed, 781 insertions(+), 2 deletions(-) create mode 100644 examples/ESP32/ChannelPost/ChannelPost.ino create mode 100644 examples/ESP32/ChatAction/ChatAction.ino create mode 100644 examples/ESP32/ChatAction/README.md create mode 100644 examples/ESP32/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino create mode 100644 examples/ESP32/CustomKeyboard/README.md create mode 100644 examples/ESP32/CustomKeyboard/ReplyKeyboardMarkup/ReplyKeyboardMarkup.ino create mode 100644 examples/ESP32/EchoBot/EchoBot.ino create mode 100644 examples/ESP32/EchoBot/README.md create mode 100644 examples/ESP32/FlashLED/FlashLED.ino create mode 100644 examples/ESP32/FlashLED/README.md create mode 100644 examples/ESP32/Location/Location.ino create mode 100644 examples/ESP32/LongPoll/LongPoll.ino rename {examples/ESP32/AdvancedLED_platformio => platformioExamples/AdvancedLED}/.gitignore (100%) rename {examples/ESP32/AdvancedLED_platformio => platformioExamples/AdvancedLED}/.travis.yml (100%) rename {examples/ESP32/AdvancedLED_platformio => platformioExamples/AdvancedLED}/README.md (100%) rename {examples/ESP32/AdvancedLED_platformio => platformioExamples/AdvancedLED}/platformio.ini (100%) rename {examples/ESP32/AdvancedLED_platformio => platformioExamples/AdvancedLED}/src/main.cpp (100%) diff --git a/.travis.yml b/.travis.yml index c7fda83..2a539e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ cache: - "~/.platformio" env: + # ESP8266 - SCRIPT=platformioSingle EXAMPLE_NAME=EchoBot EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ReplyKeyboardMarkup EXAMPLE_FOLDER=/CustomKeyboard/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=InlineKeyboardMarkup EXAMPLE_FOLDER=/CustomKeyboard/ BOARDTYPE=ESP8266 BOARD=d1_mini @@ -20,7 +21,17 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=PhotoFromFileID EXAMPLE_FOLDER=/SendPhoto/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini - - SCRIPT=platformio PLATFORMIO_CI_SRC=src EXAMPLE_NAME=AdvancedLED_platformio EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=ChatAction EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini + - SCRIPT=platformioSingle EXAMPLE_NAME=LongPoll EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini + # ESP32 + - SCRIPT=platformioSingle EXAMPLE_NAME=EchoBot EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=ReplyKeyboardMarkup EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=InlineKeyboardMarkup EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=FlashLED EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=ChatAction EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=LongPoll EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev install: diff --git a/examples/ESP32/ChannelPost/ChannelPost.ino b/examples/ESP32/ChannelPost/ChannelPost.ino new file mode 100644 index 0000000..4d2f92f --- /dev/null +++ b/examples/ESP32/ChannelPost/ChannelPost.ino @@ -0,0 +1,66 @@ +/******************************************************************* +* An example of bot that echos back any messages received, +* including ones from channels +* +* written by Brian Lough +*******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void setup() { + Serial.begin(115200); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + for (int i=0; i +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done +bool Start = false; + +void handleNewMessages(int numNewMessages) { + Serial.println("handleNewMessages"); + Serial.println(String(numNewMessages)); + + for (int i=0; i Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP32/ChatAction/README.md b/examples/ESP32/ChatAction/README.md new file mode 100644 index 0000000..46e3014 --- /dev/null +++ b/examples/ESP32/ChatAction/README.md @@ -0,0 +1,13 @@ +#ESP8266 - Chat Action + +This is a basic example of how to use chat action using UniversalTelegramBot for ESP8266 based boards. + +Application originally written by [Giancarlo Bacchio](giancarlo.bacchio@gmail.com) for [ESP8266-TelegramBot library](https://github.com/Gianbacchio/ESP8266-TelegramBot) + +Adapted by [Brian Lough](https://github.com/witnessmenow) + +NOTE: You will need to enter your SSID, password and bot Token for the example to work. + +## License + +You may copy, distribute and modify the software provided that modifications are described and licensed for free under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html). Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html), but applications that use the library don't have to be. diff --git a/examples/ESP32/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino b/examples/ESP32/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino new file mode 100644 index 0000000..26894d4 --- /dev/null +++ b/examples/ESP32/CustomKeyboard/InlineKeyboardMarkup/InlineKeyboardMarkup.ino @@ -0,0 +1,93 @@ +/******************************************************************* + An example of how to use a custom reply keyboard markup. + + + written by Vadim Sinitski (modified by Brian Lough) + *******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void handleNewMessages(int numNewMessages) { + + for (int i = 0; i < numNewMessages; i++) { + + // Inline buttons with callbacks when pressed will raise a callback_query message + if (bot.messages[i].type == "callback_query") { + Serial.print("Call back button pressed by: "); + Serial.println(bot.messages[i].from_id); + Serial.print("Data on the button: "); + Serial.println(bot.messages[i].text); + bot.sendMessage(bot.messages[i].from_id, bot.messages[i].text, ""); + } else { + String chat_id = String(bot.messages[i].chat_id); + String text = bot.messages[i].text; + + String from_name = bot.messages[i].from_name; + if (from_name == "") from_name = "Guest"; + + if (text == "/options") { + String keyboardJson = "[[{ \"text\" : \"Go to Google\", \"url\" : \"https://www.google.com\" }],[{ \"text\" : \"Send\", \"callback_data\" : \"This was sent by inline\" }]]"; + bot.sendMessageWithInlineKeyboard(chat_id, "Choose from one of the following options", "", keyboardJson); + } + + if (text == "/start") { + String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; + welcome += "This is Inline Keyboard Markup example.\n\n"; + welcome += "/options : returns the inline keyboard\n"; + + bot.sendMessage(chat_id, welcome, "Markdown"); + } + } + } +} + +void setup() { + Serial.begin(115200); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while (numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP32/CustomKeyboard/README.md b/examples/ESP32/CustomKeyboard/README.md new file mode 100644 index 0000000..c8fb2f4 --- /dev/null +++ b/examples/ESP32/CustomKeyboard/README.md @@ -0,0 +1,28 @@ +#Reply Keyboard Markup + +This is an example of how to use reply keyboard markup on a ESP8266 based board. + +![alt text](https://core.telegram.org/file/811140184/1/5YJxx-rostA/ad3f74094485fb97bd "Reply Keyboard example") + +The application will turn on and off an LED based on commands received via telegram. + +#Inline Keyboard Markup + +This is an example of how to use reply keyboard markup on a ESP8266 based board. + + +![alt text](https://core.telegram.org/file/811140999/1/2JSoUVlWKa0/4fad2e2743dc8eda04 "Inline Keyboard example") + +Right now working only URL redirection button. Other features will be added later. + +----------------- + +NOTE: You will need to enter your SSID, password and bot Token for the example to work. + +Application written by [Brian Lough](https://github.com/witnessmenow) + + + +## License + +You may copy, distribute and modify the software provided that modifications are described and licensed for free under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html). Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html), but applications that use the library don't have to be. diff --git a/examples/ESP32/CustomKeyboard/ReplyKeyboardMarkup/ReplyKeyboardMarkup.ino b/examples/ESP32/CustomKeyboard/ReplyKeyboardMarkup/ReplyKeyboardMarkup.ino new file mode 100644 index 0000000..dd3e08c --- /dev/null +++ b/examples/ESP32/CustomKeyboard/ReplyKeyboardMarkup/ReplyKeyboardMarkup.ino @@ -0,0 +1,114 @@ +/******************************************************************* + * An example of how to use a custom reply keyboard markup. * + * * + * * + * written by Brian Lough * + *******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +const int ledPin = 13; +int ledStatus = 0; + +void handleNewMessages(int numNewMessages) { + Serial.println("handleNewMessages"); + Serial.println(String(numNewMessages)); + + for (int i=0; i Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP32/EchoBot/EchoBot.ino b/examples/ESP32/EchoBot/EchoBot.ino new file mode 100644 index 0000000..041ee56 --- /dev/null +++ b/examples/ESP32/EchoBot/EchoBot.ino @@ -0,0 +1,61 @@ +/******************************************************************* +* An example of bot that echos back any messages received * +* * +* written by Giacarlo Bacchio (Gianbacchio on Github) * +* adapted by Brian Lough * +*******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void setup() { + Serial.begin(115200); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + for (int i=0; i +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done +bool Start = false; + +const int ledPin = 13; +int ledStatus = 0; + +void handleNewMessages(int numNewMessages) { + Serial.println("handleNewMessages"); + Serial.println(String(numNewMessages)); + + for (int i=0; i Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP32/FlashLED/README.md b/examples/ESP32/FlashLED/README.md new file mode 100644 index 0000000..a3e6f08 --- /dev/null +++ b/examples/ESP32/FlashLED/README.md @@ -0,0 +1,15 @@ +#ESP8266 - Flash LED + +This is a basic example of how to receive commands using UniversalTelegramBot for ESP8266 based boards. + +The application will turn on and off an LED based on commands received via telegram. + +Application originally written by [Giancarlo Bacchio](giancarlo.bacchio@gmail.com) for [ESP8266-TelegramBot library](https://github.com/Gianbacchio/ESP8266-TelegramBot) + +Adapted by [Brian Lough](https://github.com/witnessmenow) + +NOTE: You will need to enter your SSID, password and bot Token for the example to work. + +## License + +You may copy, distribute and modify the software provided that modifications are described and licensed for free under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html). Derivatives works (including modifications or anything statically linked to the library) can only be redistributed under [LGPL-3](http://www.gnu.org/licenses/lgpl-3.0.html), but applications that use the library don't have to be. diff --git a/examples/ESP32/Location/Location.ino b/examples/ESP32/Location/Location.ino new file mode 100644 index 0000000..3253017 --- /dev/null +++ b/examples/ESP32/Location/Location.ino @@ -0,0 +1,87 @@ +/******************************************************************* + * An example of recieving location Data + * + * + * By Brian Lough + *******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "SSID"; // your network SSID (name) +char password[] = "password"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void handleNewMessages(int numNewMessages) { + + for (int i = 0; i < numNewMessages; i++) { + + String chat_id = String(bot.messages[i].chat_id); + String text = bot.messages[i].text; + + String from_name = bot.messages[i].from_name; + if (from_name == "") from_name = "Guest"; + + if (bot.messages[i].longitude != 0 || bot.messages[i].latitude != 0) { + Serial.print("Long: "); + Serial.println(String(bot.messages[i].longitude, 6)); + Serial.print("Lat: "); + Serial.println(String(bot.messages[i].latitude, 6)); + + String message = "Long: " + String(bot.messages[i].longitude, 6) + "\n"; + message += "Lat: " + String(bot.messages[i].latitude, 6) + "\n"; + bot.sendMessage(chat_id, message, "Markdown"); + } else if (text == "/start") { + String welcome = "Welcome to Universal Arduino Telegram Bot library, " + from_name + ".\n"; + welcome += "Share a location or a live location and the bot will respond with the co-ords\n"; + + bot.sendMessage(chat_id, welcome, "Markdown"); + } + } +} + +void setup() { + Serial.begin(115200); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while (numNewMessages) { + Serial.println("got response"); + handleNewMessages(numNewMessages); + numNewMessages = bot.getUpdates(bot.last_message_received + 1); + } + + Bot_lasttime = millis(); + } +} diff --git a/examples/ESP32/LongPoll/LongPoll.ino b/examples/ESP32/LongPoll/LongPoll.ino new file mode 100644 index 0000000..83b0728 --- /dev/null +++ b/examples/ESP32/LongPoll/LongPoll.ino @@ -0,0 +1,66 @@ +/******************************************************************* +* An example of setting a long poll, this will mean the request +* for new messages will wait the specified amount of time before +* returning with no messages +* +* This should reduce amount of data used by the bot +* +* written by Brian Lough +*******************************************************************/ +#include +#include +#include + +// Initialize Wifi connection to the router +char ssid[] = "XXXXXX"; // your network SSID (name) +char password[] = "YYYYYY"; // your network key + +// Initialize Telegram BOT +#define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) + +WiFiClientSecure client; +UniversalTelegramBot bot(BOTtoken, client); + +int Bot_mtbs = 1000; //mean time between scan messages +long Bot_lasttime; //last time messages' scan has been done + +void setup() { + Serial.begin(115200); + + // Attempt to connect to Wifi network: + Serial.print("Connecting Wifi: "); + Serial.println(ssid); + + // Set WiFi to station mode and disconnect from an AP if it was Previously + // connected + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + + while (WiFi.status() != WL_CONNECTED) { + Serial.print("."); + delay(500); + } + + bot.longPoll = 60; + + Serial.println(""); + Serial.println("WiFi connected"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + if (millis() > Bot_lasttime + Bot_mtbs) { + int numNewMessages = bot.getUpdates(bot.last_message_received + 1); + + while(numNewMessages) { + Serial.println("got response"); + for (int i=0; i Date: Thu, 15 Feb 2018 21:19:05 +0000 Subject: [PATCH 17/22] Fixing tests --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a539e0..4c8080d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,8 +25,8 @@ env: - SCRIPT=platformioSingle EXAMPLE_NAME=LongPoll EXAMPLE_FOLDER=/ BOARDTYPE=ESP8266 BOARD=d1_mini # ESP32 - SCRIPT=platformioSingle EXAMPLE_NAME=EchoBot EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev - - SCRIPT=platformioSingle EXAMPLE_NAME=ReplyKeyboardMarkup EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev - - SCRIPT=platformioSingle EXAMPLE_NAME=InlineKeyboardMarkup EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=ReplyKeyboardMarkup EXAMPLE_FOLDER=/CustomKeyboard/ BOARDTYPE=ESP32 BOARD=esp32dev + - SCRIPT=platformioSingle EXAMPLE_NAME=InlineKeyboardMarkup EXAMPLE_FOLDER=/CustomKeyboard/ BOARDTYPE=ESP32 BOARD=esp32dev - SCRIPT=platformioSingle EXAMPLE_NAME=FlashLED EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev - SCRIPT=platformioSingle EXAMPLE_NAME=Location EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev - SCRIPT=platformioSingle EXAMPLE_NAME=ChannelPost EXAMPLE_FOLDER=/ BOARDTYPE=ESP32 BOARD=esp32dev From 76f2cbddbfb61e07f08981abab83611ca6af832d Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Thu, 15 Feb 2018 21:23:50 +0000 Subject: [PATCH 18/22] removing logic around running the client disconnect code --- src/UniversalTelegramBot.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 587106e..5300f0e 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -693,10 +693,8 @@ bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { } void UniversalTelegramBot::closeClient(){ -#ifdef ESP32 if(client->connected()){ if(_debug){Serial.println(F("Closing client")); } client->stop(); } -#endif } From 89beefdd51f35e6d0b1403fd18bb9b935ddebe92 Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Wed, 21 Mar 2018 13:47:00 +0000 Subject: [PATCH 19/22] Adding F() to serial prints where possible --- src/UniversalTelegramBot.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 5300f0e..48c13af 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -326,7 +326,7 @@ bool UniversalTelegramBot::getMe() { ***************************************************************/ int UniversalTelegramBot::getUpdates(long offset) { - if (_debug) Serial.println("GET Update Messages"); + if (_debug) Serial.println(F("GET Update Messages")); String command = "bot"+_token+"/getUpdates?offset="+String(offset)+"&limit="+String(HANDLE_MESSAGES); if(longPoll > 0) { @@ -342,9 +342,9 @@ int UniversalTelegramBot::getUpdates(long offset) { } else { if (_debug) { - Serial.print("incoming message length"); + Serial.print(F("incoming message length")); Serial.println(response.length()); - Serial.println("Creating DynamicJsonBuffer"); + Serial.println(F("Creating DynamicJsonBuffer")); } // Parse response into Json object @@ -471,7 +471,7 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, String parse_mode) { bool sent = false; - if (_debug) Serial.println("SEND Simple Message"); + if (_debug) Serial.println(F("SEND Simple Message")); long sttime = millis(); if (text!="") { From a12c462de1248b23ecfc80e23c7304ef97806be4 Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Wed, 21 Mar 2018 14:41:28 +0000 Subject: [PATCH 20/22] Making timeout configurable --- src/UniversalTelegramBot.cpp | 6 +++--- src/UniversalTelegramBot.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index 48c13af..e416941 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -62,7 +62,7 @@ String UniversalTelegramBot::sendGetToTelegram(String command) { client->println("GET /"+command); now=millis(); avail=false; - while (millis() - now < longPoll * 1000 + 1500) { + while (millis() - now < longPoll * 1000 + waitForResponse) { while (client->available()) { char c = client->read(); //Serial.write(c); @@ -125,7 +125,7 @@ String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject& payl responseReceived=false; bool finishedHeaders = false; bool currentLineIsBlank = true; - while (millis()-now<1500) { + while (millis() - now < waitForResponse) { while (client->available()) { char c = client->read(); responseReceived=true; @@ -255,7 +255,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str now=millis(); bool finishedHeaders = false; bool currentLineIsBlank = true; - while (millis()-now<1500) { + while (millis() - now < waitForResponse) { while (client->available()) { char c = client->read(); responseReceived=true; diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 3a2193b..5d1b0b8 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -87,6 +87,7 @@ class UniversalTelegramBot String userName; int longPoll = 0; bool _debug = false; + int waitForResponse = 1500; private: //JsonObject * parseUpdates(String response); From 052ecc4cfb623b629c51aeffc9b64017366f3fac Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Wed, 21 Mar 2018 15:36:55 +0000 Subject: [PATCH 21/22] Running src folder through clang format --- src/UniversalTelegramBot.cpp | 537 +++++++++++++++++++---------------- src/UniversalTelegramBot.h | 107 +++---- 2 files changed, 352 insertions(+), 292 deletions(-) diff --git a/src/UniversalTelegramBot.cpp b/src/UniversalTelegramBot.cpp index e416941..e68ba77 100644 --- a/src/UniversalTelegramBot.cpp +++ b/src/UniversalTelegramBot.cpp @@ -1,157 +1,163 @@ /* -Copyright (c) 2015 Giancarlo Bacchio. All right reserved. - -TelegramBot - Library to create your own Telegram Bot using -ESP8266 or ESP32 on Arduino IDE. -Ref. Library at https:github/esp8266/Arduino - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* **** Note Regarding Client Connection Keeping **** - Client connection is established in functions that directly involve use of client, - i.e sendGetToTelegram, sendPostToTelegram, and sendMultipartFormDataToTelegram. - It is closed at the end of sendMultipartFormDataToTelegram, but not at the - end of sendGetToTelegram and sendPostToTelegram as these may need to keep the - connection alive for respose / response checking. Re-establishing a connection - then wastes time which is noticeable in user experience. - Due to this, it is important that connection be closed manually after calling - sendGetToTelegram or sendPostToTelegram by calling closeClient(); - Failure to close connection causes memory leakage, and SSL errors on ESP32 - Note: closeClient() only closes connections on ESP32 (#ifdef ESP32). -*/ + Copyright (c) 2018 Brian Lough. All right reserved. + + UniversalTelegramBot - Library to create your own Telegram Bot using + ESP8266 or ESP32 on Arduino IDE. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + **** Note Regarding Client Connection Keeping **** + Client connection is established in functions that directly involve use of + client, i.e sendGetToTelegram, sendPostToTelegram, and + sendMultipartFormDataToTelegram. It is closed at the end of + sendMultipartFormDataToTelegram, but not at the end of sendGetToTelegram and + sendPostToTelegram as these may need to keep the connection alive for respose + / response checking. Re-establishing a connection then wastes time which is + noticeable in user experience. Due to this, it is important that connection + be closed manually after calling sendGetToTelegram or sendPostToTelegram by + calling closeClient(); Failure to close connection causes memory leakage and + SSL errors + */ #include "UniversalTelegramBot.h" -UniversalTelegramBot::UniversalTelegramBot(String token, Client &client) { +UniversalTelegramBot::UniversalTelegramBot(String token, Client &client) { _token = token; this->client = &client; } String UniversalTelegramBot::sendGetToTelegram(String command) { - String mess = ""; - long now; - bool avail; - - // Connect with api.telegram.org if not already connected - if(!client->connected()){ - if (_debug) Serial.println(F("[BOT]Connecting to server")); - if(!client->connect(HOST, SSL_PORT)){ - if (_debug) Serial.println(F("[BOT]Conection error")); + String mess = ""; + long now; + bool avail; + + // Connect with api.telegram.org if not already connected + if (!client->connected()) { + if (_debug) + Serial.println(F("[BOT]Connecting to server")); + if (!client->connect(HOST, SSL_PORT)) { + if (_debug) + Serial.println(F("[BOT]Conection error")); } } - if (client->connected()) { - - if (_debug) Serial.println(F(".... connected to server")); - - String a=""; - char c; - int ch_count=0; - client->println("GET /"+command); - now=millis(); - avail=false; - while (millis() - now < longPoll * 1000 + waitForResponse) { - while (client->available()) { - char c = client->read(); - //Serial.write(c); - if (ch_count < maxMessageLength) { - mess=mess+c; - ch_count++; - } - avail=true; - } - if (avail) { + if (client->connected()) { + + if (_debug) + Serial.println(F(".... connected to server")); + + String a = ""; + char c; + int ch_count = 0; + client->println("GET /" + command); + now = millis(); + avail = false; + while (millis() - now < longPoll * 1000 + waitForResponse) { + while (client->available()) { + char c = client->read(); + // Serial.write(c); + if (ch_count < maxMessageLength) { + mess = mess + c; + ch_count++; + } + avail = true; + } + if (avail) { if (_debug) { Serial.println(); Serial.println(mess); Serial.println(); } - break; - } - } - } + break; + } + } + } - return mess; + return mess; } -String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject& payload){ +String UniversalTelegramBot::sendPostToTelegram(String command, + JsonObject &payload) { String body = ""; String headers = ""; - long now; - bool responseReceived; - - // Connect with api.telegram.org if not already connected - if(!client->connected()){ - if (_debug) Serial.println(F("[BOT Client]Connecting to server")); - if(!client->connect(HOST, SSL_PORT)){ - if (_debug) Serial.println(F("[BOT Client]Conection error")); + long now; + bool responseReceived; + + // Connect with api.telegram.org if not already connected + if (!client->connected()) { + if (_debug) + Serial.println(F("[BOT Client]Connecting to server")); + if (!client->connect(HOST, SSL_PORT)) { + if (_debug) + Serial.println(F("[BOT Client]Conection error")); } } if (client->connected()) { // POST URI - client->print("POST /" + command); client->println(F(" HTTP/1.1")); + client->print("POST /" + command); + client->println(F(" HTTP/1.1")); // Host header - client->print(F("Host:")); client->println(HOST); + client->print(F("Host:")); + client->println(HOST); // JSON content type client->println(F("Content-Type: application/json")); // Content length int length = payload.measureLength(); - client->print(F("Content-Length:")); client->println(length); + client->print(F("Content-Length:")); + client->println(length); // End of headers client->println(); // POST message body - //json.printTo(client); // very slow ?? + // json.printTo(client); // very slow ?? String out; payload.printTo(out); client->println(out); - int ch_count=0; + int ch_count = 0; char c; - now=millis(); - responseReceived=false; + now = millis(); + responseReceived = false; bool finishedHeaders = false; bool currentLineIsBlank = true; - while (millis() - now < waitForResponse) { - while (client->available()) { - char c = client->read(); - responseReceived=true; - + while (millis() - now < waitForResponse) { + while (client->available()) { + char c = client->read(); + responseReceived = true; - if(!finishedHeaders){ + if (!finishedHeaders) { if (currentLineIsBlank && c == '\n') { finishedHeaders = true; - } - else { + } else { headers = headers + c; } } else { if (ch_count < maxMessageLength) { - body=body+c; + body = body + c; ch_count++; - } + } } if (c == '\n') { currentLineIsBlank = true; - }else if (c != '\r') { + } else if (c != '\r') { currentLineIsBlank = false; } - - } + } if (responseReceived) { if (_debug) { @@ -159,31 +165,33 @@ String UniversalTelegramBot::sendPostToTelegram(String command, JsonObject& payl Serial.println(body); Serial.println(); } - break; - } - } + break; + } + } } return body; } -String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, String binaryProperyName, - String fileName, String contentType, - String chat_id, int fileSize, +String UniversalTelegramBot::sendMultipartFormDataToTelegram( + String command, String binaryProperyName, String fileName, + String contentType, String chat_id, int fileSize, MoreDataAvailable moreDataAvailableCallback, GetNextByte getNextByteCallback) { String body = ""; String headers = ""; - long now; - bool responseReceived; + long now; + bool responseReceived; String boundry = F("------------------------b8f610217e83e29b"); // Connect with api.telegram.org if not already connected - if(!client->connected()){ - if (_debug) Serial.println(F("[BOT Client]Connecting to server")); - if(!client->connect(HOST, SSL_PORT)){ - if (_debug) Serial.println(F("[BOT Client]Conection error")); + if (!client->connected()) { + if (_debug) + Serial.println(F("[BOT Client]Connecting to server")); + if (!client->connect(HOST, SSL_PORT)) { + if (_debug) + Serial.println(F("[BOT Client]Conection error")); } } if (client->connected()) { @@ -192,45 +200,53 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str String end_request = ""; start_request = start_request + "--" + boundry + "\r\n"; - start_request = start_request + "content-disposition: form-data; name=\"chat_id\"" + "\r\n"; + start_request = start_request + + "content-disposition: form-data; name=\"chat_id\"" + "\r\n"; start_request = start_request + "\r\n"; start_request = start_request + chat_id + "\r\n"; start_request = start_request + "--" + boundry + "\r\n"; - start_request = start_request + "content-disposition: form-data; name=\"" + binaryProperyName + "\"; filename=\"" + fileName + "\"" + "\r\n"; + start_request = start_request + "content-disposition: form-data; name=\"" + + binaryProperyName + "\"; filename=\"" + fileName + "\"" + + "\r\n"; start_request = start_request + "Content-Type: " + contentType + "\r\n"; start_request = start_request + "\r\n"; - end_request = end_request + "\r\n"; end_request = end_request + "--" + boundry + "--" + "\r\n"; - client->print("POST /bot"+_token+"/" + command); client->println(F(" HTTP/1.1")); + client->print("POST /bot" + _token + "/" + command); + client->println(F(" HTTP/1.1")); // Host header - client->print(F("Host: ")); client->println(HOST); + client->print(F("Host: ")); + client->println(HOST); client->println(F("User-Agent: arduino/1.0")); client->println(F("Accept: */*")); - int contentLength = fileSize + start_request.length() + end_request.length(); - if (_debug) Serial.println("Content-Length: " + String(contentLength)); - client->print("Content-Length: "); client->println(String(contentLength)); + int contentLength = + fileSize + start_request.length() + end_request.length(); + if (_debug) + Serial.println("Content-Length: " + String(contentLength)); + client->print("Content-Length: "); + client->println(String(contentLength)); client->println("Content-Type: multipart/form-data; boundary=" + boundry); client->println(""); client->print(start_request); - if (_debug) Serial.print(start_request); + if (_debug) + Serial.print(start_request); byte buffer[512]; int count = 0; char ch; while (moreDataAvailableCallback()) { buffer[count] = getNextByteCallback(); - //client->write(ch); - //Serial.write(ch); + // client->write(ch); + // Serial.write(ch); count++; - if(count == 512){ - //yield(); + if (count == 512) { + // yield(); if (_debug) { Serial.println(F("Sending full buffer")); } @@ -239,7 +255,7 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str } } - if(count > 0) { + if (count > 0) { if (_debug) { Serial.println(F("Sending remaining buffer")); } @@ -247,40 +263,38 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str } client->print(end_request); - if (_debug) Serial.print(end_request); + if (_debug) + Serial.print(end_request); count = 0; - int ch_count=0; + int ch_count = 0; char c; - now=millis(); + now = millis(); bool finishedHeaders = false; bool currentLineIsBlank = true; while (millis() - now < waitForResponse) { while (client->available()) { char c = client->read(); - responseReceived=true; - + responseReceived = true; - if(!finishedHeaders){ + if (!finishedHeaders) { if (currentLineIsBlank && c == '\n') { finishedHeaders = true; - } - else { + } else { headers = headers + c; } } else { if (ch_count < maxMessageLength) { - body=body+c; + body = body + c; ch_count++; } } if (c == '\n') { currentLineIsBlank = true; - }else if (c != '\r') { + } else if (c != '\r') { currentLineIsBlank = false; } - } if (responseReceived) { @@ -299,14 +313,15 @@ String UniversalTelegramBot::sendMultipartFormDataToTelegram(String command, Str } bool UniversalTelegramBot::getMe() { - String command = "bot"+_token+"/getMe"; - String response = sendGetToTelegram(command); //receive reply from telegram.org + String command = "bot" + _token + "/getMe"; + String response = + sendGetToTelegram(command); // receive reply from telegram.org DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.parseObject(response); + JsonObject &root = jsonBuffer.parseObject(response); closeClient(); - if(root.success()) { + if (root.success()) { if (root.containsKey("result")) { String _name = root["result"]["first_name"]; String _username = root["result"]["username"]; @@ -320,28 +335,31 @@ bool UniversalTelegramBot::getMe() { } /*************************************************************** -* GetUpdates - function to receive messages from telegram * -* (Argument to pass: the last+1 message to read) * -* Returns the number of new messages * -***************************************************************/ -int UniversalTelegramBot::getUpdates(long offset) { - - if (_debug) Serial.println(F("GET Update Messages")); - - String command = "bot"+_token+"/getUpdates?offset="+String(offset)+"&limit="+String(HANDLE_MESSAGES); - if(longPoll > 0) { + * GetUpdates - function to receive messages from telegram * + * (Argument to pass: the last+1 message to read) * + * Returns the number of new messages * + ***************************************************************/ +int UniversalTelegramBot::getUpdates(long offset) { + + if (_debug) + Serial.println(F("GET Update Messages")); + + String command = "bot" + _token + "/getUpdates?offset=" + String(offset) + + "&limit=" + String(HANDLE_MESSAGES); + if (longPoll > 0) { command = command + "&timeout=" + String(longPoll); } - String response = sendGetToTelegram(command); //receive reply from telegram.org + String response = + sendGetToTelegram(command); // receive reply from telegram.org if (response == "") { - if(_debug) Serial.println(F("Received empty string in response!")); + if (_debug) + Serial.println(F("Received empty string in response!")); // close the client as there's nothing to do with an empty string closeClient(); return 0; - } - else { - if (_debug) { + } else { + if (_debug) { Serial.print(F("incoming message length")); Serial.println(response.length()); Serial.println(F("Creating DynamicJsonBuffer")); @@ -349,37 +367,45 @@ int UniversalTelegramBot::getUpdates(long offset) { // Parse response into Json object DynamicJsonBuffer jsonBuffer; - JsonObject& root = jsonBuffer.parseObject(response); + JsonObject &root = jsonBuffer.parseObject(response); if (root.success()) { // root.printTo(Serial); - if (_debug) Serial.println(); + if (_debug) + Serial.println(); if (root.containsKey("result")) { int resultArrayLength = root["result"].size(); if (resultArrayLength > 0) { int newMessageIndex = 0; - //Step through all results - for (int i=0; i < resultArrayLength; i++) { - JsonObject& result = root["result"][i]; + // Step through all results + for (int i = 0; i < resultArrayLength; i++) { + JsonObject &result = root["result"][i]; if (processResult(result, newMessageIndex)) { newMessageIndex++; } } - // We will keep the client open because there may be a response to be given + // We will keep the client open because there may be a response to be + // given return newMessageIndex; } else { - if (_debug) Serial.println(F("no new messages")); + if (_debug) + Serial.println(F("no new messages")); } } else { - if (_debug) Serial.println(F("Response contained no 'result'")); + if (_debug) + Serial.println(F("Response contained no 'result'")); } } else { // Parsing failed - if(response.length() < 2){ // Too short a message. Maybe connection issue - if (_debug) Serial.println(F("Parsing error: Message too short")); - } - else{ - // Buffer may not be big enough, increase buffer or reduce max number of messages - if (_debug) Serial.println(F("Failed to parse update, the message could be too big for the buffer")); + if (response.length() < + 2) { // Too short a message. Maybe connection issue + if (_debug) + Serial.println(F("Parsing error: Message too short")); + } else { + // Buffer may not be big enough, increase buffer or reduce max number of + // messages + if (_debug) + Serial.println(F("Failed to parse update, the message could be too " + "big for the buffer")); } } // Close the client as no response is to be given @@ -388,7 +414,7 @@ int UniversalTelegramBot::getUpdates(long offset) { } } -bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { +bool UniversalTelegramBot::processResult(JsonObject &result, int messageIndex) { int update_id = result["update_id"]; // Check have we already dealt with this message (this shouldn't happen!) if (last_message_received != update_id) { @@ -402,10 +428,11 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { messages[messageIndex].latitude = 0; if (result.containsKey("message")) { - JsonObject& message = result["message"]; + JsonObject &message = result["message"]; messages[messageIndex].type = F("message"); messages[messageIndex].from_id = message["from"]["id"].as(); - messages[messageIndex].from_name = message["from"]["first_name"].as(); + messages[messageIndex].from_name = + message["from"]["first_name"].as(); messages[messageIndex].date = message["date"].as(); messages[messageIndex].chat_id = message["chat"]["id"].as(); @@ -415,13 +442,13 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { messages[messageIndex].text = message["text"].as(); } else if (message.containsKey("location")) { - messages[messageIndex].longitude = message["location"]["longitude"].as(); - messages[messageIndex].latitude = message["location"]["latitude"].as(); - + messages[messageIndex].longitude = + message["location"]["longitude"].as(); + messages[messageIndex].latitude = + message["location"]["latitude"].as(); } - } - else if (result.containsKey("channel_post")) { - JsonObject& message = result["channel_post"]; + } else if (result.containsKey("channel_post")) { + JsonObject &message = result["channel_post"]; messages[messageIndex].type = F("channel_post"); messages[messageIndex].text = message["text"].as(); @@ -430,20 +457,23 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { messages[messageIndex].chat_title = message["chat"]["title"].as(); } else if (result.containsKey("callback_query")) { - JsonObject& message = result["callback_query"]; + JsonObject &message = result["callback_query"]; messages[messageIndex].type = F("callback_query"); messages[messageIndex].from_id = message["from"]["id"].as(); - messages[messageIndex].from_name = message["from"]["first_name"].as(); + messages[messageIndex].from_name = + message["from"]["first_name"].as(); messages[messageIndex].text = message["data"].as(); messages[messageIndex].date = message["date"].as(); - messages[messageIndex].chat_id = message["message"]["chat"]["id"].as(); + messages[messageIndex].chat_id = + message["message"]["chat"]["id"].as(); messages[messageIndex].chat_title = F(""); } else if (result.containsKey("edited_message")) { - JsonObject& message = result["edited_message"]; + JsonObject &message = result["edited_message"]; messages[messageIndex].type = F("edited_message"); messages[messageIndex].from_id = message["from"]["id"].as(); - messages[messageIndex].from_name = message["from"]["first_name"].as(); + messages[messageIndex].from_name = + message["from"]["first_name"].as(); messages[messageIndex].date = message["date"].as(); messages[messageIndex].chat_id = message["chat"]["id"].as(); @@ -453,9 +483,10 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { messages[messageIndex].text = message["text"].as(); } else if (message.containsKey("location")) { - messages[messageIndex].longitude = message["location"]["longitude"].as(); - messages[messageIndex].latitude = message["location"]["latitude"].as(); - + messages[messageIndex].longitude = + message["location"]["longitude"].as(); + messages[messageIndex].latitude = + message["location"]["latitude"].as(); } } @@ -465,20 +496,24 @@ bool UniversalTelegramBot::processResult(JsonObject& result, int messageIndex) { } /*********************************************************************** -* SendMessage - function to send message to telegram * -* (Arguments to pass: chat_id, text to transmit and markup(optional)) * -***********************************************************************/ -bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, String parse_mode) { + * SendMessage - function to send message to telegram * + * (Arguments to pass: chat_id, text to transmit and markup(optional)) * + ***********************************************************************/ +bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, + String parse_mode) { bool sent = false; - if (_debug) Serial.println(F("SEND Simple Message")); + if (_debug) + Serial.println(F("SEND Simple Message")); long sttime = millis(); - if (text!="") { - while (millis() < sttime+8000) { // loop for a while to send the message - String command="bot"+_token+"/sendMessage?chat_id="+chat_id+"&text="+text+"&parse_mode="+parse_mode; + if (text != "") { + while (millis() < sttime + 8000) { // loop for a while to send the message + String command = "bot" + _token + "/sendMessage?chat_id=" + chat_id + + "&text=" + text + "&parse_mode=" + parse_mode; String response = sendGetToTelegram(command); - if (_debug) Serial.println(response); + if (_debug) + Serial.println(response); sent = checkForOkResponse(response); if (sent) { break; @@ -489,10 +524,11 @@ bool UniversalTelegramBot::sendSimpleMessage(String chat_id, String text, String return sent; } -bool UniversalTelegramBot::sendMessage(String chat_id, String text, String parse_mode) { +bool UniversalTelegramBot::sendMessage(String chat_id, String text, + String parse_mode) { DynamicJsonBuffer jsonBuffer; - JsonObject& payload = jsonBuffer.createObject(); + JsonObject &payload = jsonBuffer.createObject(); payload["chat_id"] = chat_id; payload["text"] = text; @@ -504,10 +540,12 @@ bool UniversalTelegramBot::sendMessage(String chat_id, String text, String parse return sendPostMessage(payload); } -bool UniversalTelegramBot::sendMessageWithReplyKeyboard(String chat_id, String text, String parse_mode, String keyboard, bool resize, bool oneTime, bool selective) { +bool UniversalTelegramBot::sendMessageWithReplyKeyboard( + String chat_id, String text, String parse_mode, String keyboard, + bool resize, bool oneTime, bool selective) { DynamicJsonBuffer jsonBuffer; - JsonObject& payload = jsonBuffer.createObject(); + JsonObject &payload = jsonBuffer.createObject(); payload["chat_id"] = chat_id; payload["text"] = text; @@ -516,7 +554,7 @@ bool UniversalTelegramBot::sendMessageWithReplyKeyboard(String chat_id, String t payload["parse_mode"] = parse_mode; } - JsonObject& replyMarkup = payload.createNestedObject("reply_markup"); + JsonObject &replyMarkup = payload.createNestedObject("reply_markup"); // Reply keyboard is an array of arrays. // Outer array represents rows @@ -526,7 +564,8 @@ bool UniversalTelegramBot::sendMessageWithReplyKeyboard(String chat_id, String t DynamicJsonBuffer keyboardBuffer; replyMarkup["keyboard"] = keyboardBuffer.parseArray(keyboard); - //Telegram defaults these values to false, so to decrease the size of the payload we will only send them if needed + // Telegram defaults these values to false, so to decrease the size of the + // payload we will only send them if needed if (resize) { replyMarkup["resize_keyboard"] = resize; } @@ -542,10 +581,13 @@ bool UniversalTelegramBot::sendMessageWithReplyKeyboard(String chat_id, String t return sendPostMessage(payload); } -bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, String text, String parse_mode, String keyboard) { +bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, + String text, + String parse_mode, + String keyboard) { DynamicJsonBuffer jsonBuffer; - JsonObject& payload = jsonBuffer.createObject(); + JsonObject &payload = jsonBuffer.createObject(); payload["chat_id"] = chat_id; payload["text"] = text; @@ -554,7 +596,7 @@ bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, String payload["parse_mode"] = parse_mode; } - JsonObject& replyMarkup = payload.createNestedObject("reply_markup"); + JsonObject &replyMarkup = payload.createNestedObject("reply_markup"); DynamicJsonBuffer keyboardBuffer; replyMarkup["inline_keyboard"] = keyboardBuffer.parseArray(keyboard); @@ -563,20 +605,22 @@ bool UniversalTelegramBot::sendMessageWithInlineKeyboard(String chat_id, String } /*********************************************************************** -* SendPostMessage - function to send message to telegram * -* (Arguments to pass: chat_id, text to transmit and markup(optional)) * -***********************************************************************/ -bool UniversalTelegramBot::sendPostMessage(JsonObject& payload) { + * SendPostMessage - function to send message to telegram * + * (Arguments to pass: chat_id, text to transmit and markup(optional)) * + ***********************************************************************/ +bool UniversalTelegramBot::sendPostMessage(JsonObject &payload) { - bool sent=false; - if (_debug) Serial.println(F("SEND Post Message")); - long sttime=millis(); + bool sent = false; + if (_debug) + Serial.println(F("SEND Post Message")); + long sttime = millis(); if (payload.containsKey("text")) { - while (millis() < sttime+8000) { // loop for a while to send the message - String command = "bot"+_token+"/sendMessage"; + while (millis() < sttime + 8000) { // loop for a while to send the message + String command = "bot" + _token + "/sendMessage"; String response = sendPostToTelegram(command, payload); - if (_debug) Serial.println(response); + if (_debug) + Serial.println(response); sent = checkForOkResponse(response); if (sent) { break; @@ -588,18 +632,20 @@ bool UniversalTelegramBot::sendPostMessage(JsonObject& payload) { return sent; } -String UniversalTelegramBot::sendPostPhoto(JsonObject& payload) { +String UniversalTelegramBot::sendPostPhoto(JsonObject &payload) { - bool sent=false; + bool sent = false; String response = ""; - if (_debug) Serial.println(F("SEND Post Photo")); - long sttime=millis(); + if (_debug) + Serial.println(F("SEND Post Photo")); + long sttime = millis(); if (payload.containsKey("photo")) { - while (millis() < sttime+8000) { // loop for a while to send the message - String command = "bot"+_token+"/sendPhoto"; + while (millis() < sttime + 8000) { // loop for a while to send the message + String command = "bot" + _token + "/sendPhoto"; response = sendPostToTelegram(command, payload); - if (_debug) Serial.println(response); + if (_debug) + Serial.println(response); sent = checkForOkResponse(response); if (sent) { break; @@ -611,25 +657,32 @@ String UniversalTelegramBot::sendPostPhoto(JsonObject& payload) { return response; } -String UniversalTelegramBot::sendPhotoByBinary(String chat_id, String contentType, int fileSize, +String UniversalTelegramBot::sendPhotoByBinary( + String chat_id, String contentType, int fileSize, MoreDataAvailable moreDataAvailableCallback, GetNextByte getNextByteCallback) { - if (_debug) Serial.println("SEND Photo"); + if (_debug) + Serial.println("SEND Photo"); - String response = sendMultipartFormDataToTelegram("sendPhoto", "photo", "img.jpg", - contentType, chat_id, fileSize, - moreDataAvailableCallback, getNextByteCallback); + String response = sendMultipartFormDataToTelegram( + "sendPhoto", "photo", "img.jpg", contentType, chat_id, fileSize, + moreDataAvailableCallback, getNextByteCallback); - if (_debug) Serial.println(response); + if (_debug) + Serial.println(response); return response; } -String UniversalTelegramBot::sendPhoto(String chat_id, String photo, String caption, bool disable_notification, int reply_to_message_id, String keyboard) { +String UniversalTelegramBot::sendPhoto(String chat_id, String photo, + String caption, + bool disable_notification, + int reply_to_message_id, + String keyboard) { DynamicJsonBuffer jsonBuffer; - JsonObject& payload = jsonBuffer.createObject(); + JsonObject &payload = jsonBuffer.createObject(); payload["chat_id"] = chat_id; payload["photo"] = photo; @@ -647,7 +700,7 @@ String UniversalTelegramBot::sendPhoto(String chat_id, String photo, String capt } if (keyboard) { - JsonObject& replyMarkup = payload.createNestedObject("reply_markup"); + JsonObject &replyMarkup = payload.createNestedObject("reply_markup"); DynamicJsonBuffer keyboardBuffer; replyMarkup["keyboard"] = keyboardBuffer.parseArray(keyboard); @@ -659,8 +712,9 @@ String UniversalTelegramBot::sendPhoto(String chat_id, String photo, String capt bool UniversalTelegramBot::checkForOkResponse(String response) { int responseLength = response.length(); - for (int m=5; m < responseLength+1; m++) { - if (response.substring(m-10,m)=="{\"ok\":true") { //Chek if message has been properly sent + for (int m = 5; m < responseLength + 1; m++) { + if (response.substring(m - 10, m) == + "{\"ok\":true") { // Chek if message has been properly sent return true; } } @@ -668,18 +722,21 @@ bool UniversalTelegramBot::checkForOkResponse(String response) { return false; } -bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { +bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { bool sent = false; - if (_debug) Serial.println(F("SEND Chat Action Message")); + if (_debug) + Serial.println(F("SEND Chat Action Message")); long sttime = millis(); if (text != "") { - while (millis() < sttime+8000) { // loop for a while to send the message - String command="bot"+_token+"/sendChatAction?chat_id="+chat_id+"&action="+text; + while (millis() < sttime + 8000) { // loop for a while to send the message + String command = "bot" + _token + "/sendChatAction?chat_id=" + chat_id + + "&action=" + text; String response = sendGetToTelegram(command); - if (_debug) Serial.println(response); + if (_debug) + Serial.println(response); sent = checkForOkResponse(response); if (sent) { @@ -692,9 +749,11 @@ bool UniversalTelegramBot::sendChatAction(String chat_id, String text) { return sent; } -void UniversalTelegramBot::closeClient(){ - if(client->connected()){ - if(_debug){Serial.println(F("Closing client")); } +void UniversalTelegramBot::closeClient() { + if (client->connected()) { + if (_debug) { + Serial.println(F("Closing client")); + } client->stop(); } } diff --git a/src/UniversalTelegramBot.h b/src/UniversalTelegramBot.h index 5d1b0b8..5f7ace5 100644 --- a/src/UniversalTelegramBot.h +++ b/src/UniversalTelegramBot.h @@ -1,9 +1,8 @@ /* -Copyright (c) 2015 Giancarlo Bacchio. All right reserved. +Copyright (c) 2018 Brian Lough. All right reserved. -TelegramBot - Library to create your own Telegram Bot using +UniversalTelegramBot - Library to create your own Telegram Bot using ESP8266 or ESP32 on Arduino IDE. -Ref. Library at https:github/esp8266/Arduino This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -34,7 +33,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA typedef bool (*MoreDataAvailable)(); typedef byte (*GetNextByte)(); -struct telegramMessage{ +struct telegramMessage { String text; String chat_id; String chat_title; @@ -47,55 +46,57 @@ struct telegramMessage{ int update_id; }; -class UniversalTelegramBot -{ - public: - UniversalTelegramBot (String token, Client &client); - String sendGetToTelegram(String command); - String sendPostToTelegram(String command, JsonObject& payload); - String sendMultipartFormDataToTelegram(String command, String binaryProperyName, - String fileName, String contentType, - String chat_id, int fileSize, - MoreDataAvailable moreDataAvailableCallback, - GetNextByte getNextByteCallback); - - bool getMe(); - - bool sendSimpleMessage(String chat_id, String text, String parse_mode); - bool sendMessage(String chat_id, String text, String parse_mode = ""); - bool sendMessageWithReplyKeyboard(String chat_id, String text, - String parse_mode, String keyboard, bool resize = false, - bool oneTime = false, bool selective = false); - bool sendMessageWithInlineKeyboard(String chat_id, String text, - String parse_mode, String keyboard); - - bool sendChatAction(String chat_id, String text); - - bool sendPostMessage(JsonObject& payload); - String sendPostPhoto(JsonObject& payload); - String sendPhotoByBinary(String chat_id, String contentType, int fileSize, - MoreDataAvailable moreDataAvailableCallback, - GetNextByte getNextByteCallback); - String sendPhoto(String chat_id, String photo, String caption = "", - bool disable_notification = false, int reply_to_message_id = 0, String keyboard = ""); - - int getUpdates(long offset); - bool checkForOkResponse(String response); - telegramMessage messages[HANDLE_MESSAGES]; - long last_message_received; - String name; - String userName; - int longPoll = 0; - bool _debug = false; - int waitForResponse = 1500; - - private: - //JsonObject * parseUpdates(String response); - String _token; - Client *client; - bool processResult(JsonObject& result, int messageIndex); - void closeClient(); - const int maxMessageLength = 1300; +class UniversalTelegramBot { +public: + UniversalTelegramBot(String token, Client &client); + String sendGetToTelegram(String command); + String sendPostToTelegram(String command, JsonObject &payload); + String + sendMultipartFormDataToTelegram(String command, String binaryProperyName, + String fileName, String contentType, + String chat_id, int fileSize, + MoreDataAvailable moreDataAvailableCallback, + GetNextByte getNextByteCallback); + + bool getMe(); + + bool sendSimpleMessage(String chat_id, String text, String parse_mode); + bool sendMessage(String chat_id, String text, String parse_mode = ""); + bool sendMessageWithReplyKeyboard(String chat_id, String text, + String parse_mode, String keyboard, + bool resize = false, bool oneTime = false, + bool selective = false); + bool sendMessageWithInlineKeyboard(String chat_id, String text, + String parse_mode, String keyboard); + + bool sendChatAction(String chat_id, String text); + + bool sendPostMessage(JsonObject &payload); + String sendPostPhoto(JsonObject &payload); + String sendPhotoByBinary(String chat_id, String contentType, int fileSize, + MoreDataAvailable moreDataAvailableCallback, + GetNextByte getNextByteCallback); + String sendPhoto(String chat_id, String photo, String caption = "", + bool disable_notification = false, + int reply_to_message_id = 0, String keyboard = ""); + + int getUpdates(long offset); + bool checkForOkResponse(String response); + telegramMessage messages[HANDLE_MESSAGES]; + long last_message_received; + String name; + String userName; + int longPoll = 0; + bool _debug = false; + int waitForResponse = 1500; + +private: + // JsonObject * parseUpdates(String response); + String _token; + Client *client; + bool processResult(JsonObject &result, int messageIndex); + void closeClient(); + const int maxMessageLength = 1300; }; #endif From 70a393e0bd76528d0d33c164478d52fabe4d0770 Mon Sep 17 00:00:00 2001 From: Brian Lough Date: Wed, 21 Mar 2018 15:38:58 +0000 Subject: [PATCH 22/22] Fixing stray character as pointed out in PR #70 --- examples/101/FlashledBot/FlashledBot.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/101/FlashledBot/FlashledBot.ino b/examples/101/FlashledBot/FlashledBot.ino index 29dad39..b5aa01f 100644 --- a/examples/101/FlashledBot/FlashledBot.ino +++ b/examples/101/FlashledBot/FlashledBot.ino @@ -23,7 +23,7 @@ const int ledPin = 13; #define BOTtoken "XXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // your Bot Token (Get from Botfather) WiFiSSLClient client; -UniversalTelegramBot bot(BOTtoken, client);s +UniversalTelegramBot bot(BOTtoken, client); int Bot_mtbs = 1000; //mean time between scan messages long Bot_lasttime; //last time messages' scan has been done