Open ceewanna opened 6 months ago
I guess it's a bug, not sure which one it should be to be honest! probably long?
changed in #330 actually
Thanks.
By the way I am exploring ways to get multiple devices taking commands from one chat bot. Every device has its own id number and the command is attached with the id. Every device reading from the chat bot and only act on the command having id matched.
I am not so sure if by calling getUpdates the last_message_received will be moving on and some of the devices will miss its command. So I have each device maintaining its own tracking of last_message_received (through update_id). At the start each device will call getUpdates(bot.last_message_received+1) to get the proper bot.last_message_received value and make use of its as a starting tracking of message. Every bot.messages[i] each device processes it will update the tracking from update_id. Subsequently the getUpdaes will be callled based on each tracking+1.
Please correct me if I am wrong about the use of last_message_received. Do you have any guidance on how to handle the multiple devices in my case?
This is a path filled with pitfalls :) technically possible, but messy. If one of your devices go down and their is a message waiting for it, the messages will stop coming.
I would use it as a last resort. Multiple bots in a group might be a better option for example.
I think from reading your post that your idea of how the messageId thing works is wrong,
Say your last actually messaged ID was 100
When you send a getUpdates(100+1)
from any device, Telegram will delete any message it finds with a lower ID than 101 from its server as it considers them handled.
That means no device will see a message with a lower ID than 101 from this point on, even if they send getUpdates(80)
, it will not return any message with a lower ID than 101
How to implement: So in your scenario, you will have a few different boards, lets say they are labeled A, B and C
You send a message intended for C, so maybe your include the label in the message "/on C" or something.
you would need to extract the label and check them against your board.
Psuedo code:
Make messageIdToSend a global variable, you can default it to 0
long messageIdToSend = 0; //or int if it should be int
in your method for processing the message
String label = extractLabelFromMessage(message.text);
if(label == this_device_label){
//Act on message (turn on your light or whatever)
messageIdToSend = message.id +1
} else {
//Don't do anything, messageIdToSend doesn't need to be updated, the device the message it is for should delete it on Telegrams server when it gets it
//Maybe you could keep a counter here that if your receive the same message.id several times in a row it means the board the message is for is probably not working, and you could unblock the queue
}
and then send messageIdToSend in your loop when calling getUpdates
getUpdates(messageIdToSend )
I am attaching my code below.
if (cmd == "/resetall") {
bot_broadcast(me.name(true) + " RESET ALL ");
ESP.restart();
continue;
}
void bot_updates() {
static bool firstloop = true;
int numNewMessages;
/*
firstloop relies on bot.last_message_received
latter loops rely on msg_track
*/
if (firstloop) {
// initialize last_message_received and msg_track
// last_message_received won't have value unless getUpdates is called.
numNewMessages = bot.getUpdates(bot.last_message_received + 1);
msg_track = new Tracking_Var<long>(bot.last_message_received);
} else {
numNewMessages = bot.getUpdates(msg_track->current_value()+1);
}
while (numNewMessages > 0 || msg_track->current_value()<bot.last_message_received) {
if (firstloop) {
for (int i=0; i<numNewMessages; i++) {
msg_track->update(bot.messages[i].update_id);
if (bot.messages[i].text == "/resetall") {
// purge past resetall in messages
bot_broadcast(me.idname() + " restarted from resetall ");
} else {
bot_broadcast(me.idname() + " purging others commands " + bot.messages[i].text);
}
}
} else {
bot_messages_handler(numNewMessages);
}
numNewMessages = bot.getUpdates(msg_track->current_value() + 1);
if (numNewMessages==0 && msg_track->current_value() < bot.last_message_received) {
msg_track->jog(bot.last_message_received);
numNewMessages = bot.getUpdates(msg_track->current_value() + 1);
}
}
if (firstloop) {
bot_broadcast(me.idname() + " ready");
firstloop = false;
}
}
void bot_messages_handler(int numNewMessages) {
Serial.println("Handle New Messages");
Serial.println(String(numNewMessages));
for (int i=0; i<numNewMessages; i++) {
msg_track->update(bot.messages[i].update_id);
... the rest are for processing the text
String sub = get_substring(cmd, ' ', 0);
// this is where id is identified. Example : /sID on
if (sub == "/s" + me.idname()) {
String attr;
attr = get_substring(cmd, ' ', 1);
if (attr == "on") {
relay_sw.write(ON);
display_state(chat_id, true);
continue;
}
if (attr == "off") {
relay_sw.write(OFF);
display_state(chat_id, true);
continue;
}
if (attr == "state") {
display_state(chat_id);
display_tonoff(chat_id);
continue;
}
if (attr == "reset") {
bot_broadcast(me.name(true) + " RESET ");
ESP.restart();
continue;
}
}
}
Under "processResult" last_message_received takes value from update_id.
Is there any rationale behind having different datatype for these 2 variables?