I'm doing a facebook messenger bot. After you start it, it makes a call to WebHook.
Unfortunately after the first start will not stop throwing the same call with the same parameters.
The settings are:
message_deliveries;
message_reads;
messages;
messaging_optins;
messaging_postbacks.
The source code is this: https://github.com/Ellusu/nuraghebot-facebookmessenger/blob/master/index.php
Where am I wrong?
Why does only one call?
By your code I decided that you can't setup your webhook, so from documentation
At your webhook URL, add code for verification. Your code should
expect the Verify Token you previously defined, and respond with the
challenge sent back in the verification request. Click the "Verify and
Save" button in the New Page Subscription to call your webhook with a
GET request.
So, for PHP to make a success with webhook setup you must return hub_challenge parameter.
Define $verify_token with your token and add something like:
if (!empty($_REQUEST['hub_mode']) && $_REQUEST['hub_mode'] == 'subscribe' && $_REQUEST['hub_verify_token'] == $verify_token) {
// Webhook setup request
echo $_REQUEST['hub_challenge']; exit;
}
After success setup, you can delete this code from your script.
Or, if your webhook already hooked:
You should skip any read and delivery messages, like this:
if (!empty($input['entry'][0]['messaging'])) {
foreach ($input['entry'][0]['messaging'] as $message) {
// Skipping delivery messages
if (!empty($message['delivery'])) {
continue;
}
// Skipping read messages
if (!empty($message['read'])) {
continue;
}
}
}
Or, you can deselect message_reads & message_deliveries checkboxes in Page Subscription section of your Facebook Page Settings/Webhooks.
Related
Am creating a payment app on Shopify but am stuck.. any assistance will be appreciated.
Shopify must receive an HTTP 2xx response with a redirect url for the payment session creation to be successful.
How do you send such when no endpoint is provided or probably am missing something but I have done all the configuration correctly. Am stuck at Your payment can’t be processed for technical reasons - above must be the cause just I don't know how to go about it. The redirect url is required to redirect customer back to partner's payment page for payment processing.
Relevant documentation: https://shopify.dev/apps/payments/processing-a-payment#http-response-example
Here is the endpoint with the redirect URL and status code.
POST https://{shop_domain}/payments_apps/api/{api_version}/graphql.json
mutation PaymentSessionResolve($id: ID!, $authorizationExpiresAt: DateTime) {
paymentSessionResolve(id: $id, authorizationExpiresAt: $authorizationExpiresAt) {
paymentSession {
id
status {
code
}
nextAction {
action
context {
... on PaymentSessionActionsRedirect {
redirectUrl
}
}
}
}
userErrors {
field
message
}
}
}
I'm having trouble trying to verify paypal webhook signatures with PHP. Using the new V2 of paypals APIs I am receiving the paypal webhook on my page.
However I can not seem to successfully validate the signature.
From the link HERE I got some sample webhook validation PHP code from paypal.
I can not get it working, I don't know where I am supposed to get bootstrap.php from in the paypal code. The paypal information seems incomplete or half baked. Paypal seems to be terrible to set-up compared to Stripe.
Has anyone got experience of validating paypal webhook signatures with PHP when using V2 of the paypal APIs ?
Well I have come to the conclusion that the Paypal developer information is rather poor, it is scatted all over the place, on multiple different pages and sites. The examples they give on the paypal developer website HERE are not a complete picture of what is required to validate a webhook signature. Stripe developer documentation is much better formatted and concise.
Installing Paypal Checkout V2 SDK does not give you the necessary development tools to validate paypal webhook signatures i.e. you can process payments and receive webhooks but you can not validate the webhook signatures....I know stupid. Tip do not download the SDK directly as you will not include the required autoload.php file. Use composer to install Paypal Checkout V2 SDK so that you get the autoload.php file.
Once you are to a point that you can process payments and receive webhooks form paypal you need to install the another SKD called Paypal Rest API SDK. Again use composer to install the SDK so that you get a autoload.php file which you will need.
When you install Paypal Rest API SDK amazingly you will still be missing files that are required to validate the payapl webhook signatures. I can find no mention of these anywhere on the paypal developer website.
bootstrap.php & common.php
Thanks to #Grumpy I got some samples provided on github HERE
Note you will probably need to modify the samples a bit in order to get them working with your website. Tip set the logger to false and save yourself some bother if you don't have the necessary access permissions to write.
Once you have bootstrap.php & common.php files created you can write the code for your webhook endpoint page i.e. the page that paypal sends the webhook to. I have included my PHP code below for how to validate and then process the paypal webhook. Tip in the below code you need to specify the webhook ID, each webhook that you create in paypal has a unique ID. Also when you are testing you can not use webhook simulator as this will fail validation, you can make manually a payment with your sandbox account details which will trigger a webhook payment event.
Paypal sure don't make it easy, their documentation is all over the place compared to Stripe. The Paypal webhooks can sometimes take several minutes to arrive after a payment is made, very frustrating when trying to debug. Also it's a bit ridiculous that they have a webhook simulator on the paypal developer website that can not be used to validate signatures...if stripe can do it why can't paypal.
<?php
//get the webhook payload
$requestBody = file_get_contents('php://input');
//check if webhook payload has data
if($requestBody) {
//request body is set
} else {
//request body is not set
exit();
}
use \PayPal\Api\VerifyWebhookSignature;
use \PayPal\Api\WebhookEvent;
$apiContext = require __DIR__ . '/bootstrap.php';
//Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
//need header keys to be UPPERCASE
$headers = array_change_key_case($headers, CASE_UPPER);
/*
example header paypal signature content for webhook, these values are recieved as an array, we then need to use this data to verify the payload
CONTENT-LENGTH : 1376
CORRELATION-ID : 6db85170269e7
USER-AGENT : PayPal/AUHD-214.0-54377828
CONTENT-TYPE: application/json
PAYPAL-AUTH-ALGO : SHA256withRSA
PAYPAL-CERT-URL : https://api.paypal.com/v1/notifications/certs/CERT-360caa42-fca2a784-5edc0ebc
PAYPAL-AUTH-VERSION : v2
PAYPAL-TRANSMISSION-SIG : Hc2lsDedYdSjOM4/t3T/ioAVQqFPNVB/AY/EyPNlavXk5WYUfnAmt9dyEP6neAPOjFHiVkXMK+JlLODbr6dalw6i26aFQdsPXqGl38Mafuu9elPE74qgsqNferUFgHi9QFXL+UZCNYcb4mvlDePXZIIAPbB0gOuFGOdEv2uqNwTCSAa/D8aguv1/51FWb3RkytFuVwXK/XNfIEy2oJCpDs8dgtYAZeojH8qO6IAwchdSpttMods5YfNBzT7oCoxO80hncVorBtjj1zQrkoynEB9WNNN9ytepNCkT8l29fQ4Sx/WRndm/PESCqxqmRoYJoiSosxYU3bZP7QTtILDykQ==
PAYPAL-TRANSMISSION-TIME : 2020-04-05T14:40:43Z
PAYPAL-TRANSMISSION-ID : 6dec99b0-774b-11ea-b306-c3ed128f0c4b
*/
//if any of the relevant paypal signature headers are not set exit()
if(
(!array_key_exists('PAYPAL-AUTH-ALGO', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-ID', $headers)) ||
(!array_key_exists('PAYPAL-CERT-URL', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-SIG', $headers)) ||
(!array_key_exists('PAYPAL-TRANSMISSION-TIME', $headers))
)
{
exit();
}
//specify the ID for the webhook that you have set up on the paypal developer website, each web hook that you create has a unique ID
$webhookID = "ENTER_YOUR_WEBHOOK_ID_HERE";
//start paypal webhook signature validation
$signatureVerification = new VerifyWebhookSignature();
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setWebhookId($webhookID);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$signatureVerification->setRequestBody($requestBody);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($apiContext);
} catch (Exception $ex) {
//error during signature validation, capture error and exit
ResultPrinter::printError("Validate Received Webhook Event", "WebhookEvent", null, $request->toJSON(), $ex);
exit(1);
}
$sigVerificationResult = $output->getVerificationStatus();
// $sigVerificationResult is a string and will either be "SUCCESS" or "FAILURE"
//if not webhook signature failed validation exit
if($sigVerificationResult != "SUCCESS"){
exit();
}
else if($sigVerificationResult == "SUCCESS"){
//paypay webhook signature is valid
//proceed to process webhook payload
//decode raw request body
$requestBodyDecode = json_decode($requestBody);
//pull whatever info required from decoded request body, some examples below
$paymentSystemID = $requestBodyDecode->id;
$eventType = $requestBodyDecode->event_type;
//do something with info captured from the webhook payload
}
This seems to work with php 8.1:
if (openssl_verify(
data: implode(separator: '|', array: [
$httpPayPalTransmissionId,
$httpPayPalTransmissionTime,
$webhookID,
crc32(string: $rawRequestBody),
]),
signature: base64_decode(string: $httpPayPalTransmissionSignature),
public_key: openssl_pkey_get_public(public_key: file_get_contents(filename: $cachedHttpPayPalCertUrl)),
algorithm: 'sha256WithRSAEncryption'
) === 1) {
die('OK');
} else {
die('FAILED');
}
I'm having trouble implementing webhooks in FluidReview (used to be SurveyMonkey Apply). Specifically, I want to send a webhook with the applicant and current application status, triggered upon any change in application state, so that we can update our CRM with the latest status data. The problem is that I can't figure out setup the webhooks in FluidReview, and their documentation is abysmal (Fluid Review Webhooks, Fluid Review Triggers). Can anyone help me out by providing an example of setting up a simple or advanced webhook?
Steps followed thusfar:
1) I have a php endpoint on my wordpress site that uses the following code snippet to save the JSON from a webhook to the error log:
if(isset($_GET['fr-listener']) && $_GET['fr-listener'] == 'fr') {
error_log("fr-listener==fr hook caught!");
if($json = json_decode(file_get_contents("php://input"), true)) {
// if($json = json_decode(file_get_contents("php://input"), true)) {
error_log("JSON found");
error_log(print_r($json,true));
error_log(var_dump($json));
// $data = var_export($json, true);
// error_log("data dump: " + $data);
// print_json($json);
} else {
error_log("no JSON found");
print_r($_POST);
$data = $_POST;
}
}
I can use this to successfully catch webhooks from Stripe (I used the above snippet to help develop my Stripe webhook catcher) and get a look at their JSON contents. When I catch one of the webhooks from FluidReview, I get the "no JSON found" response. This is how I have the webhook set:
My Webhook Action
(URL = https://wfadev.pairsite.com/listen?fr-listener=fr, Method = POST, Request content = {{applicant.email}})
2) I have tried both setting simple and advanced webhooks, and neither of them are producing the JSON output I'd expect.
I did some more testing and it turns out that the "Request content" field is just a blank text field. To have it send JSON data from FluidReview, write it out like this, using the piping variables ("{{variable name}}")
{
"first_name": "{{user.first_name}}",
"last_name":"{{user.last_name}}",
"email":"{{user.email}}",
"application_type":"{{user.}}",
"date":"{{date}}",
"trigger":"{{trigger}}"
}
I'm trying to get the FB Messenger Bot API to work. I'm currently on the step where I'm trying to subscribe a webhook. I currently have a script of the following form:
#!/usr/bin/php
<?php
$challenge = $_REQUEST['hub_challenge'];
echo $challenge; # HERE!
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token') {
echo $challenge;
}
?>
However when I try to "Verify and Save" the callback URL I get an error of the form:
The URL couldn't be validated. Response does not match challenge, expected value = '401537941', received=''
namely that my script is sending an empty string. However, if I change the line marked "HERE!" above to "echo 'cat' ", the error message is the same except "received='cat'" as expected. Thus, my script is being executed and is trying to send some content back to FB, but for some reason the $challenge variable is empty. Why could this be the case?
Thanks!
if($_GET['hub_verify_token'] === "validation_token"){
echo($_GET["hub_challenge"]);
} else {
echo("error");
}
There are probably extra string in your response as you are not exiting after printing challenge. Try your script in browser and inspect html to see if there is anything extra.
Use the following code as you would need to seperate verification code from your work webhook calls. Also verify token is not something you create from Facebook, its your own keyword
/* validate verify token needed for setting up web hook */
if (isset($_GET['hub_verify_token'])) {
if ($_GET['hub_verify_token'] === 'YOUR_SECRET_TOKEN') {
echo $_GET['hub_challenge'];
return;
} else {
echo 'Invalid Verify Token';
return;
}
}
So in this case your verify token is YOUR_SECRET_TOKEN, now when you are setting up web hook, Type YOUR_SECRET_TOKEN in the verification token.
I wrote recently a step by step guide with screen shots here.
I want to subscribe to picture object of a specific Facebook page. In order to do that I am following this article. I made uploaded the PHP file that would serve as callback here. Code below:
<?php
/**
* This is sample subscription endpoint for using Facebook real-time update
* See http://developers.facebook.com/docs/api/realtime to additional
* documentation
*/
// Please make sure to REPLACE the value of VERIFY_TOKEN 'abc' with
// your own secret string. This is the value to pass to Facebook
// when add/modify this subscription.
define('VERIFY_TOKEN', 'app_code_123');
$method = $_SERVER['REQUEST_METHOD'];
// In PHP, dots and spaces in query parameter names are converted to
// underscores automatically. So we need to check "hub_mode" instead
// of "hub.mode".
if ($method == 'GET' && $_GET['hub_mode'] == 'subscribe' &&
$_GET['hub_verify_token'] == VERIFY_TOKEN) {
echo $_GET['hub_challenge'];
} else if ($method == 'POST') {
$updates = json_decode(file_get_contents("php://input"), true);
// Replace with your own code here to handle the update
// Note the request must complete within 15 seconds.
// Otherwise Facebook server will consider it a timeout and
// resend the push notification again.
error_log('updates = ' . print_r($updates, true));
}
?>
Then I got my access_token as directed in the article where I replaced client_id with APP_ID and client_secret with APP SECRET from my app details:
https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=<REMOVED APP ID>&client_secret=<REMOVED CLIENT SECRET>
Followed by an attempt to create the subscription:
https://graph.facebook.com/<REMOVED APP ID>/subscriptions?access_token=<REMOVED APP ACCESS TOKEN>object=user&fields=feed&verify_token=app_code_123&method=post&callback_url=http://www.shameemcompany.com/facebook.php
But it fails with the error:
"message": "(#2200) callback verification failed: ",
"type": "OAuthException",
"code": 2200
I want to subscribe to a specific Facebook page so where or how would I specify that?
First you must use HTTP POST method instead of sending "..&method=POST&.."
Second, your server must be reachable from the internet.
And third, your server must be able to process concurrent requests, because facebook sends verification requests simultaneously.