Clear "pending_update_count" in Telegram Bot - webhooks

I want to clear all pending_update_count in my bot!
The output of below command :
https://api.telegram.org/botxxxxxxxxxxxxxxxx/getWebhookInfo
Obviously I replaced the real API token with xxx
is this :
{
"ok":true,"result":
{
"url":"",
"has_custom_certificate":false,
"pending_update_count":5154
}
}
As you can see, I have 5154 unread updates til now!! ( I'm pretty sure this pending updates are errors! Because no one uses this Bot! It's just a test Bot)
By the way, this pending_update_count number are increasing so fast!
Now that I'm writing this post the number increased 51 and reached to 5205 !
I just want to clear this pending updates.
I'm pretty sure this Bot have been stuck in an infinite loop!
Is there any way to get rid of it?
P.S:
I also cleared the webhook url. But nothing changed!
UPDATE:
The output of getWebhookInfo is this :
{
"ok":true,
"result":{
"url":"https://somewhere.com/telegram/webhook",
"has_custom_certificate":false,
"pending_update_count":23,
"last_error_date":1482910173,
"last_error_message":"Wrong response from the webhook: 500 Internal Server Error",
"max_connections":40
}
}
Why I get Wrong response from the webhook: 500 Internal Server Error ?

I think you have two options:
set webhook that do nothing, just say 200 OK to telegram's servers. Telegram wiil send all updates to this url and the queque will be cleared.
disable webhook and after it get updates by using getUpdates method, after it, turn on webhook again
Update:
Problem with webhook on your side. You can try to emulate telegram's POST query on your URL.
It can be something like this:
{"message_id":1,"from":{"id":1,"first_name":"FirstName","last_name":"LastName","username":"username"},"chat":{"id":1,"first_name":"FirstName","last_name":"LastName","username":"username","type":"private"},"date":1460957457,"text":"test message"}
You can send this text as a POST query body with PostMan for example, and after it try to debug your backend.

For anyone looking at this in 2020 and beyond, the Telegram API now supports clearing the pending messages via a drop_pending_updates parameter in both setWebhook and deleteWebhook, as per the API documentation.

Just add return 1; at the end of your hook method.
Update:
Commonly this happens because of queries delay with the database.

I solved is like this
POST tg.api/bottoken/setWebhook to emtpy "url"
POST tg.api/bottoken/getUpdates
POST tg.api/bottoken/getUpdates with "offset" last update_id appeared before
doing this serveral times
POST tg.api/bottoken/getWebhookInfo
had a look if all away.
POST tg.api/bottoken/setWebhook with filled "url"

If you are using webhook, you can follow these steps
On your web browser, enter the following url with your right value of bot
https://api.telegram.org/bot/getWebhookInf
You will get a result like this on your screen
{"ok":true,"result":{"url":"url_value",...}}
On the displayed result, copy the entire url_value without quotes and replace it on this second url
https://api.telegram.org/bot/setWebhook?url=url_value&drop_pending_updates=True
Enter the second url with right bot and url_value in your web browser then press ENTER
Done!

i solve it by Change file access permissions file - set permissions file to 755
and second increase memory limit in php.ini file

A quick&dirty way is to get a temporary webhook here: https://webhook.site/ and
set your webhook to that (it will answer with a HTTP/200 code everytime, reseting your pending messages to zero)

I faced the same issue for my tele bot after user edited existing message. My bot receives update with editedMessage continuously, but update.hasMessage() was empty. As a result number of updates rocketly increased and my bot stack.
I solved this issue by adding handling for use case when message is missing - send 200 code:
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
update = MAPPER.readValue(event.getBody(), Update.class);
if (!update.hasMessage()) {
return new APIGatewayProxyResponseEvent()
.withStatusCode(200) // -> !!!!!! return code 200
.withBody("message is missing")
.withIsBase64Encoded(false);
}
... ... ...

Related

pyTelegramBotAPI inline google search engine

#bot.inline_handler(func=lambda query: len(query.query) > 0)
def query_text(query):
sleep(6)
text=query.query
html=requests.get(f'https://google.com/search?q={text}')
# print(html.status_code)
open('index.html','w', encoding='utf-8').write(html.text)
soup=BeautifulSoup(html.text, 'html.parser').find_all('div',{"class":"***********"})
for i in soup:
fk.append(types.InlineQueryResultArticle(id=str(len(fk)), title=f"{i.find('h3').get_text()}",description=f"{i.find('div',{'class':'**********'}).get_text()}",input_message_content=types.InputTextMessageContent(message_text=i.find('a').get('href').replace('/url?q=','https://google.com/url?q=')),hide_url=True,url=i.find('a').get('href').replace('/url?q=','https://google.com/url?q='),thumb_url='https://w7.pngwing.com/pngs/338/520/png-transparent-g-suite-google-play-google-logo-google-text-logo-cloud-computing.png', thumb_width=30, thumb_height=30))
print(i.find('a').get('href').replace('/url?q=','')+'\n')
sleep(2)
bot.answer_inline_query(query.id, fk)
When I write #bot google request
Bot takes it as g go goo google
What is causing the error
"A request to the Telegram API was unsuccessful. Error code: 400. Description: Bad Request: query is too old and response timeout expired or query ID is invalid"
How to make text input timeout so that it doesn't respond to every letter?
I think, the error resides in your way of parsing data. It takes at least 8 seconds (based on sleeps) just to get to the answer method. Telegram inline queries have very few seconds until they are considered old, so, it is better to process data after you call bot.answer_inline_query() and then send it to user using bot.send_message()
I am not certain how it works with async code though.
If you find another solution, please let me know :)

How to add reaction to a specific message using the ID? (discord.py)

I've been trying for hours a command that react to a message using the ID.
If someone writes !react (the message ID) the bot reacts to the message.
Can someone help me? I have no clue how to do this.
Use a converter to get the discord.Message instance of the message:
#client.command()
async def react(ctx, message: discord.Message):
...
Then use Message.add_reaction to add a reaction to it, which I'm sure you can figure out by yourself.
Keep in mind that in case the message ID is invalid, can't be found, or is not in the same channel as where the command gets called, the converter will fail & throw you an exception. If you pass in the message's URL instead of the ID, Discord will be able to figure out what channel the message was sent in so you can call the command from wherever you want.
You can get a message's URL by selecting Copy Message Link, which might be better for your users as getting the id requires Developer Mode to be on, which most people don't have enabled. The MessageConverter mentioned in the beginning can parse both id's and URL's so you don't have to worry about that part.

Cancelled account linking leads to endless loop of same response

If a user invokes my action, she is asked by google whether her account should be linked or not (something like: "If you want to use xxx, I got to link your account at xxx with google. Is this okay?"). Now, if she chooses "no", and my action returns an answer with expectUserResponse set to false, google assistant seems to jump into a very awkward endless loop of my returned response, even emitting the assistant's "conversation finished" sound after each response:
("In order to use xxx, I got to link your account at xxx with google. Is this okay?" - "No" - "Okay, this means you are not able to use your account at xxx. Get back to us if you change your mind.")
"Schönen Tag" (in the second speech bubble) is the response I am sending from my fulfillment.
So what we are getting here is an endless "Schönen Tag" - GoogleSound - "Schönen Tag" - GoogleSound - "Schönen Tag" - GoogleSound - Schönen Tag"- GoogleSound and so on. With no additional user input between each message. Imho, this definitely shouldn't happen, no matter if I configured sth wrongly or not.
I don't even need my fulfillment server to reproduce this. If I create a dialogflow intent, attach the actions_intent_SIGN_IN event to it and let this intent return a static response with "set this intent as end of conversation" set to true, I am able to fully reproduce this strange behaviour:
(this actually was the setup for all screenshots above)
If I recreate this intent, but change the setting to not end the conversation after sending the response, I do not get an endless loop anymore. But this isn't what I intended to do.
It also doesn't seem to matter if I require the sign in for explicit invocations or not (in the integrations-tab).
It looks like this was a bug, with a fix released this morning.
Are you still running into this issue?

Kamailio 4.3.1 Register/200 OK asycnhornous

I am new to Kamailio 4.3.1 and I am trying to use it as described on this http://kb.asipto.com/kamailio:k43-async-sip-routing-nodejs page. Apparently it is a new approach to make asynchronous routing using NodeJS.
I've modified a little bit the example and adapted it with a REGISTER sip and it works quite good. But now I am looking for a way to make the things a little bit more complex.
In the example the NodeJS routine is called only when the REGISTER method has been received. I am trying to make a similar asynchronous call to NodeJS when the '200 OK' comes back from the REGISTERS's destination.
If we have:
Alice---REGISTER(Alice)---> Kamailio (async call to NodeJs)---REGISTER(Alice)-->Asterisk
Later when Asterisk accepts the REGISTER the I want to have this:
Alice<---200 OK---Kamailio(async call to NodeJS)<---200 OK---Asterisk
To catch the 200 OK, I configured Kamailio to execute an async call using EVAPI, like this:
request_route
{
....
route(REGISTRAR);
....
exit;
}
route[REGISTRAR]
{
...
t_on_reply("2OO_OK_RSP"); # Here I tell that I want to catch the "200 OK"
...
exit;
}
# When the 200 OK arrives, this code is called
onreply_route[2OO_OK_RSP]
{
# Here is my async call to NodeJS
evapi_async_relay("send message to NodeJS about 200 OK");
}
#When NodeJS returns
event_route[evapi:message-received]
{
if(200 OK)
{
t_countinue("..", "...", RSP_200OK)
}
}
route[RSP_200OK]
{
t_on_branch("MANAGE_BRANCH");
t_on_failure("MANAGE_FAILURE");
route(RELAY); # I am trying here to relay the 200 OK, which finishes by calling t_relay();
exit;
}
So this is my configuration which is treating the 200 OK. I would like to say that it works (because at the end the 200 Ok is relayed to Alice) BUT Kamailio logs this message:
tm [tm.c:1479]: _w_t_relay_to(): ERROR: w_t_relay_to: unsupported route type: 4
and I don't like this. I know that there is something wrong and when I am looking at the source code of Kamailio it is clear that this is not the right place to treat messages like "200 OK".
My question is, is there any other way (a good way) to relay/route the 200 OK, once the NodeJS has replied? I tried also with
t_reply("200","OK"); instead of t_relay();
But this generates a SIP message "200 OK" which does not contain everything that the messages received by Asterisk. Probably I can tell Kamailio to reply by exactly the same 200 OK, that it has just received?
Thank you in advance!
Best regards,
Anton
So finally I could find how to resolve partially my problem.
I discovered that the module EVAPI proposes a method called evapi_relay() which does not suspend the current transaction but sends a messages to the NodeJS application and relays the SIP messages immediately.
I says that this resolves my problem partially because however I am still not able to make the whole procedure with suspending the transaction (without the Kamailio error).
In my case, it is not so important, but I imagine that in some cases the problem will persist.
Anton
From EVAPI module documentation: After evapi_async_relay() returns true, no relaying should happen in request_route(), it should be followed by exit.
Relay the event data given as parameter to connected applications. Before evaluating the parameter, the request processing is suspended using tm module (using the t_suspend()/t_continue() framework). The routing of the SIP request can be continued once event_route[evapi:message-received] is triggered. After evapi_async_relay() returns true, no relaying should happen in request_route(), it should be followed by exit;.

Gmail History list is not giving complete data

I am trying to get history from historyId which gmail api watch() gives
https://developers.google.com/gmail/api/v1/reference/users/history/list
I am getting historyId in the response like below
{
historyId: 12345
}
I tried adding fields argument with no luck.
request to https://www.googleapis.com/gmail/v1/users/me/history?startHistoryId=12345&fields=historyId,history(id%2Cmessages) is also failing
Am I doing anything wrong?
The response tells you that nothing has happened since the time your startHistoryId represents. If you send yourself a mail and try again with the same startHistoryId, you will get a new message as result.
If you are getting the historyId from watch(), it is another issue. The historyId you get in the push notification simply states the current historyId of the label you are watching. Think about it. How should Google know when you last synced? When you get a push notification, you need to use the historyId you stored since last time in your request.

Resources