See output of POST from external endpoint / webhook - php

Is there any way in PHP to see the output of a POST from an external source. For example, the POST from a stripe webhook.
$body = #file_get_contents('php://input');
$response = json_decode($body);
\Stripe\Stripe::setApiKey('MyKey');
if(!empty($response)) {
switch($response->type) {
case "customer.created":
echo $response->data->object->email;
exit;
}
}
All what I can get is logs from the web server:
54.XXX.XXX.XXX - - [18/Jun/2020:15:55:06 +0200] "POST /external/webhooks/stripe/endpoint_subscriptions.php HTTP/1.1" 200 31 "-" "Stripe/1.0 (+https://stripe.com/docs/webhooks)"

Related

Mailchimp API is giving HTTP/1.0 302 Moved Temporarily

I have a script which is attempting to pull the Lists from Mailchimp. The URL that is giving this list is:
https://us8.api.mailchimp.com/1.3/?output=php&method=lists&apikey=XXXXXHIDDENKEYXXXXX-us8
By directly visiting the link, the serialized array of lists is displayed. The issues is when I am using PHP to pull this information:
$response = "";
fwrite($sock, $payload);
stream_set_timeout($sock, $this->timeout);
$info = stream_get_meta_data($sock);
while ((!feof($sock)) && (!$info["timed_out"])) {
$response .= fread($sock, $this->chunkSize);
$info = stream_get_meta_data($sock);
}
fclose($sock);
ob_end_clean();
Once I print the $response variable, I get the following output:
HTTP/1.0 302 Moved Temporarily
Server: AkamaiGHost
Content-Length: 0
Location: https://us8.api.mailchimp.com/1.3/?output=php&method=lists&apikey=XXXXXHIDDENKEYXXXXX-us8
Date: Thu, 23 Aug 2018 16:33:55 GMT
Connection: close
Here is a link to the MCAPI library that I am using to get attempt the connection:
https://github.com/jbrooksuk/MCAPI-PHP
Why would this information be available when directly visiting the link but blocked via PHP?

Facebook Messenger API - Can't verify webhook URL (PHP)

I'm trying to set up a fb messenger chatbot but don't seem to be able to get the webhook callback url verified. Every time I try to verify it I get this error message - The URL couldn't be validated. Response does not match challenge, expected value = '1596214014', received=''
Here's the screenshot:
Screenshot
Here's the php I'm using -
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
I've also tried
echo $_GET['hub_challenge'];
and just
echo file_get_contents('php://input');
All of these result in the same error message as above. Basically, as far as I can tell facebook isn't sending a GET request to my server or if it is it doesn't include any data. Can anyone tell if I am doing something wrong or if there is a setting I need to change to ensure facebook is sending the data correctly?
Edit - When checking the access logs this is what I find, which looks like facebook isn't sending any data in the get request.
2a03:2880:1010:dffb:face:b00c:0:8000 - - [19/Apr/2016:20:50:06 +0000] "GET /wp-content/plugins/applications/fbmessenger.php HTTP/1.0" 200 - "-" "facebookplatform/1.0 (+http://developers.facebook.com)
Thanks
just try my code and it's gonna work.
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'Your's app token') {
echo $challenge;
}
//Token of app
$row = "Token";
$input = json_decode(file_get_contents('php://input'), true);
//Receive user
$sender = $input['entry'][0]['messaging'][0]['sender']['id'];
//User's message
$message = $input['entry'][0]['messaging'][0]['message']['text'];
//Where the bot will send message
$url = 'https://graph.facebook.com/v2.6/me/messages?access_token='.$row;
$ch = curl_init($url);
//Answer to the message adds 1
if($message)
{
$jsonData = '{
"recipient":{
"id":"'.$sender.'"
},
"message":{
"text":"'.$message. ' 1' .'"
}
}';
};
$json_enc = $jsonData;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json_enc);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
if(!empty($input['entry'][0]['messaging'][0]['message'])){
$result = curl_exec($ch);
}
you have to return Challenges so Facebook can verify its correct Url and Token Match
<?php
$challenge = $_REQUEST['hub_challenge'];
$verify_token = $_REQUEST['hub_verify_token'];
if ($verify_token === 'token_my_token') {
echo $challenge;
}
Facebook Docs Link ( In Node.js ) You can see challenge return after verifying the token
https://developers.facebook.com/docs/messenger-platform/getting-started/webhook-setup
Could you try my API? https://github.com/Fritak/messenger-platform
If you set it like in example, it should work:
// This is just an example, this method of getting request is not safe!
$stream = file_get_contents("php://input");
$request = empty($stream)? $_REQUEST : $stream;
$bot = new \fritak\MessengerPlatform(
['accessToken' => 'token_for_app',
'webhookToken' => 'my_secret_token',
'facebookApiUrl' => 'https://graph.facebook.com/v2.6/me/' //2.6 is minimum
], $request);
if($bot->checkSubscribe())
{
print $bot->request->getChallenge();
exit;
}
If not, problem is somewhere between Facebook and script, not in PHP itself. Go check apache settings etc.
Well issue might be on facebook side, they had some issues over past few days...
Have only this code in your php file: (fbmessenger.php)
<?php
// header('HTTP/1.1 200 OK');
/* GET ALL VARIABLES GET & POST */
foreach ($_REQUEST AS $key => $value){
$message .= "$key => $value ($_SERVER[REQUEST_METHOD])\n";
}
$input = file_get_contents("php://input");
$array = print_r(json_decode($input, true), true);
file_put_contents('fbmessenger.txt', $message.$array."\nREQUEST_METHOD: $_SERVER[REQUEST_METHOD]\n----- Request Date: ".date("d.m.Y H:i:s")." IP: $_SERVER[REMOTE_ADDR] -----\n\n", FILE_APPEND);
echo $_REQUEST['hub_challenge'];
You will have requests saved in a file called "fbmessenger.txt" in the same directory.
Note that for some strange reason you may need to submit few times to
get it approved & saved! (I had to hit "save" 8-9 times before fb
approved link)
Make sure you use https (SSL) connection and once your connection is done, verify your token with "hub_verify_token" to make sure request is coming from fb.

Does GAE support Plivo?

I've been trying to implement Plivo on my GAE server but I'm getting a 500 error.
I setup Plivo by using Plivo's Github PHP Helper Library. I saved that file as plivo.php on my test server. Then I added plivosend.php with the following code
<?php
if($_POST) {
require_once 'plivo.php';
$auth_id = "auth_id";
$auth_token = "auth_token";
$p = new RestAPI($auth_id, $auth_token);
// make sure all 3 params are valid
if(!empty($_POST['send_to_name']) && !empty($_POST['send_to_number']) && !empty($_POST['sender_name'])) {
$message = 'this message doesn't matter';
$plivo_url = 'https://glacial-harbor-8656.herokuapp.com/report';
// Send message
$params = array(
'src' => '15555555555', // Sender's phone number with country code
'dst' => $_POST['send_to_number'], // Receiver's phone number with country code
'text' => $message, // Your SMS text message
'url' => $plivo_url, // The URL to which with the status of the message is sent
'method' => 'POST' // The method used to call the url
);
// Send message
$response = $p->send_message($params);
// Print the response
$message_uuid = $response['response']['message_uuid'][0];
if(!empty($message_uuid)) {
echo '{"success":1,"message_uuid":' . $message_uuid . '"}';
}
else {
// todo log this?
echo '{"success":0,"error_message":"Message failed to send."}';
}
}
else {
echo '{"success":0,"error_message":"Message failed to send. Incorrect params."}';
}
}
?>
On my test server (just my website), this sends without any problems. When I put both plivo.php and plivosend.php on GAE, I get the following 500 error:
207.58.203.50 - - [21/Sep/2015:09:58:00 -0700] "POST /plivosend.php HTTP/1.1" 500 25 - "appname/1.0.2 (iPhone; iOS 9.0; Scale/2.00)" "appname-xxx.appspot.com" ms=4 cpu_ms=3 cpm_usd=0.000003 instance=00c61b117cd04d3645448a84e24daba9991882e1 app_engine_release=1.9.26
I have no idea why... The details are extremely limited.
Does anyone have a clue? Does GAE not support Plivo?
Google App Engine restricts many functions (necessary in order to be a massively auto-scaling application platform). One restriction is outbound HTTP requests (from your PHP code to external). Read about it here, HTTP Requests and cURL Support for details and options.

Remote file access from PHP server side gives 301 instead of file, what to do?

EDIT: the answer is in the comments to the marked answer.
I am currently working with updating a few key components on a mobile web site. The site uses data from a different server to display student schedules. Recently this other site (over which I have zero control) was subject to a major overhaul and naturally I now have to update the mobile web site.
What I am trying to do is to access an iCal file and parse it. Since the site I am working on runs in an environment that does not have the curl-library nor have fopen wrappers properly set up I have resorted to the method described here (number 4, using a socket directly).
My current issue is that instead of getting the iCal-file I get a 301 error. However, if I attempt to access the same file (via the same URL) in a web browser it works just fine.
EDIT:
I added a bit of logging and here is what came out of it:
-------------
Querying url:
https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics
Response:
HTTP/1.1 301 Moved Permanently
Server: nginx/1.2.8
Date: Sun, 11 Aug 2013 14:08:36 GMT
Content-Type: text/html
Content-Length: 184
Connection: close
Location:
https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.2.8</center>
</body>
</html>
Redirect url found: https://someUrl/schema/ri654Q055ZQZ60QbQ0ygnQ70cWny067Z0109Zx4h0Z7o525Y407Q.ics
The new location I am getting is identical to the original one.
This is the code used:
function getRemoteFile($url)
{
error_log("------------- \r\nQuerying url: " . $url, 3, "error_log.log");
// get the host name and url path
$parsedUrl = parse_url($url);
$host = $parsedUrl['host'];
if (isset($parsedUrl['path'])) {
$path = $parsedUrl['path'];
} else {
// the url is pointing to the host like http://www.mysite.com
$path = '/';
}
if (isset($parsedUrl['query'])) {
$path .= '?' . $parsedUrl['query'];
}
if (isset($parsedUrl['port'])) {
$port = $parsedUrl['port'];
} else {
// most sites use port 80
// but we want port 443 because we are using https
error_log("Using port 443\r\n" . $url, 3, "error_log.log");
$port = 443;
}
$timeout = 10;
$response = '';
// connect to the remote server
$fp = fsockopen($host, $port, $errno, $errstr, $timeout );
if( !$fp ) {
echo "Cannot retrieve $url";
} else {
$payload = "GET $path HTTP/1.0\r\n" .
"Host: $host\r\n" .
"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3\r\n" .
"Accept: */*\r\n" .
"Accept-Language: sv-SE,sv;q=0.8,en-us,en;q=0.3\r\n" .
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" .
"Referer: https://$host\r\n\r\n";
error_log("\nPAYLOAD: " . $payload, 3, "error_log.log");
// send the necessary headers to get the file
fputs($fp, $payload);
// retrieve the response from the remote server
while ( $line = stream_socket_recvfrom( $fp, 4096 ) ) {
$response .= $line;
}
fclose( $fp );
// naively find location redirect
$location_pos = strpos($response, "Location:");
if($location_pos){
$location_pos += 10;
$new_url = substr($response, $location_pos, strpos($response, "\r\n\r\n") - $location_pos);
error_log("\nRedirect url found: " . $new_url, 3, "error_log.log");
}else{
//log the response
error_log($response, 3, "error_log.log");
}
// strip the headers
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos + 4);
}
// return the file content
return $response;
}
HTTP Response Code 301 is a permanent redirect, not an error.
Your code will have to follow that redirect in order to access the resource.
For example, http://google.com/ returns a 301 in order to redirect users to http://www.google.com/ instead.
$ curl -I http://google.com/
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sun, 11 Aug 2013 01:25:34 GMT
Expires: Tue, 10 Sep 2013 01:25:34 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Alternate-Protocol: 80:quic
You can see the 301 response on line 2, followed by the Location header which tells the web browser where to go instead.
What likely happened was that during this major overhaul, they moved the resource to another location. In order not to break any users bookmarks or calendar, they used a 301 redirect so that clients will automatically fetch the resource from the new location.

How to use fsockopen to load a url from an xml sitemap

I am attempting to load each url in a sitemap.xml file in an effort to pre-cache them and speed up the users experience.
I have the following code which grabs the urls from the sitemap
$ch = curl_init();
/**
* Set the URL of the page or file to download.
*/
curl_setopt($ch, CURLOPT_URL, 'http://onlineservices.letterpart.com/sitemap.xml;jsessionid=1j1agloz5ke7l?id=1j1agloz5ke7l');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec ($ch);
curl_close ($ch);
$xml = new SimpleXMLElement($data);
foreach ($xml->url as $url_list) {
$url = $url_list->loc;
echo $url ."<br>";
}
and I am now trying to use fsockopen to load each url in turn.
where $url is in this format: http://onlineservices.letterpart.com:80/content/en/FAMILY-201103311115/Family_FLJONLINE_FLJ_2009_07_4
foreach ($xml->url as $url_list) {
$url = $url_list->loc;
$fp = fsockopen ($url,80);
if ($fp) {
fwrite($fp, "GET / HTTP/1.1\r\nHOST: $url\r\n\r\n");
while (!feof($fp)) {
print fread($fp,256);
}
fclose ($fp);
} else {
print "Fatal error\n";
}
}
But this is giving me this error for each url:
[12-May-2011 13:34:09] PHP Warning: fsockopen() [function.fsockopen]: unable to connect to http://onlineservices.letterpart.com:80/content/en/FAMILY-201103311115/Family_FLJONLINE_FLJ_2009_07_4:-1 (Unable to find the socket transport "http" - did you forget to enable it when you configured PHP?) in /home/digital1/public_html/dev/sitemap.php on line 32
I have read that I need to: "just the hostname, not the URL in the fsockopen call. You'll need to provide the uri, minus the host/port in the actual HTTP headers"
so I tried this:
$fp = fsockopen ("http://onlineservices.letterpart.com",80);
if ($fp) {
fwrite($fp, "GET / HTTP/1.1\r\nHOST: content/en/FAMILY-201103311115/Family_FLJONLINE_FLJ_2009_07_4\r\n\r\n");
while (!feof($fp)) {
print fread($fp,256);
}
fclose ($fp);
} else {
print "Fatal error\n";
}
But I still get the same error.
EDIT:
If I change the fsockopen call to:
$fp = fsockopen ("onlineservices.letterpart.com",80);
then I get a slightly different and better but still wrong response. it seems to be ignoring the onlineservices.letterpart.com section and trying http:///content/ BUT... it has appended: /web/ui.xql?action=html&resource=login.html tot he end of the url which is our login page so it must be seeing our server...
HTTP/1.1 302 Moved Temporarily Date: Thu, 12 May 2011 14:40:02 GMT Server: Jetty/5.1.12 (Windows 2003/5.2 x86 java/1.6.0_07 Expires: Thu, 01 Jan 1970 00:00:00 GMT Set-Cookie: JSESSIONID=nh62zih3q8mf;Path=/ Location: http:///content/en/FAMILY-201103311115/Family_FLJONLINE_FLJ_2009_07_4/web/ui.xql?action=html&resource=login.html Content-Length: 0
Thanks.
fsockopen is not attented to be used for HTTP request,
Curl is a better choice (and much more powerful).
There is also file_get_contents which can make it quick:
foreach ($xml->url as $url_list) {
$url = $url_list->loc;
file_get_contents($url);
}
Usefull for application cache warmup!

Categories