Create product using Oauth & curl - magento

Im trying to create product using RESTful Api. Achieved this functionality using RESTCLIENT firefox addon but failed using script. I can able to list products But im not able to create product using script. Getting access denied error. Can anyone help me?
Here is my script.
$url = 'http://magento.com/api/rest/products';
$method = 'POST';
# headers and data (this is API dependent, some uses XML)
$headers = array(
'Accept: application/json',
'Content-Type: application/json',
'oauth_signature_method : HMAC-SHA1',
'oauth_nonce : ilJuravy9KVYm6R',
'oauth_timestamp : 1363848967',
'oauth_consumer_key : xxx',
'oauth_consumer_secret : yyy',
'oauth_token : zzz',
'oauth_token_secret : xyz',
'oauth_signature : 4admodOkAj2pKwhO5Tk6TEjc7Rg%3D',
'oauth_verifier: mrr1350pp0j8hiyv31kzxhko97hyyuwx',
'oauth_version : 1.0',
);
$data = json_encode(
array(
'type_id' => 'simple',
'attribute_set_id' => 4,
'sku' => 'simple' . uniqid(),
'weight' => 1,
'status' => 1,
'visibility' => 4,
'name' => 'Simple Product',
'description' => 'Simple Description',
'short_description' => 'Simple Short Description',
'price' => 99.95,
'tax_class_id' => 0,
)
);
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
switch($method) {
case 'GET':
break;
case 'POST':
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
break;
case 'PUT':
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
break;
case 'DELETE':
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
}
echo $response = curl_exec($handle);
echo $code = curl_getinfo($handle, CURLINFO_HTTP_CODE);

you have to generate 3 things mention below and other things are static like oauth_consumer_key,oauth_token etc.
1.timestmap
2.signature
3.nonce
i have generated all things see below code.
$nonce = substr(md5(uniqid('nonce_', true)),0,16);
$temprealm="http://magentohost/api/rest/products";
$realm=urlencode($temprealm);
$oauth_version="1.0";
$oauth_signature_method="HMAC-SHA1";
$oauth_consumer_key="lro2hnoh3c8luvhcr49j6qgygmyvw7e3";
$oauth_access_token="xbqe4wnu3zv357gimpdnuejvcbtk51ni";
$oauth_method="GET";
$oauth_timestamp=time();
$algo="sha1";
$key="sb88hfdihyg25ipt1by559yzbj2m3861&s7uhaheu8nrx961oxg6uc3os4zgyc2tm"; //consumer secret & token secret //Both are used in generate signature
$data="oauth_consumer_key=".$oauth_consumer_key."&oauth_nonce=".$nonce."&oauth_signature_method=".$oauth_signature_method."&oauth_timestamp=".$oauth_timestamp."&oauth_token=".$oauth_access_token."&oauth_version=".$oauth_version;
$send_data=$oauth_method."&".$realm."&".urlencode($data);
$sign=hash_hmac($algo,$send_data,$key,1); // consumer key and token secrat used here
$fin_sign=base64_encode($sign);
$curl = curl_init();
curl_setopt($curl,CURLOPT_HTTPHEADER,array('Authorization : OAuth realm='.$realm.', oauth_version="1.0", oauth_signature_method="HMAC-SHA1", oauth_nonce="'.$nonce.'", oauth_timestamp="'.$oauth_timestamp.'", oauth_consumer_key='.$oauth_consumer_key.', oauth_token='.$oauth_access_token.', oauth_signature="'.$fin_sign.'"'));
curl_setopt ($curl, CURLOPT_URL,$temprealm);
$xml=curl_exec($curl);

Related

504 timeout error when sending many notifications using laravel +firebase messaging

I m sending notifications to many users at the same time and this is my code:
public function sendNotifications($title,$body,$image){
$SERVER_API_KEY ="my_api_key";
$tokens=DB::select("select * from fcm_token");
$token_array=[];
for( $i =0;$i<count($tokens);$i++){
array_push($token_array,$tokens[$i]->token);
}
$data = [
"registration_ids" =>
$token_array
,
"notification" => [
"title" => $title,
"body" => $body,
"image" => $image,
"sound"=> "default" // required for sound on ios
],
];
$dataString = json_encode($data);
$headers = [
'Authorization: key=' . $SERVER_API_KEY,
'Content-Type: application/json',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $dataString);
$response = curl_exec($ch);
curl_close($ch);
}
this function is executed after a form is filled by the admin who should give the title body and image to the back-end. after that, he must wait for the task to be complete (to make sure that everyone got the notification ). it was working like a charm before but right now after a long loading time, the server responds with 504 timeout. I know that I could have queued but would that solve the problem? wouldn't the Queue be stopped also by the same error? I m hosting the app in shared hosting (lws) and my max execution time is 60 seconds and can't increase it without paying more but I want to be sure where the problem resides.
I tried to test it with just 100 users, and it is working like a charm, but I need to send it to more than that since my users are more than 4000.
Google clound messaging supports sending to 1000 tokens at once.
$tokens=array_chunk($all_tokens,1000);
foreach($tokens as $thousand_tokens){
send_notification($thousand_tokens, $request->title.' Video added', 'New Video added in '.$cat->category->name, $cat->image_url, $data);
}
Above one is sample code. You can use that to modify your code.
function send_notification($tokens, $message, $description, $image, $data)
{
try{
$token_ids = array($tokens);
$apiKey = env('FCM_KEY');
$url = 'https://fcm.googleapis.com/fcm/send';
$msg =
array(
"registration_ids"=> $tokens,
"collapseKey"=> "com.notification",
"data"=> $data,
"notification"=> array(
"android"=> array(
"channelId"=> "Notifications-Channel",
"imageUrl"=> $image,
"sound"=> "sample.mp3"
),
"sound"=> "sample.mp3",
"channelId"=> "Notifications-Channel",
"android_channel_id"=> "Notifications-Channel",
"body"=> $description,
"title"=> $message
)
);
define("GOOGLE_API_KEY", $apiKey);
$headers = array(
'Authorization: key='.$apiKey,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($msg));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}catch(Exception $e){
return 'at exception '.$e->getLine();
die('Error: '.$e->getMessage());
}
}

Laravel SaveJson to Database

I am new to Json and API I need your help in understanding this error. I wish to save JSON Data in a database table (MpesaStkPush), all I get is an error.
I have tried changing from json_encode to json_decode.
laravel.log
[2021-02-12 19:13:41] local.ERROR: Symfony\Component\HttpFoundation\Response::setContent(): Argument #1 ($content) must be of type ?string, stdClass given
MpesaController
public function stkPush(Request $request){
$amount = $request->totalAmount;
$url ='https://sandbox.safaricom.co.ke/mpesa/stkpush/v1/processrequest';
$curl_post_data =[
'BusinessShortCode' => 174379,
'Password' => $this->lipaNaMpesaPassword(),
'Timestamp'=>Carbon::rawParse('now')->format('YmdHms'),
'TransactionType'=> 'CustomerPayBillOnline',
//'Amount' => $amount,
'Amount' => '1',
'PartyA' =>'254710909198',
'PartyB' =>174379,
'PhoneNumber'=>'254710909198',
'CallBackURL'=> 'https://375e0eb81d88.ngrok.io/api/stk/push/callback/url',
'AccountReference'=>"Wabe Digital Agency",
'TransactionDesc'=> "Lipa Na Mpesa"
];
$data_string =json_encode($curl_post_data);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:Bearer '.$this->newAccessToken()));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
$curl_response = curl_exec($curl);
return json_encode($curl_response);
}
public function mpesaRes(Request $request){
$response =json_decode($request->getContent());
if (property_exists($response, property: 'Body') && $response->Body->stkCallback->ResultCode =='0'){
$merchant_request_id=$response->Body->stkCallback->MerchantRequestID;
$checkout_request_id=$response->Body->stkCallback->CheckoutRequestID;
$trn = new MpesaStkPush;
$trn =MpesaStkPush::where('merchant_request_id', $merchant_request_id)->where('checkout_request_id', $checkout_request_id)->first();
$data=[
'result_desc'=> $response->Body->stkCallback->ResultDesc,
'result_code'=> $response->Body->stkCallback->ResultCode,
'merchant_request_id' => $merchant_request_id,
'checkout_request_id' => $checkout_request_id,
'amount' => $response->Body->stkCallback->CallbackMetadata[0]->Value,
'mpesa_receipt_number'=> $response->Body->stkCallback->CallbackMetadata[1]->Value,
//'b2c_utility_account_available_funds',
'transaction_date' => $response->Body->stkCallback->CallbackMetadata[2]->Value,
'phone_number'=> $response->Body->stkCallback->CallbackMetadata[3]->Value,
];
$trn->fill($data)->save();
. K
Pay more attention to the logs. In your case it points that you've mismatched with types (put a class instance instead of the string)
Anyway, I advise you to read the following php function documentation:
https://www.php.net/manual/en/function.json-decode.php
The second argument is a trick: if it's set to true, you'll get an array instead of stdClass instance.
Overmore, request instance has more eloquent methods.

Nativescript - Onesignal rest Api

I have push notifications on my app with onesignal sdk, but i´m having dificulty understanding how could i send with a large icon, i mean the one that stays on the left when the user receives the push(instead of showing a bell)...i know the icon must be transparent and have 256px x 256px. I´m sending the push using the rest api, but i don´t know where the problem is because nothing seems to work, here is my code:
public function sendMessage($messagePush){
$subtitle=["en" => $messagePush['message']];
$content = array(
"en" => $messagePush['contentJson']['tipoImovel'],
"large_icon" => public_path('img/icon.png')
);
$hashes_array = array();
array_push($hashes_array, array(
"id" => "id1",
"text" => "Ver"
));
$fields = array(
'app_id' => "myappid",
'included_segments' => array(
'All'
),
'data' => array(
"imovel" => $messagePush['contentJson']
),
'headings'=> $subtitle,
'contents' => $content,
'buttons' => $hashes_array
);
$fields = json_encode($fields);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://onesignal.com/api/v1/notifications");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'Authorization: my autorization'
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$resp = curl_exec($ch);
curl_close($ch);
return $resp;
}
I can receive the push, but the icon never appears, and there´s also another problem...the push always appear on the top tray instead of the popup "kind", for that manner below is also my code that is on my app.js:
if (application.android) {
application.on(application.launchEvent, (args) => {
try {
TnsOneSignal.startInit(application.android.context).setNotificationOpenedHandler(new TnsOneSignal.NotificationOpenedHandler({
// notificationOpened: function (result: com.onesignal.OSNotificationOpenResult) {
notificationOpened: function (result) {
const imovelAndroid = JSON.parse(result.stringify()).notification.payload.additionalData;
handleOpenURL(imovelAndroid);
}
})).init();
TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification);
TnsOneSignal.startInit(application.android.context).init();
}
catch (error) {
console.error('error', error);
}
});
}
If i remove the TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification); the popup style appears, but the buttons don´t navegate to my handleOpenURL function...but if i let it stay, it does navigate but the push is always on the tray.
Any tips? thanks for your time.
Regards
You will have to remove TnsOneSignal.setInFocusDisplaying(TnsOneSignal.OSInFocusDisplayOption.Notification); as that would force the notification to be the tray one. Default one is InAppAlert already.
You were resetting setNotificationOpenedHandler on second call to startInit. So if you remove the second startInit statement too you should be good.

Using the Google Search Console API to test if a site is mobile friendly is failing with 400 errors

I want to check if a website is "mobile friendly" using the google api to access their own testing service.
I am using curl via PHP to talk to the https://searchconsole.googleapis.com/v1/urlTestingTools/mobileFriendlyTest:run end point. Ref google api docs here.
However the returned data from my code is always a 400 error page.
What I do know is that my API key is valid. If I run the command via the curl utility in a linux shell it works (ref the example given in the google documentation).
Has anyone seen this before ? It must be something to do with my php code and how I've implemented curl in it...
$ch = curl_init();
$curlConfig = array(
CURLOPT_URL => "https://searchconsole.googleapis.com/v1/urlTestingTools/mobileFriendlyTest:run?key=xxxx",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-Type:application/json'),
CURLOPT_POSTFIELDS => json_encode(array(
'url' => 'https://www.test.com'
))
);
curl_setopt_array($ch, $curlConfig);
$result = curl_exec($ch);
curl_close($ch);
echo $result;
So with the help of someone outside of SO I got an answer to this which was basically to setup to rewrite the code slightly differently. I can't work out what exactly is the sticking point but it works if formatted as follows...
$data="http://www.yourdomain.com/";
$url="https://searchconsole.googleapis.com/v1/urlTestingTools/mobileFriendlyTest:run?key=xxxxx";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
$payload = json_encode( array( "url"=> $data ) );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$api_content = curl_exec ($ch);
curl_close ($ch);
$api_result = json_decode($api_content);
var_dump($api_result);

Start point for google analytics and webmaster api

I have about 50 websites in my google analytics account.
I want to do some research, create notification system and compare analytics data with data from other sources.
That means I want to get a dozen of reports for every site twice a day. I parse them and store in mysql. What's the simplest way do do that?
I registered an application and turned on analytics api in it, but there's no webmaster api. Also I have not a clear understanding of oAuth. Is there a way without redirecting and requesting new access token every time? That's something like granting permanent access for my application in my account from my ip without further confirmations.
So, is there a good tutorial for the beginner about retrieving data from analytics and webmaster written in php, perl or ruby?
Following code will help you to retrieve "refresh token" using offline access of oauth flow.
you can use this refresh token to get an access token without bothering user.
Make sure that the Redirect Uri that you have mentioned in your API console should be same as the filename in which you will place the following code.
For eg.
If the redirect uri is:-http://test.com/google_oauth.php
then following script should be placed in :- google_oauth.php (path:http://test.com/google_oauth.php)
<?php
$OAuth = array(
'oauth_uri' => 'https://accounts.google.com/o/oauth2/auth',
'client_id' => '#clientId',
'client_secret' => '#clientSecret',
'access_type' => 'offline',
'redirect_uri' => 'http://test.com/google_oauth.php', //this url should be same as you had registered in your api console as redirect uri()
'oauth_token_uri' => 'https://accounts.google.com/o/oauth2/token'
);
$token = array(
'access_token' => '',
'token_type' => '',
'expires_in' => '',
'refresh_token' => ''
);
$title = 'No Code';
$AuthCode = 'Null';
// see if error parameter exisits
$error = _get_url_param($_SERVER['REQUEST_URI'], 'error');
if ($error != NULL)
{ // this means the user denied api access to GWMTs
$title = $error;
}
else
{ // does the code parameter exist?
$AuthCode = _get_url_param($_SERVER['REQUEST_URI'], 'code');
if ($AuthCode == NULL)
{ // get authorization code
$OAuth_request = _formatOAuthReq($OAuth, "https://www.googleapis.com/auth/analytics.readonly");
header('Location: ' . $OAuth_request);
exit; // the redirect will come back to this page and $code will have a value
}
else
{
$title = 'Got Authorization Code';
// now exchange Authorization code for access token and refresh token
$token_response = _get_auth_token($OAuth, $AuthCode);
$json_obj = json_decode($token_response);
$token['access_token'] = $json_obj->access_token;
$token['token_type'] = $json_obj->token_type;
$token['expires_in'] = $json_obj->expires_in;
$token['refresh_token'] = $json_obj->refresh_token;
echo 'access_token = ' . $json_obj->access_token;
}
}
function _get_auth_token($params, $code)
{
$url = $params['oauth_token_uri'];
$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'redirect_uri' => $params['redirect_uri'],
'grant_type' => 'authorization_code'
);
$response = _do_post($url, $fields);
return $response;
}
function _do_post($url, $fields)
{
$fields_string = '';
foreach ($fields as $key => $value)
{
$fields_string .= $key . '=' . $value . '&';
}
$fields_string = rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
function _formatOAuthReq($OAuthParams, $scope)
{
$uri = $OAuthParams['oauth_uri'];
$uri .= "?client_id=" . $OAuthParams['client_id'];
$uri .= "&redirect_uri=" . $OAuthParams['redirect_uri'];
$uri .= "&scope=" . $scope;
$uri .= "&response_type=code";
$uri .= "&access_type=offline";
return $uri;
}
function _get_url_param($url, $name)
{
parse_str(parse_url($url, PHP_URL_QUERY), $params);
return isset($params[$name]) ? $params[$name] : null;
}
function _get_refresh_token($params, $code)
{
$url = $params['oauth_token_uri'];
$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'refresh_token' => $token['refresh_token'],
'grant_type' => 'refresh_token'
);
$response = _do_post($url, $fields);
return $response;
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title><?= $title; ?></title>
</head>
<body>
<h1>OAuth2 Authorization Code</h1>
<p>Authorization Code: <?= $AuthCode; ?></p>
<p>access token: <?= $token['access_token']; ?></p>
<p>expires in: <?= $token['expires_in']; ?></p>
<p>refresh token: <?= $token['refresh_token']; ?></p>
<p></p>
</body>
</html>
Once you get your refresh token you can use following code to get data from google analytics:-
<?php
$refresh_token='#refresh-token';
$fields_string = "client_id=#ClientId&client_secret=#clientSecret&refresh_token=$refresh_token&grant_type=refresh_token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://accounts.google.com/o/oauth2/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
$token_response = curl_exec($ch);
$json_obj = json_decode($token_response);
$access_token = $json_obj->access_token;
curl_close($ch);
$url = "https://www.googleapis.com/analytics/v3/data/ga?ids=ga:30566906&start-date=2013-01-01&end-date=2013-04-16&dimensions=ga:medium&metrics=ga:visits,ga:bounces";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer $access_token"));
curl_setopt($ch, CURLOPT_URL, html_entity_decode($url));
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
$json_obj = json_decode($output);
$test=$json_obj->columnHeaders;
foreach($test as $a){
var_dump($a);
}
curl_close($ch);
?>
In above scripts:-
#clientId and #clientSecret should be replaced by the client id and client secret that you have received while registering your web application.
For your use case I would suggest using a Google Service Account rather than the OAuth flow that requires human confirmation.
There are Client Libraries available for several languages that can make the OAuth part simpler. For example, in the ruby library includes a sample script showing how to use a service account with Google Analytics API. Essentially it's this:
#client = Google::APIClient.new(
:application_name => opts['application_name'],
:application_version => opts['application_version'])
## Load our credentials for the service account
key = Google::APIClient::KeyUtils.load_from_pkcs12(key_file, key_secret)
#client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => 'https://www.googleapis.com/auth/analytics.readonly',
:issuer => service_account_email,
:signing_key => key)
## Request a token for our service account
#client.authorization.fetch_access_token!
query_data = #client.execute(:api_method => #analytics.data.ga.get, :parameters => {
'ids' => "ga:" + #profileID,
'start-date' => #startDate,
'end-date' => #endDate,
'dimensions' => dimension,
'metrics' => metric,
'sort' => sort
})
There is a Webmaster API available although it does not have access to the query data. You can get that through this Google-published python script or through a similar one in PHP with more data.

Resources