Messenger bot broken after renaming it - php

I have a Messenger bot hosted on Dropbox, and deployed on Heroku.
It worked fine.
I renamed it on Heroku, then also renamed it (to match that change) on developers.facebook.com
It is no longer working (doesn't reply to any command, while it did reply to commands when it worked).
What other setting should I update or check?
I can post the code, but there was no code change at all - from when it worked, until it broke - so that probably won't help.
Edit:
When trying to generate a new token, I get:
Invalid Scopes: manage_pages, pages_messaging, pages_messaging_phone_number, pages_messaging_subscriptions. This message is only shown to developers. Users of your app will ignore these permissions if present. Please read the documentation for valid permissions at: https://developers.facebook.com/docs/facebook-login/permissions
Edit:
Making the bot private ("developer mode") allowed me to generate a new token. I pushed the new token to Dropbox and Heroku, and the bot started responding to commands again (working), but making it public broke it again.
Edit:
I now see that under the Bot's page, in Messenger > Settings, it says that I need permission to use the "API Send (pages_messaging)". I've sent a request for that...
Are such permissions always required for a Bot to work?
I'm not trying to access any user info (not that I know of), and the docs said that one can immediately make a bot public, unless it needs to access private info. All my bot does is reply certain messages to certain commands.
Notes:
I never tested it with an account other then mine (the developer account for the bot), so it can be that it never "worked" while public. It is newly made.
By now, the title of this post maybe should change to "bot broken after making it public", but I'm not sure about that being the case just yet.

TL;DR
Renaming shouldn't be an issue, provided you rename it in all necessary locations (including but not necessarily limited to: developers.facebook.com, Heroku).
In long:
It turns out I never tested the bot from an account other than the admin, so it never "stopped working", rather was never published yet. Renaming is not a problem (as long as you also rename it on developers.facebook.com)
In order to have it work for other accounts (I.E. make it public), you need to request permission to use pages_messaging. Scrolling down on the "Messenger" page (on developers.facebook.com), you can initiate the request, and it will prompt you to fill any required information, such as your app's privacy policy, icon, as well as temporarily add several accounts as testers for your app (these accounts will be provided to you in that prompt), plus adding those same accounts as editors of the Facebook page you want to use the bot on.
Notes:
I'm not sure if pages_messaging is required for a Facebook bot altogether, or only if one also wants the bot to be available on the Messenger platform, but because that's what I wanted for my bot, I selected that feature when setting up the bot to be public and initiate the request.
Initiating a request will toggle your bot back to "private" (invisible to non-admin accounts).
A useful sanity check (which helped me a few times) if things break and you are not sure why, is generating a new token by "selecting" your page again under the App's settings (don't forget to actually use that token and push changes).

Related

Know if access_token is for an App Folder or Full Access?

We have a bunch of mixed up authenticated accounts from the past few years in our database, where some were given "Full Access" early on and later it was changed to just using the "App Folder".
Is there any way of using the API to know if the access_token we have is within an App Folder, or to the whole account?
We basically want to switch all accounts to App Folders, but only want to alter those that need it. We'll have to move folders and also store a default path in the DB.
Having looked through the documentation I can't see anything that gives this info, any thoughts?
The Dropbox API is designed so that the permission level (e.g., app folder vs full Dropbox) is transparent to the app, so there isn't a good/official programmatic way to detect the permission for any given access token. We'll consider this a feature request though.
That said, some features of the API are only accessible to full Dropbox apps, so you could use those as a way to implicitly detect the permission. For example, the /2/sharing/list_folders endpoint is only usable by full Dropbox apps:
Apps must have full Dropbox access to use this endpoint.
That could potentially work for you, though it's still not a great solution, since in the case of an app folder app, you'll get a 400 error with a plain text body (and not a nice structured 409 error) so you can't reliably tell the difference between that and some other 400 error. To work around that you could match against the error message, but that could change of course:
Error in call to API function "sharing/list_folders": Your API app is an "App Folder" app. It is not allowed to access this API function.
Thanks to #Greg for pointing me in the right direction.
Because /sharing/list_folders doesn't return any errors I was unable to distinguish the difference between Full Dropbox & App Folder access.
For future reference, to solve my query I did the following:
Sent an API request to /sharing/get_folder_metadata with a made up shared_folder_id
This will always return an error (unless you somehow managed to pick a shared_folder_id that exists!)
If the error contained a response (which will always be invalid_id) then the access_token has Full Dropbox access
If the error was empty, then the access_token has only App Folder access

Other users cant login using facebook's api on localhost

I'm working with the PHP SDK on localhost. I've looked at other questions posted on here like this:
Can't login to website using facebook's api's
Domains, urls, login urls all match. The app secret and id match, sandbox was never turned on (double checked to make sure). I had trouble moving it to a new laptop, cuz the folder i put it in was called something else. After i changed that it worked fine.
The problem I'm having is, I as the owner of the app can log in and it does what i want it to do, but if i have a friend, or another user try to log in, it asks for permissions, then shows the "An error has occured, Please try later" facebook error page. Not entirely sure why its doing this, because i havn't hardcoded my info into it at all.
I've used different browsers, cleared cookies, nothing seems to work. Any ideas would be helpful.
EDIT: i've also tried destroying the session before login, didn't help.
Thank you.
Other people cannot access your app 'on localhost' if they are not using your computer, which is the local host.
If you want other people to be able to use your app, they'll need a copy of your code, running on their local machine, or you'll need to make it available via a publicly accessible IP and/or domain name.

How does session/authentication work with nginx/NHPM/PHP-FPM?

So, I'm looking at architecting an application using nginx with the nginx-http-push-module and PHP-FPM, and after lots of fun configuring, I got it working to the point of handling PHP pages as it should.
What I don't get, though, is how sessions are supposed to work - all of the examples I've seen for nginx+NHPM run through the publisher-subscriber system, but it's never clear what should happen if the subscriber channel is going to be, effectively, unique to a subscriber. Think of a chat system with a public channel and a private channel for each user, for example.
Now, in a conventional PHP setup, you'd be passing the cookies to PHP, looking up the session from there, and handling the rest of the page based on whether the user was authenticated or not, but with PHP-FPM and long-polling, it doesn't seem like it should work like that.
I can understand if the request is a non authenticated user, you just dump them with an error message and terminate the long-poll from the client knowing that it's not valid, but with a valid request, you almost need to poll from the client, authenticate in PHP, then disconnect but leaving the request open - and I'm not sure how that part works.
Can anyone explain how it should be achieved, ideally with an example if possible? Please note I'm not looking for HTTP Basic authentication here, I need the authentication to be looked up against a separate data storage which is in MongoDB.
Disclaimer: I can't clearly understand your 4. paragraph.
As far as I can tell, the main problem with authentication in NHPM is that the PHP application gets absolutely zero notification of incoming connections. The Comet part of your setup is write-only for PHP.
A possible solution follows, I'll be trying this out in the next days.
nginx configuration:
push_subscriber_concurrency first: so that the channel can only be used by the intended user
push_authorized_channels_only on: not strictly necessary, but good to have in my opinion
Authorization workflow:
Client sends credentials via old-fashioned requests
Server authenticates, and generates a token (channel id). Creates the channel and responds with the token.
Client tries to open long-poll to the given channel.
If it fails (possibly because the channel was hijacked), it tells the server that channel so-and-so is invalid. Mind that we use old-fashioned requests here, so you can use any auth method. Server deletes the channel. Back to step two.
If the connection is successful (you probably won't know this, only that it hasn't failed), the channel can be considered authenticated.
Note that if your application should be accessible from multiple pages in the same browser with the same login, then you'll need to prepare for multiple channels per user.

Facebook Connect - Mobile

I am currently in the process of creating a mobile version of my web app.
The app is being developed with Facebook's PHP Client Library.
The issue:
I am using the following mobile url to allow users to log in using the mobile devices:
http://m.facebook.com/tos.php?api_key=APIKEY&v=1.0&next=http%3A%2F%2Ftweelay.net%2Fm.php&cancel=http%3A%2F%2Ftweelay.net%2Fm.php
APIKEY being my app's actual Facebook API key.
In the url I am telling Facebook to redirect the user back to http://tweelay.net/m.php when the user signs in or clicks cancel on the log in screen. I am pulling my hair trying to figure out why it keeps sending the user to http://m.tweelay.net/m.php which is currently an invalid end point.
I have gone through all of my app's settings on Facebook and I cant find any that reference http://m.tweelay.net and going through all of my source code I cant find any that reference the m. sub-domain either.
Any ideas? Is there a setting I'm missing? Maybe a Flag in the library?
I've seen Facebook do this when detecting the mobile browser type and also sometimes randomly through Firefox (it can also happen when trying to get to facebook.com). I've managed to reset it sometimes, but it's not a guaranteed fix.
If you want to be sure the user makes it to your correct site I suggest creating the subdomain and redirecting traffic to your usual site, it's what I did and now I don't worry about it reverting back.

How do I detect if a Facebook connect session hasn't expired from PHP/the server?

For my application I need to know if a Facebook Connect session is valid from the server side.
The Javascript API lets you know if you are connected to Facebook or not, but it seems that this can't be done from the PHP client library.
The scenario where I need it is similar to the following:
Log in to The Run Around using Facebook connect.
Open Facebook in another tab.
Log out from the Facebook tab (not The Run Around).
Go back to the Run Around tab.
Enter a new entry, but deactivate the "Publish this run to Facebook" checkbox.
After submitting the form your run will get published though you logged out before! After that call, the site will log you out because the Javascript API will try to validate your status.
In the 5th step, the application should check with Facebook if the session has expired or not (or use a workaround). The Connect implementation of The Run Around is flawed and shouldn't be used as an example because of this security issue.
While I understand your analysis of the situation, this is actually the correct behaviour.
The Run Around is a Facebook Connect site, which means that it is completely separate from Facebook, as it should be. When you use FB Connect to link your FB account to the Run Around site, it establishes a local session and account for you in the Run Around database. This is technically what you are logged in to The Run Around with. Once this happens, your Facebook session is entirely irrelevant unless The Run Around wants to retrieve information about you from Facebook.
There are options to provide a FB Connect site with closer linkage to Facebook if you want to. See Detecting Connect Status and the FB.init() parameters for more on this. The Run Around has utilized this to force a logout of the local session once it detects that you are no longer logged in to Facebook. However, this only occurs once a page change or action happens and the Javascript runs to verify your FB session status.
The overall effect of how this all works is that Facebook Connect sites retain the ability to manage users locally, and only utilize Facebook features when needed and/or possible.
A friend told me the way to know if a session is valid or not:
http://wiki.developers.facebook.com/index.php/Users.getLoggedInUser
This method uses the session key as a parameter and returns the user id. If the session has expired, an error code is returned.
NOTE:
I won't use this in my application, as Zombat said, my app should keep its own session. I'll do what Digg does: be consistent with the log in and log out procedure by not automatically logging in and out when someone logs on Facebook.
The Run Around tries to do everything automatically, but that is problematic, specially because the app doesn't check the session from the server side.

Categories