Messenger Bot Fails to Respond - node.js

My bot has been approved and is available publicly (see image), but it does not respond to anyone besides the developer.
I have it hosted on Heroku. I have tried to debug it with a ton of console logs, and I have realized that it doesn't log the "Enter App.Post" (see below) when any one other than the developer sends it a message.
Has anybody else experienced this behavior?
/// Facebook verification
app.get('/webhook/', function (req, res) {
if (req.query['hub.verify_token'] === '***************') {
res.send(req.query['hub.challenge'])
}
res.send('Error, wrong token')
})
/// Star up the server
app.listen(app.get('port'), function() {
console.log('running on port', app.get('port'))
})
app.post('/webhook/', function (req, res) {
console.log("Enter App.Post");
messaging_events = req.body.entry[0].messaging
for (i = 0; i < messaging_events.length; i++) {
....
Update: I found the following logs:
Error: { message: '(#10) Cannot message users who are not admins, developers or testers of the app until pages_messaging permission is reviewed and the app is live.',
type: 'OAuthException',
code: 10,
fbtrace_id: 'CVUDg****' }

Are you sure your Facebook messenger bot has been approved by Facebook?
They have to formally approve specifically the messenger bot before anyone besides admins developers and testers can use it.
There's nothing in the code provided that would stop it from receiving messages from other users, so I'm guessing your bot hasn't actually been approved by Facebook yet.
If you're trying to test it with a user besides yourself, add them as a tester and they will have access to the bot, pre-approval.

Related

Node / React Authentication API callback STUMPER

I've been developing for a year and change and this maybe a novice question but I've tried EVERYTHING (~150 hours worth of tries, YIKES) I will post my React Frontend and my Nodejs backend to hopefully get some clarity.
Key notes:
-I am using Auth0 authentication to build an api with a nodeJs server
-Auth0 says to use an https:// call which my localhost:3000 is not. However, everything about AUTH0 works except the API call invoked when a user logs in to redirect them and display their information on their profile. I have only found one solution to this which is a reverse proxy https:// server to make calls (I can stop here if this is the issue lol unless another easier method is out there). Also why would AUTH0 require production https servers to test???
-I have the correct CORS enabled on AUTH0's site and 99% sure NodeJs (I can get a console.log response from my API) and have tried many ways on the front end and backend
to solve.
Help would greatly, greatly, be appreciated.
Code:
function URLChecker() {
// setTimeout(function(){
// console.log("Executed immediately");
if (location.pathname.indexOf('/profile/') === 0) {
//setToken(true);
return true;
}
}
function tokenChanger() {
setToken(true);
console.log("Your token is presented as...", token)
}
useEffect(()=> {
//console.log("url checker is:" + URLChecker());
if(URLChecker() == true){
tokenChanger();
console.log(location)
if (token) {
console.log("token exists");
axios.defaults.headers.get['Access-Control-Allow-Origin'] = 'http://localhost:3000';
axios.get('http://localhost:8080/profile')
.then(res => {
//console.log(res);
console.log(res.data);
}).catch(error => {
console.log(error);
console.log("API for user FAILED")
})
}
app.get('/profile', requiresAuth(), (req, res, next ) => {
console.log(req.oidc.user);
res.header("Access-Control-Allow-Origin", "*");
res.redirect(http://localhost:3000/profile/${((req.oidc.user.nickname))})
});
(res(req.oidc.user) returns a localhost:8080/profile page that is blank with the JSON of the user's information displayed. My next step is to obviously make my frontend call a different API instead of /profile to hit an authentication required api that will return user data, however no matter what I've tried I always get stuck with the same error message. I am so close and don't know whether to stick with AUTH0 to solve this error or going with Google authentication which I hear is nice.
Thank you,
imgur link to error message on my frontend

Botbuilder - How to ignore user response without exiting prompt dialog

I have a multipatform bot (node.js through Azure Botframework) that uses a series of prompts to play a game with the user.
In group mode, such as on Kik or Slack, it waits for responses addressed to the bot.
However, I haven't found a way to simply ignore a message that doesn't address the bot. The solution I found ages ago was to simply reply with a new blank prompt:
builder.Prompts.text(session, "");
And this worked fine. However recently Slack must have changed something, because now this causes an error and the bot restarts.
How do I make the bot ignore certain responses without ending the dialog?
If suggesting a duplicate, please ensure it actually addresses this issue. Many other questions allow for the dialog to end, however this would interrupt the game.
You can setup middleware, as mentioned by Gary, that intercepts incoming messages and only processes it if the bot is #mentioned:
bot.use({
botbuilder: function (session, next) {
var message = session.message;
var botMri = message.address.bot.id.toLowerCase();
var botAtMentions = message.entities && message.entities.filter(
(entity) => (entity.type === "mention") && (entity.mentioned.id.toLowerCase() === botMri));
if (botAtMentions && botAtMentions.length) {
next();
}
},
send: function (event, next) {
next();
}
})

Chatbot messages do not show up in Facebook Messenger chat heads

I am developing a chatbot for Facebook Messenger using Microsoft Bot Framework. The bot sends the user proactive messages (reminders). Unfortunately, for some reason the messages never show up in a chat head (the Android widget for conversations), nor pop up a chat head if it wasn't present on the screen before. It does happen for other chatbots (Jarvis, for example).
This is the code that sends the reminders:
Reminder.find({ next_reminder: { $lte: new Date() } }, (err, res) => {
if (err !== null) {
return console.error(err);
}
res.forEach(reminder => {
// Build a notification message and address it to user who created the reminder
const msg = new builder.Message().text('...');
bot.beginDialog(reminder.user_address, '*:/sendReminder', {message: msg, nudnik: nudnik});
});
});
};
};
I have also tried bot.send(msg, () => ....) and session.beginDialog('sendReminder', msg). However, there is still no indication from Messenger when the message is received. What could go wrong here?
OK, I figured it out! Apparently, the default notification setting for a Facebook message is not to show a notification. To change it, in NodeJS you should add channel-specific data to the message with the following code:
msg = msg.sourceEvent({
facebook:
{notification_type: 'REGULAR'}
});
You can discover more in official documentation by Microsoft (here and here) and also in this Github discussion.

Stripe login link URL does not work

I am following the project at stripe-connect-rocketrides, and running it on my own NodeJS server to try to learn how to integrate Stripe payments. I've setup pretty much everything,
but am now running into an issue where the login link doesn't work.
To start, I have a Stripe Account ID that I have created for the user who logged in and stored in the database. Now, when I try to log the user in to the Stripe Dashboard, I know that I need to use the Create Login Link API to fetch a URL from Stripe that I can redirect users to. The URL I get is: https://connect.stripe.com/express/somehash
The problem is, when I redirect users to https://connect.stripe.com/express/somehash, this is the response I get:
{
"error": {
"code": "unexpected_api_error",
"message": "An unexpected error occurred",
"type": "api_error"
}
}
This is code in the project that redirects the users to that page:
router.get('/transfers', pilotRequired, async (req, res) => {
const pilot = req.user;
// Make sure the logged-in pilot had completed the Stripe onboarding.
if (!pilot.stripeAccountId) {
return res.redirect('/pilots/signup');
}
try {
// Generate a unique login link for the associated Stripe account.
const loginLink = await
stripe.accounts.createLoginLink(pilot.stripeAccountId);
return res.redirect(loginLink.url);
} catch (err) {
console.log('Failed to create a Stripe login link.');
return res.redirect('/pilots/signup');
}
});
I wonder if this is because the URL expired. But I always get the API error from Stripe as soon as I receive the URL. Any help would be greatly appreciated

builder.Prompts.text not working after being hosted remotely

I have a simple bot that fetches news articles based on a user prompt. The entire flow works fine locally using emulator but after being deployed to a server the bot fails when it hits a builder.Prompts.text block. Below is my code and you will see a "Asking article count" prompt which is where it stops in flow.
Bot shows accepted when testing on the BOT Framework page
Bot is receiving messages via WebChat and Slack
Bot also shows 0 issues for each channel after interacting
var bot = new builder.UniversalBot(connector);
var intents = new builder.IntentDialog();
bot.dialog('/', intents);
var HHCC = require('./hhcc.js');
intents.matches(/^news/i, [
function(session) {
console.log("Intent Given!");
session.beginDialog('/news');
},
function(session, results) {
session.send('Enjoy reading!');
}
]);
bot.dialog('/news', [
function(session) {
console.log("Asking article count");
builder.Prompts.text(session, 'How many articles would you like to see?');
},
function(session, results) {
session.sendTyping();
session.conversationData.count = results.response;
HHCC.getNews(session.conversationData.count, session, function(newsArticles) {
newsArticles.forEach(function(newsCard) {
session.send(newsCard);
});
session.conversationData.news = newsArticles;
console.log(newsArticles);
session.endDialog();
});
}
]);
server.post('/api/messages', connector.listen());
Ive checked all logs and can't seem to find any clues as its failing pretty silently.
Have you attempted using builder.Prompts.number() instead of .text()? It only accepts numbers and (I'm guessing you're doing this) you won't have to parse the results.response into a number. Without provided error messages or logs it's difficult to help.
One thing you might have to look out for (if using builder.Prompts.number) is if a user provides a decimal, as the prompt will accept this input, requiring the bot to round to the nearest integer.
Also, if you've saved the results.response into your session object, you will not need to pass in session.conversationData.count as another parameter to HHCC.getNews(). You can instead access it from session in your function.

Resources