How to get reports from Commision Junction API - PHP - php

Commision Junction is the name of an affiliate company. I am not familiar with SOAP, WSDL and with web services in general, but wanted to quickly test the data coming back from their affiliate api. Cannot make it work though. They provide a page for their API
I tried smtg like:
public function testCJApi() {
$url = "http://" . $this->user . ":" . $this->password . "#datatransfer.cj.com/datatransfer/files/" . $this->account . "/outgoing/commission_report.csv";
$xml = simplexml_load_file($url);
if (isset($xml)) {
return ($xml
? $this->formatJsonReturn($xml, array("txt"=>"CJ Results OK","code"=>""))
: $this->formatJsonReturn("", array("txt"=>"CJ Results Empty","code"=>""))
);
}
}
but it didn't give me any results. I just need to quickly test the data coming back.
The API link they provide is
http://api.affiliatewindow.com/v4/MerchantService?wsdl.

I have figured it out myself:
public function testCJApi() {
$uri = "https://commission-detail.api.cj.com/v3/commissions?date-type=posting&start-date=2013-02-15&end-date=2013-02-17"; // can be other api uri, this is one of them
$context = stream_context_create(
array(
'http' => array(
'method' => 'GET',
'header' => 'Authorization: ' . 'YOUR API KEY GOES HERE'
)
)
);
$x = file_get_contents($uri, false, $context);
$response = new SimpleXMLElement($x);
return $response->asXML();
}

Related

How to use twitter API v2 in wordpress php? // I can't get the oauth 1 auth headers right on the request and get error "Not Authenticated"

TLDR: Trying to post a tweet everytime someone posts on wordpress but can't authenticate correctly with oauth 1 to use the /2/tweets endpoint.
So I was annoyed when Jetpack social on my site decided to start charging for tweet scheduling. Usually I would be fine with this but it just seemed dumb that they were charging for something that I could build in a few days. So I'm planning on making an open source plugin that let's anyone use their wordpress as a tweet scheduler.
I'm currently struggling to properly authenticate with oauth to use the api v2. There's a lot of content out there for v1 but far less for v2 and particuarly v2 with wordpress.
Here's the resources I've used:
-https://www.youtube.com/watch?v=jOlJ5VJ_kSw for the oauth code
-https://developer.wordpress.org/reference/functions/wp_remote_post/ for the wp_remote_post() api call
-Numerous stack articles ie Wordpress twitter api 1.1 search class
which provides a good solution for 1.1 but I have made the possibly
false assumption based on what I've seen that 1.1 is now deprecated
-https://developer.twitter.com/en/docs/authentication/oauth-1-0a/creating-a-signature
shows you how to make a signature for a 1.1 endpoint to post a tweet.
I believe the problem is with the parameters I pass in for oauth, I used all that params from the above twitter docs article but that was 1.1 so possibly an issue.
Here's my code:
function focus_tweet_getSignature($endpoint, $method, $params, $focus_tweet_api_key_secret, $focus_tweet_access_token_secret)
{
uksort($params, 'strcmp');
foreach ($params as $key => $value) {
$params[$key] = rawurlencode($key) . '=' . rawurlencode($value);
}
$signatureBase = array(
rawurlencode($method),
rawurlencode($endpoint),
rawurlencode(implode('&', $params)),
);
$signatureBaseString = implode('&', $signatureBase);
$signatureKey = array(
rawurlencode($focus_tweet_api_key_secret),
rawurlencode($focus_tweet_access_token_secret),
);
$signatureKeyString = implode('&', $signatureKey);
return base64_encode(hash_hmac('sha1', $signatureBaseString, $signatureKeyString, true));
}
// 'oauth_consumer_key',
// 'oauth_nonce',
// 'oauth_signature',
// 'oauth_signature_method',
// 'oauth_timestamp',
// 'oauth_token',
// 'oauth_version',
// 'status'
function focus_tweet_getAuthorizationString($oauth)
{
$authorizationString = 'Authorization OAuth:';
$count = 0;
foreach ($oauth as $key => $value) {
$authorizationString .= !$count ? ' ' : ', ';
$authorizationString .= rawurlencode($key) . '="' . rawurlencode($value) . '"';
$count++;
}
return $authorizationString;
}
function focus_tweet_makeApiCall( $apiParams, $focus_tweet_status ){
$response = wp_remote_post($apiParams['endpoint'], array(
'method' => $apiParams['method'],
'headers' => array(
array(
'Accept: application/json',
$apiParams['authorization'],
'Expect:'
),
),
'body' => "{
'text': $focus_tweet_status
}",
)
);
//If response is not 200, trigger fatal error
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) != 200) {
//Combine response details and build auth header function
$focus_tweet_res_body = wp_remote_retrieve_body($response);
wp_die($apiParams['authorization'] . '&' . $focus_tweet_res_body);
} else {
wp_die("Tweeted!");
}
}
function focus_tweet_tweet($focus_tweet_status)
{
$focus_tweet_api_key = '';
$focus_tweet_api_key_secret = '';
$focus_tweet_access_token = '';
$focus_tweet_access_token_secret = '';
$oauth = array(
'oauth_consumer_key' => $focus_tweet_api_key,
'oauth_nonce' => md5(microtime() . mt_rand()),
'oauth_signature_method' => 'HMAC-SHA1',
'oauth_token' => $focus_tweet_access_token,
'oauth_timestamp' => time(),
'oauth_version' => '1.0',
'status' => $focus_tweet_status,
);
$oauth['oauth_signature'] = focus_tweet_getSignature('https://api.twitter.com/2/tweets', 'POST', $oauth, $focus_tweet_api_key_secret, $focus_tweet_access_token_secret);
$apiParams = array(
'method' => 'POST',
'endpoint' => 'https://api.twitter.com/2/tweets',
'authorization' => focus_tweet_getAuthorizationString($oauth),
'url_params' => array(),
);
focus_tweet_makeApiCall($apiParams, $focus_tweet_status);
}
Triggered when I save a post for now while I'm testing.
Warning: Array to string conversion in C:\Users\Will\Local Sites\plugintestbench\app\public\wp-includes\class-requests.php on line 800
Authorization OAuth: oauth_consumer_key="", oauth_nonce="", oauth_signature_method="HMAC-SHA1", oauth_token="", oauth_timestamp="1672918493", oauth_version="1.0", status="Hello%20World%21", oauth_signature=""&{ "title": "Unauthorized", "type": "about:blank", "status": 401, "detail": "Unauthorized" }
The warning I believe is fine for now although will fix later.
I have used the credentials to post a tweet from postman so that's not the issue.
I initially believed that it was not possible to use curl in wordpress so may try switching to that although I really believe that the issue is with the oauth params.
(Including twitter/flickr api calls on every page load (WordPress))
Will keep this post updated while I work on this and will ofcourse post the finished github code once it's completed.

How to use Twitter API pagination for getting user tweets

I am fetching tweets of a user. I need to show all tweets with ajax pagination. How can I achieve that?
https://api.twitter.com/1.1/statuses/user_timeline.json
Tried
I am using the above link. I heard about max_id, since_id but do not know how to use that. I have tried with max_id and since_id, then the collection is repeating. I am not getting any cursor response.
my code
$api_key = urlencode('*********'); // Consumer Key (API Key)
$api_secret = urlencode('***********'); // Consumer Secret (API Secret)
$auth_url = 'https://api.twitter.com/oauth2/token';
// what we want?
$data_username = '********'; // username
$data_count = 1; // number of tweets
$data_url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
// get api access token
$api_credentials = base64_encode($api_key . ':' . $api_secret);
$auth_headers = 'Authorization: Basic ' . $api_credentials . "\r\n" .
'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' . "\r\n";
$auth_context = stream_context_create(
array(
'http' => array(
'header' => $auth_headers,
'method' => 'POST',
'content' => http_build_query(array('grant_type' => 'client_credentials',)),
)
)
);
$auth_response = json_decode(file_get_contents($auth_url, 0, $auth_context), true);
$auth_token = $auth_response['access_token'];
// get tweets
$data_context = stream_context_create(array('http' => array('header' => 'Authorization: Bearer ' . $auth_token . "\r\n",)));
$datas = json_decode(file_get_contents($data_url . '?include_rts=true&count=' . $data_count . '&screen_name=' . urlencode($data_username), 0, $data_context), true);
// result - do what you want
print('<pre>');
print_r($datas);
Question
What values i have to pass for getting pagination url?
Thank you.
The Twitter API response should include a next_token variable which can be used for subsequent API calls / Pagination.
See https://developer.twitter.com/en/docs/twitter-api/pagination for more information on the topic (this refers to v2, as v1.1 is deprecated by now)

Google Admin SDK: You are not authorized to access this API

Since the Google Login Auth is disabled since last week I'm trying to get oAuth 2.0 working with a service account. We want to give users on our internal web application the oppurtunity to set there Out of Office.
I downloaded the lastest Google APIs Client Library for PHP. In the Google Developer Console, I have created a new project for my application and created a Service account credentials. I have also enabled the API service: Admin SDK in the Developer Console.
I have granted the account user ID access to the correct scopes (I think):
When I use the service-account.php example and change the details, I recieve an JSON with an access token, but when I do an CURL request (same as before) to get the e-mail settings from a user, the error "You are not authorized to access this API." occur.
My code:
<?php
include_once "templates/base.php";
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
$client_id = '124331845-DELETEDPART-hbh89pbgl20citf6ko.apps.googleusercontent.com'; //Client ID
$service_account_name = '124331845-DELETEDPART-89pbgl20citf6ko#developer.gserviceaccount.com'; //Email Address
$key_file_location = 'globaltext-4ce09b20cb73.p12'; //key.p12
$client = new Google_Client();
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://apps-apis.google.com/a/feeds/emailsettings/2.0/'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$aOutput = json_decode($client->getAccessToken());
$strEmailAdresSplit = explode('#', "FIRSTNAME.LASTNAME#DOMAIN.EXTENSION");
$strDomein = $strEmailAdresSplit[1];
$strAlias = $strEmailAdresSplit[0];
$resConnectionJobs = curl_init();
$aHeader = array();
$aHeader[] = 'Authorization: Bearer '.$aOutput->access_token;
$aHeader[] = 'Content-Type: application/atom+xml';
curl_setopt($resConnectionJobs, CURLOPT_URL, "https://apps-apis.google.com/a/feeds/emailsettings/2.0/DOMAIN.EXTENSION/FIRSTNAME.LASTNAME/vacation");
curl_setopt($resConnectionJobs, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($resConnectionJobs, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($resConnectionJobs, CURLOPT_RETURNTRANSFER, true);
curl_setopt($resConnectionJobs, CURLOPT_HEADER, false);
$oCurlData = curl_exec($resConnectionJobs);
curl_close($resConnectionJobs);
echo $oCurlData;
?>
Are you certain your credentials are OK?
Please try the following procedure to make sure you have the right credentials.
Creating your API keys
Go to the developer's console and follow these steps:
Select your project
Choose menu item "APIs & auth"
Choose menu item "Registered app"
Register an app of type "web application"
Choose one of the following options, depending on what kind of app you're creating. Server side languages should use this option :
Key for server apps (with IP locking)
Getting access token & refresh token
Create a file that contains the following code :
<?php
if (isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://accounts.google.com/o/oauth2/token';
$params = array(
"code" => $code,
"client_id" => YOUR_CLIENT_ID,
"client_secret" => YOUR_CLIENT_SECRET,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"grant_type" => "authorization_code"
);
$ch = curl_init();
curl_setopt($ch, constant("CURLOPT_" . 'URL'), $url);
curl_setopt($ch, constant("CURLOPT_" . 'POST'), true);
curl_setopt($ch, constant("CURLOPT_" . 'POSTFIELDS'), $params);
$output = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] === 200) {
header('Content-Type: ' . $info['content_type']);
return $output;
} else {
return 'An error happened';
}
} else {
$url = "https://accounts.google.com/o/oauth2/auth";
$params = array(
"response_type" => "code",
"client_id" => YOUR_CLIENT_ID,
"redirect_uri" => 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"],
"scope" => "https://www.googleapis.com/auth/plus.me"
);
$request_to = $url . '?' . http_build_query($params);
header("Location: " . $request_to);
}
Now, replace YOUR_CLIENT_ID and YOUR_CLIENT_SECRET with your client ID and client secret.
Make sure your scope is correct. For example, it should be https://www.googleapis.com/auth/analytics if you want to get access to Analytics.
If you run the file, you should get an OAuth2 approval screen.
If you now press Accept, you should get a result that looks like this:
{
"access_token" : YOUR_ACCESS_TOKEN,
"token_type" : "Bearer",
"expires_in" : 3600,
"refresh_token" : YOUR_REFRESH_TOKEN
}
The result may contain additional fields, depending on which scope you're applying for.
Connecting with Google's systems in background
Once you get the above to work, your application needs to implement the following workflow:
1) Check if your input contains a GET parameter named "code". If "code" is present, get a new access token and repeat this step (refresh your page)
If "code" is not present, go to step 2.
2) Check if you have credentials stored for your service. If credentials are present, check if your access token has expired or will expire soon. Then go to step 3. If credentials are not present, go to the auth path of your service to get the auth code and go back to step 1 (make sure Google redirects to your current URL).
3) If refresh is needed, refresh your page and go back to step 1.
If refresh is not needed, you're ready to actually do what you wanted to do in the first place.
Google's PHP library takes care if the oAuth2 flow for you, however. If you're using their library, each of the steps in the 3-step process are taken care of by the library and you should just be able to do whatever you want to do with Google's services straight away. I use this strategy myself in my Google Adwords dashboard.
You can, however, just write your custom library and connect with the service directly. Herebelow is some dev code from a project I wrote a few months ago. While it doesn't work out of the box (since it's a controller that's part of a larger application), it should help you understand the flow that Google's library takes care of under the hood.
namespace Application;
class Controller_API_Google_Youtube extends Controller_API {
public function read() {
$scope = "https://www.googleapis.com/auth/youtube";
$this->doOauth($scope);
}
function doOauth($scope) {
$oauth2Credentials = JSON_File::load(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json');
$paths = array(
'token' => 'https://accounts.google.com/o/oauth2/token',
'auth' => "https://accounts.google.com/o/oauth2/auth"
);
$refreshtime = 300;
if (isset($_GET['code'])) {
// Get access code
$query = $_GET;
unset($query['code']);
if (count($query) > 0) {
$query = '?' . http_build_query($query);
} else {
$query = '';
}
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
'code' => $_GET['code'],
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"redirect_uri" => HTTP_PROTOCOL . URL_PATH . $query,
"grant_type" => "authorization_code"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($content);
$oauth2Credentials[$scope] = array();
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
$oauth2Credentials[$scope]['refresh_token'] = $output['refresh_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
header("Location: " . HTTP_PROTOCOL . URL_PATH . $query);
} else {
echo "Something went wrong";
}
} elseif (!isset($oauth2Credentials[$scope])) {
// Get auth code
header("Location: " . $paths['auth'] . '?' . http_build_query(
array(
"response_type" => "code",
"client_id" => $oauth2Credentials['client_id'],
"redirect_uri" => HTTP_PROTOCOL . DOMAIN_PATH,
"scope" => $scope
)
));
} elseif ($oauth2Credentials[$scope]['expires'] - $refreshtime < time()) {
// Refresh access code
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'url' => $paths['token'],
'returntransfer' => 1,
'post' => true,
'postfields' => array(
"client_id" => $oauth2Credentials['client_id'],
"client_secret" => $oauth2Credentials['client_secret'],
"refresh_token" => $oauth2Credentials[$scope]['refresh_token'],
"grant_type" => "refresh_token"
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$info = $response['maps']->getInfo();
$content = $response['maps']->getContent();
if ($info['http_code'] === 200) {
$output = JSON::decode($response['maps']->getContent());
$oauth2Credentials[$scope]['expires'] = time() + $output['expires_in'];
$oauth2Credentials[$scope]['access_token'] = $output['access_token'];
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'Config.json', JSON::encode($oauth2Credentials));
$this->read();
} else {
$this->output = array("error" => "Something went wrong");
}
} else {
$this->doSomethinguseful($oauth2Credentials, $scope);
}
return $this;
}
function doSomethinguseful($oauth2Credentials, $scope) {
// https://developers.google.com/youtube/v3/sample_requests?hl=nl
$client = \PowerTools\HTTP_Client::factory(
array(
'maps' => array(
'useragent' => 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13',
'url' => 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails&mine=true',
'returntransfer' => true,
'httpheader' => array(
'Authorization: Bearer ' . $oauth2Credentials[$scope]['access_token'],
'Accept-Encoding: gzip, deflate'
)
)
)
)->execute();
$responses = $client->getResponses();
$response = array_pop($responses);
$content = $response['maps']->getContent();
$this->output = JSON::decode(gzdecode($content));
}
}
It looks like you may be running into a problem I had as well.
The call to Google_Auth_AssertionCredentials actually requires more parameters than you're sending to work with a service account. (At least, it did in my case.)
You need to pass enough parameters to include sub (which user to take actions on account of).
Without that, I always got an access denied. This clearly isn't obvious, since there's even been a function added to the php library, loadServiceAccountJson, which is supposed to set up a service account client connection, but breaks because it doesn't set sub either.
See working code here: Google php client library loadServiceAccountJson broken - fix enclosed

Linkedin api oauth2.0 get user profile details

As per the new oauth 2.0 for linkedin.
I am unable to get user profile details.
I have set the attributes in my app but still cant get the details.
Can somebody help me the code snippet to get user details.
public function fetch($method, $resource, $body = '') {
$opts = array(
'http' => array(
'method' => $method,
'header' => "Authorization: Bearer " .
$_SESSION['oauth_access_token'] . "\r\n" .
"x-li-format: json\r\n"
)
);
$url = 'api.linkedin.com' . $resource;
if (count($this->$params)) {
$url .= '?' . http_build_query($this->$params);
}
$context = stream_context_create($opts);
$response = file_get_contents($url, false, $context);
return json_decode($response);
}
$xml_response = $LinkedInn->fetch("GET","/v1/people/~");
Please check your permissions in your code when you are logging in with linked-in.
Look at this link-
https://developer.linkedin.com/support/developer-program-transition

Google Tracks API "Bad Request" using PHP

I am using Google Tracks API to build a simple web based program to track a vehicle that has a tracking device sending latitude and longitude coordinates.
I am using PHP and the OAuth2 PHP library to make an authorized connection.
After authorizing and getting an access token I am making a request to create entities. Though I can't seem to get this working and keep getting a "400 Bad Request" response. Following all the steps shown in the documentation.
Here is my code:
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$parsedAuth['access_token'];
$data = array('entities' => array( "name"=> "Chevrolet" ));
$json_data = json_encode($data);
$data_length = http_build_query($data);
$options = array(
'http' => array(
'header' => "Content-type: application/json\r\n". "Content-Length: " . strlen($data_length) . "\r\n",
'method' => 'POST',
'content' => $json_data
),
);
$context = stream_context_create($options);
$response = file_get_contents($url, false, $context);
var_dump($response);
Exact Error is: "failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request"
Why am I getting a bad request? What would be a good request that will register these entities and return id's?
Thank you
The answer given here is wrong. The documentation states that it must be a POST see here My issue was not with the Auth but with the Tracks API itself. I ended up moving to create the request with CURL and it works just fine.
Please. This is PHP with CURL. It works 100%.
//Google maps tracks connection
//Get Files From PHP Library
require_once 'google-api-php-client/src/Google/autoload.php';
require_once 'google-api-php-client/src/Google/Service/MapsEngine.php';
//Set Client Credentials
$client_id = '*************.apps.googleusercontent.com'; //Client ID
$service_account_name = '************#developer.gserviceaccount.com'; //Email Address
$client_email = '*************#developer.gserviceaccount.com';
$private_key = file_get_contents('************.p12');
$scopes = array('https://www.googleapis.com/auth/tracks');
//Create Client
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
//Send Credentials
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key
);
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($credentials);
}
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$client->setAssertionCredentials($credentials);
$_SESSION['service_token'] = $client->getAccessToken();
foreach ($_SESSION as $key=> $value) {
$vars = json_decode($value);
}
$parsedAuth = (array) $vars;
$token = $parsedAuth['access_token'];
//all functions in the program use this auth token- It should be global for easy accesses.
global $token;
function createEntities(){
global $token;
$url = 'https://www.googleapis.com/tracks/v1/entities/create/?access_token='.$token;
//FIX ME: fields is temporarily hard coded- should be brought from DB
$fields = array(
'entities' => array(
'name' => "DemoTruck",
'type' => "AUTOMOBILE"
),
);
//json string the data for the POST
$query_string = '';
foreach($fields as $key => $array) {
$query_string .= '{"' . urlencode($key).'":[{';
foreach($array as $k => $v) {
$query_string .= '"' . urlencode($k) . '":"' . urlencode($v) . '",';
}
}
$str = rtrim($query_string , ',');
$fstr = $str.'}]}';
$length = strlen( $fstr );
//open connection
$ch = curl_init();
//test connection
if (FALSE === $ch)
throw new Exception('failed to initialize');
//set options
$header = array('Content-type: application/json');
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fstr);
$result = curl_exec($ch);
//dump in case of error
if (FALSE === $result){
var_dump( curl_error($ch) );
var_dump( curl_getinfo($ch) );
}
//close connection
curl_close($ch);
}

Categories