What is Callback URL in Facebook webhook page subscription? - facebook

I'm trying to stream the real time public feeds using Facebook Web-hook API. Here I'm trying to set up a page subscription in Web-hook console. There is a field called Callback URL. What is this URL about?
I have also tried going through the documentation for Setting up callback URL. but I Couldn't figure out.
https://developers.facebook.com/docs/graph-api/webhooks#setup
Cant the callback URL be SSL localhost? Whenever I try to give a localhost URL i get a error message "Unable to verify provided URL".

You can forward the request to localhost with the following:
Download and install ngrok from https://ngrok.com/download
./ngrok http 8445
Subscribe your page to the Webhooks using verify_token and https://<your_ngrok_io>/webhook as callback URL.
Talk to your bot on Messenger!

Facebook will make a request to that URL from their servers to deliver the updates – so of course it has to be publicly reachable over the internet, which a localhost address obviously isn’t.
Facebook will send a request to that URL if any data for the object and fields that you subscribed for changes. And what the data structure looks like, is described in the docs. For page fields it returns the new content directly; for user fields it will only tell you which fields have changed, so that you can then make a request for that data.
You can only get real-time updates for pages that you have admin access to. And the Public Feed API is not deprecated; but access to it is limited to a small set of Facebook partners. You can not apply to become one – if you absolutely need this kind of data, then you’ll have to contact one of those partners and have them develop a solution for you.

I think it means that you need a server which has a fixed IP address. If you want to use the real time update from the Facebook, you need to build a server which receive the post request from Facebook and meanwhile keep a long connection to you endpoint so that the endpoint can receive message pushed by the server.

You have to write a webhook to get the fb request from fb server as well as the webhook should be running in a public ip address, this public url is the one to be filled it out on the callback url box. So that the fb server could update you through the url which is nothing but the url of running webhook. To get the public url address for fb recognising your webhook, you can use ngrok or can host your webook in heroku.

Related

Where to find Callback URL

I am using webhook to create bot for page. I got everything but not getting where to get Callback URL
I think you're misunderstanding the concept of webhooks. The Callback URL is simply the location that you want Facebook to deliver messages to.
For example: if you are running a server at https://my_awesome_service.com and you want it to receive facebook updates, you would first create a route (let's say /v1/facebook_subscriptions) in your service. Once that's ready, you would insert https://my_awesome_service.com/v1/facebook_subscriptions into that Callback URL field. Facebook will then do a GET on that URL, which your server must reply to correctly. After that's done, Facebook will start sending you POST's, based on the subscription fields you set up.
There's a lot more information about this in the Facebook API Docs.
Callback URL(s)
A callback URL indicates where the user is to be redirected after a successful sign-in. Choose at least one callback URL, and it should:
Be an absolute URI.
Be pre-registered with a client.
Not include a fragment component.
See OAuth 2.0 - Redirection Endpoint.
Amazon Cognito requires HTTPS over HTTP except for http://localhost for testing purposes only.
App callback URLs such as myapp://example are also supported.

REST API: Providing redirect URIs to external services using client app domain

Background
I have a RESTful API accessed through the domain http://restapi.com
I have a client app using http://restapi.com. The client app has the domain http://myapp.com
The way I have my HATEOAS setup is that the API presents URIs without a domain. So instead of http://restapi.com/some/resource, it contains links to resources like so /some/resource. Example API json resource below:
{"_links":{"self":{"href":"/some/resource"}}}
The benefit this has is that the API doesn't need to know about the client app, and the client app has to do very little to get the correct resource from the API and doesn't have to reformat all the URIs in the resource. For example, in the client app, the following URI would be used by the browser http://myapp.com/some/resource. When the app gets the request, it then needs to call the API to get the resource and simply swaps the domain i.e. http://restapi.com/some/resource.
This has been successful so for, and allows a lot of flexibility to have different clients use the API with the only knowledge required being the initial end point (domain) of the API. It also completely decouples the API from the client apps.
The problem I have run into is that I have started using some external services (specifically PayPal adaptive payments) where I need to provide a redirect URL for cancelled payments and successful payments. For example, the browser navigates to http://myapp.com/payment. The resource returned by http://restapi.com/payment presents a link to PayPal. Without going into too much detail, the API has to ask PayPal for a payment ID, which can then be used to create a link to a PayPal payment e.g. http://paypal.com?PayId-123456. Part of the creation process requires that URLs are provided to redirect on payment cancellation or success. Again, don't want to go into details, but when requesting a PayId from PayPal, the redirect URLs are sent as variables to PayPal, and I guess PayPal stores them against the specific PayId created.
The browser navigates to the link returned in the resource - http://paypal.com?PayId-12345. Payment is made and PayPal then uses the redirect URLs as needed to redirect back to my app e.g. on successful completion of payment, PayPal should redirect to http://myapp.com/paymentcomplete. Note: I realise that this is not a restfully named URI, but it simplifies building up the description of my problem
Problem
The problem I have may now be obvious. I need to redirect back to http://myapp.com/paymentcomplete, BUT its the API that provides the redirect URL to PayPal. It has no knowledge of the client application. Since PayPal is an external service, the full URL must be provided. The best the API can do is send http://restapi.com/paymentcomplete as the redirect URL, but if PayPal redirects to this, the resulting response will be a JSON string (the output format of my API) not the nicely formatted page of the client app.
My question is, what is a good way to correctly provide the redirect URL to PayPal?
One thought I had was to make the client application handle creating the PayPal PayId, but I don't like this option as I would like to keep the creation of the PayPal payment ID on the API side. It would also require every client app to provide its own implementation, something I also don't want.
The other option I though of was to ask the client to provide its domain in the request. Currently the request the client makes to get the resource with the link to PayPal is GET http://restapi.com/payment, but I could use POST http://restapi.com/payment with the client providing its domain as a param. The API can then use this to construct the correct redirect URL. I don't really like this idea either as its seems a bit hackish and also requires the app to know that is must fill in this field i.e. a human user wouldn't fill the domain input in.
Additional solutions, or thoughts greatly welcomed.
As you had already mentioned, PayPal is an external api that requires this additional parameter and you do not have control over it. Looks like the client is the only party that can provide the Redirect URI Information.
Couple of ideas come to mind.
The client could send the redirect uri to restapi via header and thus
keeping your rest urls intact. This is a grey area and not a violation of restful api
in my opinion. (Then again, its just my opinion).
The restapi could return the response with a placeholder for the
client to fill in before rendering. This way the API need not know
about the redirect uri and the responsibility is left to the client
which has this information.
It would be nicer if you could implement option 2 with executing couple of lines on Javascript code on the browser to fill-in the placeholder. Which is easy. Ultimately, only 2 end points of this transaction would be aware of the redirect uri - browser & paypal.
This alleviates most of your concerns. The job of handling PayPal id will continue to remain with your API.
You should be able to use the Referer header to determine the client's full URI. It might be populated automatically for you. If not, you can add it yourself. The URI class has methods to pull out the client's host for you. When the API builds the PayPal URI to return to the client, it can include the client's host.
Note that referer is not always included and sometimes gets stripped by intermediaries, as detailed on the wiki page. Since you control both the client and the server in this case, you should be able to tell everybody to play nicely.
I would keep the GET http://restapi.com/payment and pass in a query param with the client domain
GET http://restapi.com/payment?domain=http://myapp.com (of course, the "http://myapp.com" needs to be encoded)

Is it possible to send a Facebook request without a dialog?

I need to send a request to a user using my custom dialog (which user has other options). After this, I have 'users_ids' to send requests.
Is it possible do this using Graph API?
(I did not find any way to do this at Requests Dialog.)
There are two types of requests as mentioned in the Social Channels documentation (section Requests): User-generated and App-generated.
You can send App-generated requests to the user both from the server and client side with out the need of using a dialog.
How ever you can send these requests only for a user who authorized your app, as it described in the connection in the user object.
The User-generated requests can only be sent using the dialogs, as the name implies.
The best source for this issue is the Requests documentation.

I'm unable to de-authorize callback

I want to delete record of those peoples who have remove app from their application's list, to do this I have entered that URL where I make a code to delete record of active user from my database in de-authorize callback. But still I'm unable to de-authorize users from by db.
Edit: See Facebook Deauthorize Callback over HTTPS for what my original problem really was. Summary: Improper web server configuration on my part.
Original answer was:
One potential problem has to do with https based deauthorize callbacks. At least some SSL certificates are not compatible with the Facebook back end servers that send the ping to the deauthorize callback. I was only able to process the data once I implemented a callback on an http based handler.
Some things to check...
That the URL of your server is visible from facebook's servers (ie not 192.168 or 10.0 unless you've got proper firewall and dns config).
Try using an anonymous surfing service and browsing to the URL you gave facebook - do you see a PHP Error?
Increase the loglevel for PHP and Apache/IIS to maximum and see if you get any more information
We can't do much more unless you give us your code...

Error code 100 (Can only call this method on valid test users for your app)

getting the error {"error":{"message":"(#100) Can only call this method on valid test users for your app","type":"OAuthException"}} whenever trying to write to any facebook end point. Reading (GET) works fine, writing (POST) fails. Does anybody know how to resolve this?
I have also opened a ticket on FB dev site:
http://developers.facebook.com/bugs/184198634991192?browse=search_4e93328871c8a3231774584
The problem does not occur is I would shoot the POST request from my browser as if I am the user.
The problem does occurs only when sending from our servers on behalf of the user from one of our dev machines which have other subdomain names instead of www (such as dev1.blablabla.com & dev2.blablabla.com, while the app is registered to www.blablabla.com).
So the question is, does facebook attempt to do a reverse DNS lookup on all write requests to verify the source?
I believe your requirement is to get the user details of the owner of Facebook access token (normally the currently logged in user)
For that you have to issue a GET request and not a POST request.
The reason why it works when fired from the browser is that when you submit a query through the address bar it is send as a GET request, and when sent from your server it is send as POST and fails producing the error message mentioned in your post.
Facebook doesn't do a reverse DNS lookup on your write request and not need to configure anything in your server related to it.
Hope the answer is clear enough for you.