Slack Interactive Messages: No POST response from Slack - node.js

I'm constructing and sending the message attachment:
var zz = {
"text": "Would you like to play a game??",
"attachments": [
{
"text": "Choose a game to play",
"fallback": "You are unable to choose a game",
"callback_id": "wopr_game",
"color": "#3AA3E3",
"attachment_type": "default",
"actions": [
{
"name": "chess",
"text": "Chess",
"type": "button",
"value": "chess"
}
]
}
]
}
web.chat.postMessage(message.source.channel, '', zz);
The message with buttons displays fine on Slack, but when I tap a button there's no POST response from Slack to my local ngrok or express route:
app.post('/slackaction', function(req, res)
While other messages are posting fine to this route.
I'm seeing this error from Slack after I tap a button:
"Oh no, something went wrong. Please try that again"
Slack Interactive Messages request_url set as:
https://xxx.ngrok.io/slackaction

Thanks to comments from Taylor Singletary for pointing me in the right direction.
The test tokens or a bot token for Custom Integrations can post Interactive Messages but you need an App to handle them.
To fix it you need to add a bot to your app here: https://api.slack.com/apps
and then get the access token for that bot.
You can use the Slack button generator here: https://api.slack.com/docs/slack-button# to get the OAuth URL and paste it on a browser.
Then from your app handle the OAuth flow, store the access token and use that with chat.postMessage.
Then you should receive the POST request when clicking on the message buttons.

Related

The google action simulator can't reach my web server

I try to test my google assistant application but the console.action simulator can't reach my web server while the "dialogflow simulator" can (Dialogflow simulator screenshot). I don't get any request from it in my ngrok console.
When I write in the simulator "Talk to my test app", I get the following error:
We're sorry, but something went wrong. Please try again.
.
{
"response": "We're sorry, but something went wrong. Please try again.",
"expectUserResponse": false,
"conversationToken": "",
"audioResponse": "",
"ssmlMarkList": [],
"visualResponse": {
"visualElementsList": [
{
"displayText": {
"content": "Sorry, this action is not available in simulation"
}
}
],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 8,
"is3pResponse": false,
"clientOperationList": [],
"projectName": "",
"renderedHtml": "",
"previewStartTimeMicros": "",
"isEmptyResponse": false,
"agentName": "",
"servingModelOutdated": false
}
All the solutions I tried:
I enabled web & App activity on my personnal account (App activity screenshot).
I enabled logs and applied the query "resource.type="global"" but no log appears (except those resulting from the tests carried out with dialogflow).
I have manually modified the webhook address of the simulator.
Webhook simulator screenshot
I deleted my project several times and recreated it.
I tried to invoke the wizard on my phone.
I tried ngrok and localtunnel
On dialogflow, I went to settings => Share and added a new user as Developper (a child account of my main google account). I then went to the IAM console and gave him the following rights: "Dialogflow API Client", "Reader". I accessed the simulator with this account via another browser but the error persists. (Source)
I activated/desactivated the webhook for the intent "Default Welcome Intent".
I changed the language and the localization of the simulator by those which I had informed during the creation of the project (Simulator location screenshot).
Here is a extract of my code:
const {
dialogflow,
actionssdk,
Image,
Table,
Carousel,
List,
} = require('actions-on-google');
const express = require('express');
const bodyParser = require('body-parser');
const app = dialogflow({
debug: false
});
app.intent('Default Welcome Intent', (conv, params) => {
conv.ask(`Salut mec ca va ?`);
});
app.catch((conv, error) => {
console.error(error);
conv.ask(`J'ai rencontré un problème, pouvez-vous répéter ?`);
});
app.fallback((conv) => {
conv.ask(`Je n'ai pas compris. Pouvez-vous répéter ?`);
});
express().use(bodyParser.json(), app).listen(3000);
This is a dedicated page for actions that are stuck in review, but it also offers some other support options.
https://support.google.com/actions-console/contact/support

dialogflow quick reply for Facebook client

When I'm trying to send a response from Node app to Dialogflow using webhook for Facebook messenger client.
Trying to send a quick reply to the Facebook client, however, it is not working and getting the bellow error.
Error: Reply string required by Suggestion constructor
Any help will be appreciated.
const {Suggestion} = require('dialogflow-fulfillment');
agent.add(new Suggestion().setReply('test reply from NodeApp'));
First, you need to update the version of dialogflow-fulfillment package in the package.json file in the inline editor to ^0.6.1 which is the latest one.
Then, I think you can just send quick replies using the statement:
agent.add(new Suggestion(`sample reply`));
Please remember there should have a text response before the replies for Facebook to accept the response object.
Below is a snippet that may help you better.
const {Suggestion} = require('dialogflow-fulfillment');
agent.add(`This is quick reply.`);
agent.add(new Suggestion(`option 1`));
agent.add(new Suggestion(`option 2`));
The above way will work if you are using the Dialogflow Inline Editor as the fulfillment.
If not (i.e, opt to have your own deployment/development environment), you have to send the quick replies as custom payloads within the fulfillment code. (Here also, you have to upgrade the dialogflow-fulfillment package first)
Here is a sample code snippet:
const {Payload} = require("dialogflow-fulfillment")
var payload = {
"facebook": {
"text": "Welcome to my agent!",
"quick_replies": [
{
"content_type": "text",
"payload": "reply1",
"title": "reply 1"
}
]
}
}
agent.add(new Payload(agent.UNSPECIFIED, payload, {rawPayload: true, sendAsMessage: true}))
Hope these will work for you.

How can I get the phone number from Twilio in fulfillment dialogflow

I'm working in a whastapp bot between Twilio and Dialogflow. In one of the intents, I'm sending media files from dialogflow to the user. Here it's the problem, now it's working with my mobile number hardcoded, but I need to access to the user phone number in each case to send the media file.
I develop this in fulfillment dialogflow, inline editor, using some nodejs code, but there I can't access to the user number.
Fulfillment node js
function sendAudioMensaje(agent) {
client.messages.create({
body: 'Body message',
to: 'whatsapp:+34---------', // Text to this number
from: 'whatsapp:+14155238886', // From a valid Twilio number
mediaUrl: 'https://demo.twilio.com/owl.png'
}).then((message) => agent.add(message.sid));
}
I expect that the message would be sent to the current number in each conversation
Twilio developer evangelist here.
As far as I can tell, the Dialogflow webhook request comes with a originalDetectIntentRequest property in the JSON. This contains a OriginalDetectIntentRequest object, which has a payload property that contains the original request.
I'd start by logging the contents of the webhook request to see what is fully available to you though.
Let me know if that helps at all.
In the payload of the OriginalDetectIntent request you will see a JSON like this in the webhook if it's enabled.
{
"source": "twilio",
"data": {
"SmsSid": "",
"Body": "",
"SmsStatus": "received",
"MessageSid": "",
"ApiVersion": "2010-04-01",
"From": "",
"AccountSid": "",
"NumMedia": "0",
"To": "",
"SmsMessageSid": "",
"NumSegments": "1"
}
}

Can a webhook server have no response?

I have a dialogflow implementation using Google assistant, a nodeJS server to serve the webhook calls. Some of the user intents are empty phrases, and they do not need any response from webhook server. However, the webhook must be called with every user sentence.
Can the webhook response return an empty response and not crash while doing so?
The server returns the response in predefined JSON format known to google assistant. When I set this response to NULL OR when I set the payload part of this response to BLANK, the application crashes.
var simpleChatResponse = {
"payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
]
}
}
},
"outputContexts": [
]
};
Actual results: "myAgent1 is not responding" and the application crashes.
No, you can not send an empty response. As the docs state:
The first item in a rich response must be a simple response.

How to send tweet from Google Chrome Extension?

I am following Google oAuth tutorial. And I am having some trouble with authorizing user.
I am sending user to twitter for authorization. As this is chrome extension and there is no callback. I dont know how to send tweet on the behalf of that user.
How I am doing things:
I have a background page that has the code of authorizing user from twitter. On the time when user install the extension, background page send that user to twitter for authorization. My authorization method is getting called with their call back. But dont know if I am having everything to make a tweet.
Now when user will click on extension icon, the popup.html will be appear. And on this page I want user to send a tweet. How?
Following is my code:
manifest.json
{
"name": "TweetChrome",
"version": "1.0",
"description": "Tweet from Chrome",
"browser_action": {
"default_icon": "images/share.png",
"popup": "popup.html"
},
"permissions": [
"tabs",
"http://ajax.googleapis.com",
"*://*.twitter.com/*",
"clipboardWrite"
],
"options_page": "options.html",
"background_page": "background.html"
}
background.html
I am getting some html page markup in resp of callback method. I dont know what it is for?
var oauth = ChromeExOAuth.initBackgroundPage({
'request_url': 'https://api.twitter.com/oauth/request_token',
'authorize_url': 'https://api.twitter.com/oauth/authorize',
'access_url': 'https://api.twitter.com/oauth/access_token',
'consumer_key': 'key',
'consumer_secret': 'secret',
'scope': '',
'app_name': 'TweetChrome'
});
oauth.authorize(onAuthorized);
function onAuthorized() {
var url = 'https://api.twitter.com/oauth/authorize';
/*as they are optional, i left empty*/
var request = {
'force_login': '',
'screen_name': ''
};
oauth.sendSignedRequest(url, callback, request);
};
function callback(resp, xhr) { alert('it get called too'); };
popup.html
To tweet I am using a borrowed twitter.js. I didn't wrote it.
Twitter.verify_credentials({install: true});
Twitter.update("test");
My approach of oauth is right on having it in a background page? As my authorization is getting call how much far I am to make a tweet for a user?
Any help will be appreciated. I am hopeful to solve this issue to finish my extension.
You don't need to request https://api.twitter.com/oauth/authorize in onAuthorized - once you get to that function, you already have a key and the user has authenticated.
Try requesting http://api.twitter.com/1/account/verify_credentials.json in onAuthorized instead. You should see a JSON response with the user's information.

Resources