Bing Ads api - invalid credentials error - php

So, our BingAds reporting program, which has been running for many months, is suddenly plagued with 105 (InvalidCredentials) errors. The access token had expired, so I requested a new one, which succeeds, giving me a new access token that expires in the future.
$accessTokenExchangeUrl = "https://login.live.com/oauth20_token.srf";
$accessTokenExchangeParams = array();
$accessTokenExchangeParams['client_id'] = $this->client_id();
$accessTokenExchangeParams['client_secret'] = $this->client_secret();
$accessTokenExchangeParams['grant_type'] = 'refresh_token';
$accessTokenExchangeParams['refresh_token'] = $code;
// Create an HTTP client and execute an HTTP POST request to
// exchange the authorization token for an access token and
// refresh token.
$httpClient = new HttpClient();
$responseJson = $httpClient->postData( $accessTokenExchangeUrl, $accessTokenExchangeParams);
// The response formatted in json
$responseArray = json_decode($responseJson, TRUE);
// If the response contains an access_token element, it was successful.
// If not, an error occurred - throw an exception
if (isset($responseArray['access_token']))
{
return $responseArray;
}
But then using that new token results in a 105 error:
$proxy = \BingAds\Proxy\ClientProxy::ConstructWithCredentials($wsdl, $bingUserName,
$bingPasswd,
$developer_token,
$access_token);
$report = new KeywordPerformanceReportRequest();
$report->Format = ReportFormat::Tsv;
$report->ReportName = 'Keyword Performance Report';
$report->ReturnOnlyCompleteData = false;
<report definition>
$encodedReport = new SoapVar($report, SOAP_ENC_OBJECT, 'KeywordPerformanceReportRequest', $proxy->GetNamespace());
$this->bingReportRequestID = $this->_BingSubmitGenerateReport( $proxy, $encodedReport );
$request = new SubmitGenerateReportRequest();
$request->ReportRequest = $report;
$retval = $proxy->GetService()->SubmitGenerateReport($request)->ReportRequestId;
::> throws a SoapFault
Any ideas? Like I said, it was working fine for months, now suddenly, nothing.

Apparently you are using a refresh_token to authenticate. With the new token you got, you need to generate you new refresh_token and use that one instead.

Related

Getting the acess token from Guzzle Oauth authentication

I'm currently trying to develop a connection to the Reddit api through Oauth using Guzzle. I get to the point where I authenticate in Reddit, then I get to the authorization token, but I can't take the access token from the Guzzle response so I can set it as a cookie and using on subsequent requests. My current code looks like this:
public function __construct(){
if(isset($_COOKIE['reddit_token'])){
$token_info = explode(":", $_COOKIE['reddit_token']);
$this->token_type = $token_info[0];
$this->access_token = $token_info[1];
} else {
if (isset($_GET['code'])){
//capture code from auth
$code = $_GET["code"];
//construct POST object for access token fetch request
$postvals = sprintf("code=%s&redirect_uri=%s&grant_type=authorization_code",
$code,
redditConfig::$ENDPOINT_OAUTH_REDIRECT);
//get JSON access token object (with refresh_token parameter)
$token = self::runCurl(redditConfig::$ENDPOINT_OAUTH_TOKEN, $postvals, null, true);
//store token and type
if (isset($token->access_token)){
$this->access_token = $token->access_token;
$this->token_type = $token->token_type;
//set token cookie for later use
$cookie_time = 60 * 59 + time(); //seconds * minutes = 59 minutes (token expires in 1hr)
setcookie('reddit_token', "{$this->token_type}:{$this->access_token}", $cookie_time);
}
} else {
$state = rand();
$urlAuth = sprintf("%s?response_type=code&client_id=%s&redirect_uri=%s&scope=%s&state=%s",
redditConfig::$ENDPOINT_OAUTH_AUTHORIZE,
redditConfig::$CLIENT_ID,
redditConfig::$ENDPOINT_OAUTH_REDIRECT,
redditConfig::$SCOPES,
$state);
//forward user to PayPal auth page
header("Location: $urlAuth");
}
}
This is my authentication flow. The I have the runCurl method that is going to make the guzzle requests:
private function runCurl($url, $postVals = null, $headers = null, $auth = false){
$options = array(
'timeout' => 10,
'verify' => false,
'headers' => ['User-Agent' => 'testing/1.0']
);
$requestType = 'GET';
if ($postVals != null){
$options['body'] = $postVals;
$requestType = "POST";
}
if ($this->auth_mode == 'oauth'){
$options['headers'] = [
'User-Agent' => 'testing/1.0',
'Authorization' => "{$this->token_type} {$this->access_token}"];
}
if ($auth){
$options['auth'] = [redditConfig::$CLIENT_ID, redditConfig::$CLIENT_SECRET];
}
$client = new \GuzzleHttp\Client();
$response = $client->request($requestType, $url, $options);
$body = $response->getBody();
return $body;
}
The problem resides here, the getBody() method returns a stream, and if I use getBody()->getContents() I get a string, none of which can help me.
Any idea on how can I get the access token so I can finish the authentication process?
To answer the question itself - you just need to cast $body to string. It should be a json, so you will also need to json_decode it to use it as an object in the code above. So instead of return $body; in your runCurl, you need to do:
return json_decode((string)$body);
I would recommend to use the official client tho. The code in the question has some unrelated issues, which will make it costy to maintain.

Quickbooks Online Error PHP

When I attempt to connect to QBO via the Consolibyte package I downloaded I get an error.
Error Code: internal_error
Message: Error getting application from request token
You can contact us for further assistance. Error
Id:ixnkryec2iu513ef45f3f5xv-12940655
I have set up the config.php file as directed in the instructions and even got to the point of authorizing the application with Quickbooks but now when I navigate to the page it indicates that I am not logged in and when I click the "Connect to QuickBooks" button on the index.php page I get the error above. I'm not familiar enough with the process to know where to start troubleshooting this problem and any help would be greatly appreciated.
Link: http://production.technology-architects.com/unleashed_new/quickbook/docs/partner_platform/example_app_ipp_v3/
example_app_ipp_v3/config.php code
require_once dirname(__FILE__) . '/../../../QuickBooks.php';
$token = 'f5ddd229b1d19b4153b8218b08b97897050f';
$oauth_consumer_key = 'qyprdYvvyNLq1om6FSw0xLebctZEAz';
$oauth_consumer_secret = 'KCLYZRgZ4LnHUB35AzvylxnH6c8CDCyjhva8I9Gp';
$sandbox = true; // When you're using development tokens
$quickbooks_oauth_url = 'http://production.technology-architects.com/unleashed_new/quickbook/docs/partner_platform/example_app_ipp_v3/oauth.php';
$quickbooks_success_url = 'http://production.technology-architects.com/unleashed_new/quickbook/docs/partner_platform/example_app_ipp_v3/success.php';
$quickbooks_menu_url = 'http://production.technology-architects.com/unleashed_new/quickbook/docs/partner_platform/example_app_ipp_v3/menu.php';
$dsn = 'mysqli://myusername:mypassword#localhost/databasename';
$encryption_key = 'bcde1234';
$the_username = 'DO_NOT_CHANGE_MEddd';
$the_tenant = 'sdfaswrqwerqwr';
if (!QuickBooks_Utilities::initialized($dsn)){
QuickBooks_Utilities::initialize($dsn);
}
$IntuitAnywhere = new QuickBooks_IPP_IntuitAnywhere($dsn, $encryption_key, $oauth_consumer_key, $oauth_consumer_secret, $quickbooks_oauth_url, $quickbooks_success_url);
if ($IntuitAnywhere->check($the_username, $the_tenant) and $IntuitAnywhere->test($the_username, $the_tenant)){
$quickbooks_is_connected = true;
$IPP = new QuickBooks_IPP($dsn);
$creds = $IntuitAnywhere->load($the_username, $the_tenant);
$IPP->authMode(
QuickBooks_IPP::AUTHMODE_OAUTH,
$the_username,
$creds);
if ($sandbox){
$IPP->sandbox(true);
}
$realm = $creds['qb_realm'];
$Context = $IPP->context();
$CompanyInfoService = new QuickBooks_IPP_Service_CompanyInfo();
$quickbooks_CompanyInfo = $CompanyInfoService->get($Context, $realm);
} else {
$quickbooks_is_connected = false;
}
None of the tokens or OAuth credentials you have in your code match what you have in the screenshot.
Fix your tokens and OAuth values.
$token = 'f5ddd229b1d19b4153b8218b08b97897050f';
$oauth_consumer_key = 'qyprdYvvyNLq1om6FSw0xLebctZEAz';
$oauth_consumer_secret = 'KCLYZRgZ4LnHUB35AzvylxnH6c8CDCyjhva8I9Gp';

PHP-EWS "Soap client returned status of 404"

So, I'm using php-ews library to connect to my Microsoft Office 365 Exchange Email account to read emails. I've connected successfully to it and I have managed to retrieve a list of emails that I need.
Now the problem is that I cannot get message body. Reading documentation about Exchange Web Services it says that body cannot be fetched with FindItem(), only with GetItem(), and that's okay.
Now the problem I'm seeing is following:
I tried all possible examples I could find about this, and the code doesn't have any errors, it just says "Soap client returned status of 404".
If anyone has any idea where to look for the solution, please tell me.
EDIT:
$ews = new Client('outlook.office365.com/EWS/OData/Me/Inbox/Messages', '###', '###', ClientEWS::VERSION_2010_SP2);
$request = new FindItemType();
$request->ItemShape = new ItemResponseShapeType();
$request->ItemShape->BaseShape = DefaultShapeNamesType::DEFAULT_PROPERTIES;
$request->ItemShape->BodyType = BodyTypeResponseType::BEST;
$request->Traversal = ItemQueryTraversalType::SHALLOW;
$request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId = new DistinguishedFolderIdType();
$request->ParentFolderIds->DistinguishedFolderId->Id = DistinguishedFolderIdNameType::INBOX;
// sort order
$request->SortOrder = new NonEmptyArrayOfFieldOrdersType();
$request->SortOrder->FieldOrder = array();
$order = new FieldOrderType();
// sorts mails so that oldest appear first
// more field uri definitions can be found from types.xsd (look for UnindexedFieldURIType)
$order->FieldURI = new PathToUnindexedFieldType();
$order->FieldURI->FieldURI = 'item:DateTimeReceived';
$order->Order = 'Ascending';
$request->SortOrder->FieldOrder[] = $order;
try{
//getting list of all emails - works perfectly
$result = $ews->FindItem($request);
if ($result->ResponseMessages->FindItemResponseMessage->ResponseCode == 'NoError' && $result->ResponseMessages->FindItemResponseMessage->ResponseClass == 'Success') {
$count = $result->ResponseMessages->FindItemResponseMessage->RootFolder->TotalItemsInView;
$request = new GetItemType();
$request->ItemShape = new ItemResponseShapeType();
$request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES;
for ($i = 0; $i < $count; $i++){
$message_id = $result->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message[$i]->ItemId->Id;
$messageItem = new ItemIdType();
$messageItem->Id = $message_id;
$request->ItemIds->ItemId[] = $messageItem;
}
// Here is your response
// It throws an error here with the message "Soap client returned status of 404"
$response = $ews->GetItem($request);
print_r($response);
}
//print_r($result);
} catch(\Exception $e) {
echo $e->getMessage();
}
It looks like your trying to use the new REST endpoint for Office365
'outlook.office365.com/EWS/OData/Me/Inbox/Messages'
But your trying to make and EWS SOAP Request, the endpoint you should be using for EWS SOAP is
https://outlook.office365.com/EWS/Exchange.asmx
You might want to consider using the new REST interface as an alternative to EWS/SOAP but you then need to use a REST library.ouauth etc as per https://dev.outlook.com/restapi.
I'd suggest you use a newer version of this library that's maintained much more and has more features (In this case, it support OAuth logins for Office 365), garethp/php-ews. When using it, you can either use the endpoint provided by Glen Scales, or just use outlook.office365.com.

got a 401 when I get access token for LinkedIn

$oauth->getAccessToken() causes Invalid auth/bad request (got a 401, expected HTTP/1.1 20X or a redirect).
How do I look at the request headers to figure out what exactly is wrong?
$oauth = new OAuth(CONSUMER_KEY, CONSUMER_SECRET);
$oauth->disableSSLChecks();
$request_token_response = $oauth->getRequestToken('https://api.linkedin.com/uas/oauth/requestToken');
if($request_token_response === FALSE) {
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse());
} else {
$request_token = $request_token_response;
var_dump($request_token);
if (!isset($_GET['oauth_verifier'])) {
$this->redirect("https://api.linkedin.com/uas/oauth/authorize?oauth_token=" . $request_token['oauth_token']);
} else {
$oauth_verifier = $_GET['oauth_verifier'];
$oauth->setToken($request_token['oauth_token'], $request_token['oauth_token_secret']);
$access_token_url = 'https://api.linkedin.com/uas/oauth/accessToken';
$access_token_response = $oauth->getAccessToken($access_token_url, "", $oauth_verifier);
if($access_token_response === FALSE) {
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse());
} else {
$access_token = $access_token_response;
$params = array();
$headers = array();
$method = OAUTH_HTTP_METHOD_GET;
// Specify LinkedIn API endpoint to retrieve your own profile
$url = "http://api.linkedin.com/v1/people/~";
// By default, the LinkedIn API responses are in XML format. If you prefer JSON, simply specify the format in your call
// $url = "http://api.linkedin.com/v1/people/~?format=json";
// Make call to LinkedIn to retrieve your own profile
$oauth->fetch($url, $params, $method, $headers);
echo $oauth->getLastResponse();
}
}
}
}
oauth_verifier only verifies the request_token from which it was obtained. I needed to store the original request_token in session instead of getting a new request_token on callback.

How do I get the access_token from tumblr's official php client?

I've followed the directions posted in this stackoverflow question, but I am stuck.
I am using tumblr/tumblr.php from Github (the official "PHP client for the tumblr API").
I am also following directions here (which are actually for twitter), but those directions aren't tailored for the git library I am using.
I have a valid consumer key and secret.
From those I make a request and get oauth_token and oauth_token_secret like so:
$client = new Tumblr\API\Client($consumerKey,$consumerSecret);
$client->getRequestHandler()->setBaseUrl('https://www.tumblr.com/');
$req = $client->getRequestHandler()->request('POST', 'oauth/request_token', [
'oauth_callback' => '...',
]);
// Get the result
$result = $req->body->__toString();
print_r( $result );
Which gives me:
oauth_token=2C6f...MqSF&oauth_token_secret=HaGh...IJLi&oauth_callback_confirmed=true
Then I send the user to the http://www.tumblr.com/oauth/authorize?oauth_token=2C6f...MqSF, so they can allow access for the app. This redirects to: ...?oauth_token=2C6f...MqSF&oauth_verifier=nvjl...GtEa#_=_
And now in the final step I believe I am supposed to convert my request token to an access token. Is that right? I am doing something wrong:
$client = new Tumblr\API\Client($consumerKey,$consumerSecret);
$client->getRequestHandler()->setBaseUrl('https://www.tumblr.com/');
$req = $client->getRequestHandler()->request('POST', 'oauth/access_token', [
'oauth_token' => '2C6f...MqSF',
'oauth_verifier' => 'nvjl...GtEa'
]);
// Get the result
$result = $req->body->__toString();
print_r( $result );
because I get responses like this one:
oauth_signature [AqbbYs0XSZ7plqB0V3UQ6O6SCVI=] does not match expected value [0XwhYMWswlRWgcr6WeA7/RrwrhA=]
What is wrong with my last step?
I am not sure if I should even be sending oauth_verifier with the request. Is #_=_ supposed to be part of oauth_verifier? I wouldn't think so. I get signature errors for all the variations Ive tried.
Without the token and tokenSecret I can't make certain calls to the API. I get unauthorized 403 responses. Same when I use the token and token_secret from the second step. I'm pretty sure I need a new token/secret pair.
You're pretty close, you just are passing the oauth_token incorrectly in the last step, and skipping out on oauth_token_secret altogeter.
I've compiled this working code (which you can also now find posted on the Wiki at https://github.com/tumblr/tumblr.php/wiki/Authentication):
<?php
require_once('vendor/autoload.php');
// some variables that will be pretttty useful
$consumerKey = '<your consumer key>';
$consumerSecret = 'your consumer secret>';
$client = new Tumblr\API\Client($consumerKey, $consumerSecret);
$requestHandler = $client->getRequestHandler();
$requestHandler->setBaseUrl('https://www.tumblr.com/');
// start the old gal up
$resp = $requestHandler->request('POST', 'oauth/request_token', array());
// get the oauth_token
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// tell the user where to go
echo 'https://www.tumblr.com/oauth/authorize?oauth_token=' . $data['oauth_token'];
$client->setToken($data['oauth_token'], $data['oauth_token_secret']);
// get the verifier
echo "\noauth_verifier: ";
$handle = fopen('php://stdin', 'r');
$line = fgets($handle);
// exchange the verifier for the keys
$verifier = trim($line);
$resp = $requestHandler->request('POST', 'oauth/access_token', array('oauth_verifier' => $verifier));
$out = $result = $resp->body;
$data = array();
parse_str($out, $data);
// and print out our new keys
$token = $data['oauth_token'];
$secret = $data['oauth_token_secret'];
echo "\ntoken: " . $token . "\nsecret: " . $secret;
// and prove we're in the money
$client = new Tumblr\API\Client($consumerKey, $consumerSecret, $token, $secret);
$info = $client->getUserInfo();
echo "\ncongrats " . $info->user->name . "!\n";

Categories