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

Light bot for specific user id #42

Closed muk3shb closed 2 years ago

muk3shb commented 2 years ago

Hi, if you look at the examples, in the setup you find this:

int64_t user id = 123456789;
myBot.sendTo (userid, welcome_msg);

this means that only the telegam user with id = 123456789 will be able to receive replies from your bot. Similarly, you can do the same by telling your bot to receive and process responses only from one or more selected telegram ID.

Hello

Thankyou So much!! I found that code on the example and with little changes, it is working!! i have not changed anything just very minute changes. There are no errors but the message is continuously generating. Here is the code..

// i am reverifying the chatid by using simple operator and it is working!! but the bot is continuosly generating the message. the code that i have mentioned will work fine

#define USE_CLIENTSSL false  

#include <AsyncTelegram2.h>
// Timezone definition
#include <time.h>
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"

#ifdef ESP8266
  #include <ESP8266WiFi.h>
  BearSSL::WiFiClientSecure client;
  BearSSL::Session   session;
  BearSSL::X509List  certificate(telegram_cert);

#elif defined(ESP32)
  #include <WiFi.h>
  #include <WiFiClient.h>
  #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

AsyncTelegram2 myBot(client);
const char* ssid  =  "xxxxxxxx";     // SSID WiFi network
const char* pass  =  "xxxxxxxxxx";     // Password  WiFi network
const char* token =  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";  // Telegram token

const int LED = 5;

void setup() {
  // initialize the Serial
  Serial.begin(115200);
  Serial.println("\nStarting TelegramBot...");

  // set the pin connected to the LED to act as output pin
  pinMode(LED, OUTPUT);
  digitalWrite(LED, LOW); // turn off the led (inverted logic!)

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

#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(1000);
  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());
  int64_t chat_id = 1234567890; // You can discover your own chat id, with "Json Dump Bot"
  myBot.sendTo(chat_id, welcome_msg);

}

void loop() {
  // local variable to store telegram message data
  TBMessage msg;
  // if there is an incoming message...
  if( myBot.getNewMessage(msg)); {
    String msgText = msg.text;

    if (msgText.equals("/light_on")) {                 // if the received message is "LIGHT ON"...
      digitalWrite(LED, HIGH);                          // turn on the LED (inverted logic!)
      myBot.sendMessage(msg, "Light is now ON");       // notify the sender
    }
    else if (msgText.equals("/light_off")) {           // if the received message is "LIGHT OFF"...
      digitalWrite(LED, LOW);                          // turn off the led (inverted logic!)
      myBot.sendMessage(msg, "Light is now OFF");       // notify the sender
    }
    else {                                              // otherwise...
      // generate the message for the sender
      String reply;
      reply = "Welcome " ;
      reply += msg.sender.username;
      reply += ".\nTry /light_on or /light_off ";
      myBot.sendMessage(msg, reply);                    // and send it
    }
  }

}

Originally posted by @muk3shb in https://github.com/cotestatnt/AsyncTelegram2/issues/41#issuecomment-1018844366

cotestatnt commented 2 years ago

Hi @muk3shb, I've just uploaded a new release 2.0.8 with this bug fixed. Now the bot will reply always in the chat where message was sent, whether it comes from a user or a group.

You need to take care with command ( words preceded by "/") coming from group, because Telegram in that case add automatically the id of group like this for example: /my_command@myGroupName

You need to handle this messages in a different way than the lightBot.ino example do. For example a quick mod would be using indexOf() instead equals() or storing the group name in a variable.

  if (msgText.indexOf("/light_on") > -1) {           // if the received message contains /light_on"...
    digitalWrite(LED, LOW);                          // turn on the LED 
    myBot.sendMessage(msg, "Light is now ON");       // notify the sender
  }
  else if (msgText.indexOf("/light_off") > -1) {      // if the received message contains "/light_off"...
    digitalWrite(LED, HIGH);                          // turn off the led 
    myBot.sendMessage(msg, "Light is now OFF");       // notify the sender
  }
muk3shb commented 2 years ago

Hi @muk3shb, I've just uploaded a new release 2.0.8 with this bug fixed. Now the bot will reply always in the chat where message was sent, whether it comes from a user or a group.

You need to take care with command ( words preceded by "/") coming from group, because Telegram in that case add automatically the id of group like this for example: _/my_command@myGroupName_

You need to handle this messages in a different way than the lightBot.ino example do. For example a quick mod would be using indexOf() instead equals() or storing the group name in a variable.

  if (msgText.indexOf("/light_on") > -1) {           // if the received message contains /light_on"...
    digitalWrite(LED, LOW);                          // turn on the LED 
    myBot.sendMessage(msg, "Light is now ON");       // notify the sender
  }
  else if (msgText.indexOf("/light_off") > -1) {      // if the received message contains "/light_off"...
    digitalWrite(LED, HIGH);                          // turn off the led 
    myBot.sendMessage(msg, "Light is now OFF");       // notify the sender
  }

Sir, I executed this, it is working fine. I have few questions to ask.. Here they are..

  1. How can we disregard other commands while allowing the bot to work with only one command ?

    for example - if /High is input than the output is high and i get the replied msg like "Something is high" However if i write anything other than "/High" than the BOT should not reply or accept other command.

My concern - If someone who knows the command other than the user then the BOT will work for the actual user and the user who knows the command.

  1. Can we store the userid in variable ?

The BOT works as universal so i think there's something which is fixed on the working side of the bot.

cotestatnt commented 2 years ago

When your bot receive a new message, inside the struct TBMessage msg there are all informations about the sender. You can check for a specific userid or even for a specific username. In addition you could ask user to confirm command with a password, check this example as a starting point: OTA_password.ino

if (myBot.getNewMessage(msg)) {
    Serial.print("\nMessage received from: ");
    Serial.print(msg.sender.id);
    Serial.print("@");
    Serial.println(msg.sender.username);
......
muk3shb commented 2 years ago

This is Compiling well and on the output side, Only Default case is being executed. How can i call for "insert pw" in message document case. or is there any other method ? i didnt understood the working Of Messagedocument case, i only half understood it, how to execute for calling for pw with text of some specific text ?

Here in the code I have just wrote tha passkey, pley don't confused i haven't assigned any passkey yet.



/Code_removed
cotestatnt commented 2 years ago

MessageDocument type is when you receive a binary file as attached document (as in case for a new firmware). If you are working only with text message, simply apply the same workflow with text received. If you set force_reply property, the user will be prompted to respond as reply to your specific message. In this way you can handle better the next reply wich will be of MessageReply type containing the password string

   ......
   MessageType msgType = msg.messageType;
   String msgText = msg.text;
   Serial.print("\nText message received: ");
   Serial.println(msgText);

   switch (msgType) {  
      // Normal text message
      case MessageText :
        if (msgText.indexOf("/askMePassword") > -1) {         
          msg.force_reply = true;
          myBot.sendMessage(msg, "Please insert password", "");
        }
        break;  

      // Reply to a message
      case MessageReply: 
        tgReply = msg.text;     
        // User has confirmed  with right password, replying to my message
        if ( msgText .equals("your password) ) {
          Serial.println("Password correct");
        }
        break;
   }
muk3shb commented 2 years ago

Thanks sir, i got the refrence and this is working fine. However, Since i have defined the lightbot outside switch structure, it is easily accessible. how i make the loop end by turning lightbot on and reverting back to first step or welcome msg step ? and how can i add /start to start the loop everytime ?. The Bot is working pretty well.. just this minor details will enhance it.

switch (msgType) {
// Normal text message case MessageText : if (msgText.indexOf("/Click_here") > -1) {
msg.force_reply = true; myBot.sendMessage(msg, "Please insert password", ""); } break;

  // Reply to a message
 // Reply to a message
  case MessageReply: 
    tgReply = msg.text;     
    // User has confirmed  with right password, replying to my message
    if ( msgText.equals("Badu") ) 
    {
      Serial.println("Password correct");
      String reply;
  reply = "Welcome " ;
  reply += msg.sender.username;
  reply += ".\nTry /light_on or /light_off ";
  myBot.sendMessage(msg, reply);          
    }
    break;
    }

if (msgText.indexOf("/light_on") > -1) { // if the received message contains /light_on"... digitalWrite(LED, HIGH); // turn on the LED myBot.sendMessage(msg, "Light is now ON"); // notify the sender } else if (msgText.indexOf("/light_off") > -1) { // if the received message contains "/light_off"... digitalWrite(LED, LOW); // turn off the led myBot.sendMessage(msg, "Light is now OFF"); // notify the sender }