1
votes

I have created a Telegram bot that features an inline keyboard whereby a user can enter a code. See GIF 1 below. The message text is updated as you tap the keyboard buttons so that you can see all the digits you have entered. The web app behind this is a Google Apps Script project. I'm enclosing my code below.

Everything works pretty well as long as you go slow, waiting for the text to update before you tap the next button. But as you speed up a bit, there are multiple instances of the web app running concurrently, trying to update the same message text which results in havoc. See GIF 2 below.

The desired behavior I'm aiming for is for the message text to update correctly no matter how fast I go at tapping the buttons. I do need each doPost instance to complete before the next one runs. Or, that's what I think the good plan is.

Please, help me figure this out.

function doPost(e) {
  
  var contents = JSON.parse(e.postData.contents);
  
  var mes_id = contents.callback_query.message.message_id;
    
  var user_input = contents.callback_query.data;
    
  var text_field = contents.callback_query.message.text;
    
  var inline_keyboard = contents.callback_query.message.reply_markup;   
    
  UrlFetchApp.fetch(url + "/answerCallbackQuery?callback_query_id=" + String(contents.callback_query.id)); 
    
  text_field = text_field + ' ' + user_input;
 
  var keydata = {
        method: "post",
        payload: {
          method: "editMessageText",
          chat_id: String(mychat_id),
          message_id: mes_id,
          text: text_field,
          parse_mode: "HTML",
          reply_markup: JSON.stringify(inline_keyboard)
        }
      }
        
UrlFetchApp.fetch('https://api.telegram.org/bot' + token + '/', keydata); 
        
} 

tapping slowly

tapping faster

1
Do you have access to something like RxJS in your project? This would simplify asynchronous operations like this - BobbyTables
@BobbyTables, I don't think so. This is a Google Apps Script project. - hey

1 Answers

0
votes

From your comment i gather that there is no asynchronicity (no async/await nor promises) in Google Apps Script.

This pseudocode might work, it puts new requests on a queue if theres a current one running - and then process them when the previous is done (it hurts my brain to not having async operations)

let processing = false;
let queue = [];

doPost() {
   if (!processing) {
     // Mark that were running a request (and dont run more at the same time)
     processing = true;

    [ HERE GOES YOUR CURRENT CODE ]

     // Now the request is done, lets see if theres more in the queue
     processing = false;
     if (queue.lenght > 0) {
       doPost(queue.pop()); // Lets process the next request
     }
   } else {
     // Another request is processing, so put this on the queue
     queue.push(e);
   }
}