cotestatnt / AsyncTelegram2

Powerful, flexible and secure Arduino Telegram BOT library. Hardware independent, it can be used with any MCU capable of handling an SSL connection.
MIT License
83 stars 25 forks source link

AsyncTelegram2 and other https reliant libraries #99

Closed pablopeu closed 1 year ago

pablopeu commented 1 year ago

Hi, I'm having a hard time trying to merge two projects into one, take for example the lightbot example in the library, and another example, in my case, the thingspeak IOT library (https://github.com/mathworks/thingspeak-arduino) This library allows making HTTP or HTTPS connections to update sensor values on the Thingspeak site.

Is it possible for AsyncTelegram2 to connect and update while in the same app updating the other library? Tried HTTP and HTTPS in the thingspeak library and either AT2 doesn't connect or TS fails at updating.

Thanks

cotestatnt commented 1 year ago

Hi @pablopeu I'm trying to work with mathworks ThingSpeak IOT library, but with ESP32 seems not working also the included example WriteSingleFieldSecure.ino as is (using HTTPS).

No problem with HTTP connection indeed, even togheter with AsyncTelegram2, but using two distinct client (WiFiClientSecure for AsyncTelegram2 and WiFiClient for ThingSpeak).

pablopeu commented 1 year ago

Hi @cotestatnt thanks for the reply.

Based on your suggestion to use nonsecure thingspeak as this example works, here is the code I made merging you echobot code (sans the your public channel update and LED) with the thingspeak example. Both of these run alone work as expected, but when merged only thingspeak. The telegram bot is not updated but is properly detected. Not even the welcome message is sent.

Testing on esp32

I'm sure botching something LOL but can't see it.

`/* WriteMultipleFields Library Example

Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds over secured HTTPS connection.

Hardware: ESP32 based boards

!!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!!

Note:

/ Name: echoBot.ino Created: 26/03/2021 Author: Tolentino Cotesta cotestatnt@yahoo.com Description: a simple example that check for incoming messages and reply the sender with the received message. The message will be forwarded also in a public channel anad to a specific userid. /

/ Set true if you want use external library for SSL connection instead ESP32@WiFiClientSecure For example https://github.com/OPEnSLab-OSU/SSLClient/ is very efficient BearSSL library. You can use AsyncTelegram2 even with other MCUs or transport layer (ex. Ethernet) With SSLClient, be sure "certificates.h" file is present in sketch folder /

define USE_CLIENTSSL true

include

// Timezone definition

include

define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"

ifdef ESP8266

include

BearSSL::WiFiClientSecure client; BearSSL::Session session; BearSSL::X509List certificate(telegram_cert);

elif defined(ESP32)

include

include

if USE_CLIENTSSL

#include <SSLClient.h>  
#include "tg_certificate.h"
WiFiClient base_client;
SSLClient client(base_client, TAs, (size_t)TAs_NUM, A0, 1, SSLClient::SSL_ERROR);

else

#include <WiFiClientSecure.h>
WiFiClientSecure client;  

endif

endif

// #include

include "secrets.h"

include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros

// used secrets.h from the thingspeak WriteMultipleFields example to put all secret values there char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password int keyIndex = 0; // your network key Index number (needed only for WEP) WiFiClient cliente;

unsigned long myChannelNumber = SECRET_CH_ID; const char * myWriteAPIKey = SECRET_WRITE_APIKEY;

// Initialize our values int number1 = 0; int number2 = random(0,100); int number3 = random(0,100); int number4 = random(0,100); String myStatus = "";

AsyncTelegram2 myBot(client); // bot definitions const char* token and int64_t userid = moved to secrets.h for sharing code purposes

void setup() { Serial.begin(115200); //Initialize serial

WiFi.mode(WIFI_STA); WiFi.begin(ssid, pass); delay(500); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(500); }

ThingSpeak.begin(cliente); // Initialize ThingSpeak

ifdef ESP8266

// Sync time with NTP, to check properly Telegram certificate configTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org"); //Set certficate, session and some other base client properies client.setSession(&session); client.setTrustAnchors(&certificate); client.setBufferSizes(1024, 1024);

elif defined(ESP32)

// Sync time with NTP configTzTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");

if USE_CLIENTSSL == false

client.setCACert(telegram_cert);

endif

endif

// Set the Telegram bot properies myBot.setUpdateTime(2000); myBot.setTelegramToken(token);

// Check if all things are ok Serial.print("\nTest Telegram connection... "); myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

Serial.print("Bot name: @"); Serial.println(myBot.getBotName());

char welcome_msg[128]; snprintf(welcome_msg, 128, "BOT @%s online\n/help all commands avalaible.", myBot.getBotName());

// Send a message to specific user who has started your bot myBot.sendTo(userid, welcome_msg); }

void loop() {

TBMessage msg;

// if there is an incoming message... if (myBot.getNewMessage(msg)) {
// Send a message to your public channel String message ; message += "Message from @"; message += myBot.getBotName(); message += ":\n"; message += msg.text; Serial.println(message);

// myBot.sendToChannel(channel, message, true);

// echo the received message
myBot.sendMessage(msg, msg.text);

}

// set the fields with the values ThingSpeak.setField(1, number1); ThingSpeak.setField(2, number2); ThingSpeak.setField(3, number3); ThingSpeak.setField(4, number4);

// figure out the status message if(number1 > number2){ myStatus = String("field1 is greater than field2"); } else if(number1 < number2){ myStatus = String("field1 is less than field2"); } else{ myStatus = String("field1 equals field2"); }

// set the status ThingSpeak.setStatus(myStatus);

// write to the ThingSpeak channel int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); if(x == 200){ Serial.println("Channel update successful."); } else{ Serial.println("Problem updating channel. HTTP error code " + String(x)); }

// change the values number1++; if(number1 > 99){ number1 = 0; } number2 = random(0,100); number3 = random(0,100); number4 = random(0,100);

delay(20000); // Wait 20 seconds to update the channel again } `

pablopeu commented 1 year ago

small update, if I change #define USE_CLIENTSSL true to false I get the welcome message, but not the echo replacing myBot.sendMessage(msg, msg.text); by: myBot.sendTo(userid, msg.text); this also doesnt work:

but sending a message outside if (myBot.getNewMessage(msg)) { like: myBot.sendTo(userid, "test"); works as expected

pablopeu commented 1 year ago

it was the delay(20000)... replaced it with a timer and received all the replies at once LOL

here is the code, I'm sure will help someone else:

`/* WriteMultipleFields Library Example

Description: Writes values to fields 1,2,3,4 and status in a single ThingSpeak update every 20 seconds over secured HTTPS connection.

Hardware: ESP32 based boards

!!! IMPORTANT - Modify the secrets.h file for this project with your network connection and ThingSpeak channel details. !!!

Note:

/ Name: echoBot.ino Created: 26/03/2021 Author: Tolentino Cotesta cotestatnt@yahoo.com Description: a simple example that check for incoming messages and reply the sender with the received message. The message will be forwarded also in a public channel anad to a specific userid. /

/ Set true if you want use external library for SSL connection instead ESP32@WiFiClientSecure For example https://github.com/OPEnSLab-OSU/SSLClient/ is very efficient BearSSL library. You can use AsyncTelegram2 even with other MCUs or transport layer (ex. Ethernet) With SSLClient, be sure "certificates.h" file is present in sketch folder /

define USE_CLIENTSSL false

include

// Timezone definition

include

define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"

ifdef ESP8266

include

BearSSL::WiFiClientSecure client; BearSSL::Session session; BearSSL::X509List certificate(telegram_cert);

elif defined(ESP32)

include

include

if USE_CLIENTSSL

#include <SSLClient.h>  
#include "tg_certificate.h"
WiFiClient base_client;
SSLClient client(base_client, TAs, (size_t)TAs_NUM, A0, 1, SSLClient::SSL_ERROR);

else

#include <WiFiClientSecure.h>
WiFiClientSecure client;  

endif

endif

// #include

include "secrets.h"

include "ThingSpeak.h" // always include thingspeak header file after other header files and custom macros

char ssid[] = SECRET_SSID; // your network SSID (name) char pass[] = SECRET_PASS; // your network password int keyIndex = 0; // your network key Index number (needed only for WEP) WiFiClient cliente;

unsigned long myChannelNumber = SECRET_CH_ID; const char * myWriteAPIKey = SECRET_WRITE_APIKEY;

unsigned long thingtimer=millis()+20000;

// Initialize our values int number1 = 0; int number2 = random(0,100); int number3 = random(0,100); int number4 = random(0,100); String myStatus = "";

AsyncTelegram2 myBot(client); // bot definitions const char* token and int64_t userid = moved to secrets.h for sharing code purposes

void setup() { Serial.begin(115200); //Initialize serial

WiFi.mode(WIFI_STA); WiFi.begin(ssid, pass); delay(500); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(500); }

ThingSpeak.begin(cliente); // Initialize ThingSpeak

ifdef ESP8266

// Sync time with NTP, to check properly Telegram certificate configTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org"); //Set certficate, session and some other base client properies client.setSession(&session); client.setTrustAnchors(&certificate); client.setBufferSizes(1024, 1024);

elif defined(ESP32)

// Sync time with NTP configTzTime(MYTZ, "time.google.com", "time.windows.com", "pool.ntp.org");

if USE_CLIENTSSL == false

client.setCACert(telegram_cert);

endif

endif

// Set the Telegram bot properies myBot.setUpdateTime(2000); myBot.setTelegramToken(token);

// Check if all things are ok Serial.print("\nTest Telegram connection... "); myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

Serial.print("Bot name: @"); Serial.println(myBot.getBotName());

char welcome_msg[128]; snprintf(welcome_msg, 128, "BOT @%s online\n/help all commands avalaible.", myBot.getBotName());

// Send a message to specific user who has started your bot myBot.sendTo(userid, welcome_msg); }

void loop() {

TBMessage msg;

// if there is an incoming message... if (myBot.getNewMessage(msg)) {
// Send a message to your public channel String message ; message += "Message from @"; message += myBot.getBotName(); message += ":\n"; message += msg.text; Serial.println(message);

// myBot.sendToChannel(channel, message, true);

// echo the received message
// myBot.sendMessage(msg, msg.text); //no anda
myBot.sendTo(userid, msg.text); 

}

// myBot.sendTo(userid, "Mande fruta al 2020");

if (millis() > thingtimer) thingspeak();

}

void thingspeak(){

thingtimer=millis()+20000;

// set the fields with the values ThingSpeak.setField(1, number1); ThingSpeak.setField(2, number2); ThingSpeak.setField(3, number3); ThingSpeak.setField(4, number4);

// figure out the status message if(number1 > number2){ myStatus = String("field1 is greater than field2"); } else if(number1 < number2){ myStatus = String("field1 is less than field2"); } else{ myStatus = String("field1 equals field2"); }

// set the status ThingSpeak.setStatus(myStatus);

// write to the ThingSpeak channel int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); if(x == 200){ Serial.println("Channel update successful."); } else{ Serial.println("Problem updating channel. HTTP error code " + String(x)); }

// change the values number1++; if(number1 > 99){ number1 = 0; } number2 = random(0,100); number3 = random(0,100); number4 = random(0,100); } `