Cancelled account linking leads to endless loop of same response - dialogflow-es

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?

Related

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.

DialogFlow follow up triggers empty response

I have a DialogFlow intent follow up that I'm having a hard time with. It's the only follow up to my main intent, and the issue I'm having is that when
the incidents.data array is empty it doesn't trigger the conv.ask statement in the else case and causes DialogFlow to throw an empty speech response error. The code looks something like this:
app.intent('metro_timetable - yes', async (conv: any) => {
const incidents = await serviceIncidents.getIncidents();
if (incidents.data.length > 0) {
conv.ask('I have incidents')
} else {
conv.ask(
`I wasn't able to understand your request, could you please say that again?`
);
}
});
incidents.data gets stored in the global scope, and is set deep within
the metro_timetable intent. It stores an incident for the follow up. Because all yes responses trigger the follow up I setup an else case so it catches it if someone says yes when metro_timetable doesn't understand their original request and asks them to repeat it. If incidents.data actually has information to share the dialog triggers correctly and I have incidents is correctly read to the user.
In DialogFlow it looks something like this. Where am I going wrong here?
Your description is a little convoluted how incidents.data actually gets set, but it sounds possible that instead of it being set to an empty array, it isn't set at all. In this case, I suspect that the following happened:
incidents.data would be undefined
Trying to evaluate incidents.data.length would cause an error
Since the program crashes, your webhook doesn't return a result. Since you probably didn't set a result in the UI for the intent, an empty result was returned.
You can probably solve this by doing a test such as (for example)
incidents && incidents.data && incidents.data.length > 0
Your other issue, however, seems to be that you have a Followup Intent set for a scenario where you don't actually want that as the followup. This is one of the reasons you probably shouldn't use Followup Intents but, instead, only set a context when you send a response where that context would make sense, and look for the "Yes" response in the context you define. Then, when metro_timetable doesn't understand the request, you don't set the context and you give an error.
To do this, you would remove the automatically generated metro_timetable-followup context from the two Intents. You'll create your own context, which I'll name timetable for purposes of this example.
In the fulfillment for the metro_timetable Intent, if you respond with something that needs confirmation (ie - when "yes" will be something the user says), you would set the timetable context with something like
conv.contexts.set('timetable',2);
conv.ask('Are you sure?');
You can then create an Intent that checks for timetable as the Incoming Context and has training phrases that are equivalent to "yes". In that Intent, you'd do what you need to and respond.

Clear "pending_update_count" in Telegram Bot

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);
}
... ... ...

"immediate_failed" - Could not automatially log in the user

I have a problem when I developed my website with Google+ sign-in:
I did step by step that the doc told me but I always failed at step4:
https://developers.google.com/+/web/signin/
the result was always ""immediate_failed" - Could not automatially log in the user", I just don't kown why, can anyone help me, thanks very much! :-(
Note that in the sample code you pointed to, the "immediate_failed" check is commented out. This is intentional, since the first time a user encounters the Sign-in button on the page, it will fail.
The reason it fails is that when the page first loads, before the user even presses the button, a request is sent to Google to determine if the user has already logged in (via Google or another site, for example). If they are - there is no need for them to log in again, so the button never needs to be shown. But if they have not been logged in already, you will get the "immediate_failed" response, and will need to either show (or not clear) the button.
tl;dr - Don't worry aout getting immediate_failed when the page first loads. This is normal.
As a workaround I use gapi.auth.authorize method in the gapi.auth.signIn callback. Here is my code:
gapi.auth.signIn({
'callback': gPlusLoginCallback
});
function gPlusLoginCallback(authResult) {
if (authResult['status']['signed_in']) {
doSmth(authRes['access_token']);
} else if (authResult['error'] == "immediate_failed") {
gapi.auth.authorize({
client_id: gplusClientId,
scope: 'https://www.googleapis.com/auth/plus.login email',
immediate: true
}, function (authRes) {
if (authRes['status']['signed_in']) {
doSmth(authRes['access_token']);
}
});
}
}
function doSmth(accessToken){
//Do smth
}
Change this setting "immediate: true", to be false " immediate: false".
But if you like to make more complex implementation look at the first sample here https://developers.google.com/api-client-library/javascript/start/start-js. You have to calls to Google's "gapi.auth.authorize({...", the first one with "immediate: true", and the second one with "immediate: false".
The question is old but I faced this issue recently.
In my case, it was because I specified the URI parameter prompt to none. I guess Google doesn't like that if the user has never been logged to your platform before.
Whenever I changed that to consent or totally removed it, it worked great.
In my case, the error was because of explicitly specifying the authorization parameter prompt to 'none',similar to a previous answer.
It worked for me by specifying prompt=None or as per the official docs,you may skip this parameter.

calling a sip phone

im searching for a simple method to "ping" a sip:user#ip and get back a status like "available for call" , "busy" , "not connected" if the first two require to make his phone ring, thats ok
(optionally if necessary to call them to see the status then it was nice to include a senders number so that i can identify my server on the phone display when its checking the status or to play a short signal .wav in case someone takes up, so that they know what it was)
.....something like sipsak -x 1200 -C random#ownip -s sip:adressee#hisip -vvv...
gives me "406 Not Acceptable without Contact header"
i did not try anything else yet
i already wonder if the sending call still needs to be logged in at an isp then?
You're probably looking for the OPTIONS message. The reply to an OPTIONS does two things - first, it tells you the capabilities of the remote party and second, more importantly, the Status-Code returned is the Status-Code you would get if you'd sent an INVITE.
According to sipsak's documentation you're looking for this:
sipsak -vv -s sip:nobody#foo.bar
SIMPLE will work, but it may be overkill for what you want to do. See http://en.wikipedia.org/wiki/SIMPLE
Of course, not all SIP phones support SIMPLE.

Resources