Google Analytics API - Integration With Symfony2 - api

I am trying to gain access to Google Analytics API through OAuth2.
What i did:
Open developers console > APIs and Auth > Credentials
Create a new Client ID
Generate p12 key
Copy the key on the server
Open google analytics page > admin > Account > User Management
Add the email from generated Client ID, something like: xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com
Give to this email Read and Analyze permissions
Then when I go back to developers console > permission. The new email is added on Service accounts with Edit permissions
Recheck if Google Analytics is enabled and data is going in.
Now I had installed widop/google-analytics-bundle and configure the bundle:
widop_google_analytics:
client_id: "xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com"
profile_id: "ga:12345678"
private_key_file: "mykey.p12"
http_adapter: "widop_http_adapter.curl"
And the query I try to create is:
$profileId = 'ga:12345678';
$query = new Query($profileId);
$query->setStartDate(new \DateTime('-2months'));
$query->setEndDate(new \DateTime());
$query->setMetrics(array('ga:visits' ,'ga:bounces'));
$query->setDimensions(array('ga:browser', 'ga:city'));
$query->setSorts(array('ga:country', 'ga:browser'));
$query->setFilters(array('ga:browser=~^Firefox'));
$query->setSegment('gaid::10');
$query->setStartIndex(1);
$query->setMaxResults(10000);
$query->setPrettyPrint(false);
$query->setCallback(null);
$clientId = 'xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com';
$privateKeyFile = 'mykey.p12';
$httpAdapter = new CurlHttpAdapter();
$client = new Client($clientId, $privateKeyFile, $httpAdapter);
$token = $client->getAccessToken();
$service = new Service($client);
$response = $service->query($query);
return $response;
As a response I get this error:
User does not have sufficient permissions for this profile.
When I open developers console > overview > 1 hour (tab)
I had notice that requests are going in.
From all that - I assume that authentication and query is OK but the user has no permissions to get any kind of data which is weird because I had granted Read and Analyze permissions to
xxxxxxxx-xxxxxxxxxxxxxxx#developer.gserviceaccount.com
What could by the reason for that exception?

I do not know if you already solved this issue.
The solution for me was use the view ID instead of account ID on the analytics account.
The view ID is on the third column in settings, on Google Analytics administration panel.
Sorry for my english.

Related

AAD Authentication with Azure Data Explorer (Kusto) not working for simple query via API

I'm attempting to access Kusto via the API with Python (a "headless" script, in other words), and would like to use an AAD application for authentication. I'm specifically working with the sample code on https://github.com/Azure/azure-kusto-python/blob/master/azure-kusto-data/tests/sample.py, which attempts to query the Samples > StormEvents table on the cluster https://help.kusto.windows.net. I can run the query in the Kusto explorer just fine, but I'm getting "Caller is not authorized to perform this action" when trying to run the sample code.
I followed the instructions on https://kusto.azurewebsites.net/docs/management/access-control/aad.html and https://kusto.azurewebsites.net/docs/management/access-control/how-to-provision-aad-app.html to create an AAD application on the Azure portal and add API permissions for Azure Data Explorer. In the code, I have the "Application (client) ID" from the portal in the client_id field, and the appropriate secret in the client_secret field. The authority_id field is set to 72f988bf-86f1-41af-91ab-2d7cd011db47, which is what's shown on the portal as well as the table on https://kusto.azurewebsites.net/docs/management/access-control/aad.html#authenticating-with-aad-programmatically The app name (and client ID) is accepted on https://www.analytics.msftcloudes.com/support/directory just fine.
The code is thus as follows (omitting the imports and the specific secrets):
cluster = "https://help.kusto.windows.net"
client_id = "<omitted>"
client_secret = "<omitted>"
authority_id = "72f988bf-86f1-41af-91ab-2d7cd011db47"
kcsb = KustoConnectionStringBuilder.with_aad_application_key_authentication(
cluster, client_id, client_secret, authority_id
)
client = KustoClient(kcsb)
db = "Samples"
query = "StormEvents | take 10"
response = client.execute(db, query)
The failure output is:
azure.kusto.data.exceptions.KustoServiceError: (KustoServiceError(...), [{'error': {'code': 'Forbidden', 'message': 'Caller is not authorized to perform this action', '#type': 'Kusto.DataNode.Exceptions.UnauthorizedDatabaseAccessException', '#message': "Principal 'AAD app id=(omitted)' is not authorized to access database 'Samples'.", '#context': {'timestamp': '2019-06-05T19:39:17.3493255Z', 'serviceAlias': 'HELP', 'machineName': 'KEngine000000', 'processName': 'Kusto.WinSvc.Svc', 'processId': 18832, 'threadId': 25568, 'appDomainName': 'Kusto.WinSvc.Svc.exe', 'clientRequestd': 'KPC.execute;9ede2b2d-5fba-478c-ad8f-8306284cf6e9', 'activityId': 'efdb96c9-da46-4d5f-b739-54661e7002e3', 'subActivityId': '33f89e2b-2347-447a-abe9-81e586d0e2a0', 'activityType': 'DN-FE-ExecuteQuery', 'parentActivityId': '438b2bb3-26fb-4f7e-813d-bc8a5c39ce1c', 'activityStack': '(Activity stack: CRID=KPC.execute;9ede2b2d-5fba-478c-ad8f-8306284cf6e9 ARID=efdb96c9-da46-4d5f-b739-54661e7002e3 > KD-Query-Client-ExecuteQueryAsKustoDataStream/5ddd9239-e742-4edc-ab3e-55d59a1f2c99 > P-WCF-Service-ExecuteQueryInternalAsKustoDataStream--IClientServiceCommunicationContract/438b2bb3-26fb-4f7e-813d-bc8a5c39ce1c > DN-FE-ExecuteQuery/33f89e2b-2347-447a-abe9-81e586d0e2a0)'}, '#permanent': True}}])
I've also added the sample cluster in Kusto Explorer, like the docs say.
Am I still missing something?
https://help.kusto.windows.net is the URL of an ADX cluster which is an exploratory aid, and only allows interactive access by AAD users (not AAD applications).
for running automation using AAD application authentication, you should redirect your code at your own cluster/database, on which you grant your AAD application the necessary permissions (database user/viewer)

Twitter Ads API error: INSUFFICIENT_USER_AUTHORIZED_PERMISSION. How to solve it?

I am trying to perform a request to the twitter Ads API in my dev environment. I am already registered to get access to this service.
I have received a confirmation e-mail like this:
Your application (ID:12345678) has been approved for the Twitter Ads API program and your organization has been granted a Developer license for Read/Write access. ...
This is why I suppose to have my APP ready to query the Ads API.
Besides that I have information about the APP (tokens and secrets) in the page https://developer.twitter.com/en/apps but I can't find any reference to the account_id, mentioned in the official documentation.
Advertising accounts are registered on ads.twitter.com and identified
in the API by account_id. Advertising accounts link directly to funding
sources and leverage content from one or more Twitter user accounts as
‘promotable users’. Each advertising account can grant permission to
one or more Twitter user accounts. The advertising account, or “current
account,” is represented in nearly every URL executed as an in-line
:account_id parameter.
Following this post I have create the follow code in oder to get access to the Twitter Ads API:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
The previous code is working (I am not querying Ads API. But the next one ( querying the Ads Api) is not working:
$url = 'https://ads-api.twitter.com/5/accounts';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->buildOauth($url, $requestMethod)->performRequest();
dd($data);
{"errors":[{"code":"INSUFFICIENT_USER_AUTHORIZED_PERMISSION","message":"User 2222222222 is not authorized to make this request. Please have them reauthorize with your client application APPNAme."}],"request":{"params":{}}}
What am I missing?
I have found a solution. I don't know if this is the only one but it works.
We must instal Twurl. Twurl is a curl-like application, tailored specifically for the Twitter API.
Install twurl in your system. $ sudo gem install twurl
Set authorization to twurl acceess your twitter APP. $ twurl authorize --consumer-key xxxxx --consumer-secret xxxxx
That is the output for the prevoius command: Go to https://api.twitter.com/oauth/authorize?oauth_consumer_key=xxxx&oauth_nonce=ffff&oauth_signature=bbb&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1556889574&oauth_token=ddd&oauth_version=1.0 and paste in the supplied PIN
Open the browser copy and paste the provided URL https://api. .... version=1.0
You will be redirected to a page asking to confirm the authorization. Confirm it.
You will receive a message: 'You've granted access to APP_Name! Next, return to APP_Name and enter this PIN to complete the authorization process. PIN = 09010101'.
Just copy the PIN number and paste back in the terminal and hit enter.
You will get a message in the terminal Authorization successful.
Go to yor APP_Name page https://developer.twitter.com/en/apps/123456 and go to Keys and tokens section. You need to regenerate the Access token & access token secret. Hit the button 'regenerate'
Once it is regenerate you can get access to the api trough twurl in your terminal: $ twurl -H "ads-api.twitter.com" "/5/accounts". Please note that today (May-2019) I am using number 5 in "/5/accounts". You must to check your version at your date.
Now you can get access to the Twitter Ads API trough curl in php also.
Create a class TwitterAPIExchangeService (I am in Laravel 5.8). You can get the class in this post.
Use the follow code with your keys:
$settings = array(
'oauth_access_token' => env('TWITTER_ACCESS_TOKEN'),
'oauth_access_token_secret' => env('TWITTER_ACCESS_TOKEN_SECRET'),
'consumer_key' => env('TWITTER_CONSUMER_KEY'),
'consumer_secret' => env('TWITTER_CONSUMER_SECRET'),
);
//Regular Twitter API
$url = 'https://api.twitter.com/1.1/followers/ids.json';
$getfield = '?screen_name=J7mbo';
//Ads Twitter API
//$url = 'https://ads-api.twitter.com/5/accounts';
//$getfield = '';
$requestMethod = 'GET';
$twitter = new TwitterAPIExchangeService($settings);
$data = $twitter->setGetfield($getfield)
->buildOauth($url, $requestMethod)
->performRequest();
dd($data);
Need to regenerate keys and tokens. after that its work for me

How do you obtain a WeChat access_token certificate from api.wechat.com?

This site tries to explain the process: http://admin.wechat.com/wiki/index.php?title=Access_token
The problem is nowhere do they tell you where to get the AppID or what exactly the secret is.Has anyone else succeeded in communicating with WeChat?
Essentially we # WeChat have 2 types of accounts, subscription and service. Subscription account only gives you access to the Message API which allows for receiving messages and autoresponses and allows you to broadcast to your users once a day. Subscription accounts are also grouped in a category in your contacts under subscription.
A service account gives you an APP ID and APP SECRET which allows you to generate an access token which is needed for pretty much all the other API's apart from the Message API. A service account displays in the user's contact list under the main chats in between all your other normal contacts. You can only broadcast to each of your users once a month on a service account.
If you have a service account you will get the APP ID and APP SECRET from admin.wechat.com -> login -> function -> advanced -> developer mode -> Just under your token you will see the APP ID and APP SECRET
To see what type of account you have go to admin.wechat.com -> login and then look at the top right of the screen next to your account name you will see your account name and just above that it will either say subscription account or service account.
If you want to test all the API's I recommend going to the developer sandbox environment where you get full access to all the API's: How does link with href for Line and Wechat?
Please note your number needs to be in the international format so 072 111 2233 you have to enter as +27721112233
Login http://admin.wechat.com
[advanced] --> [Developer Mode], you will got your Appid & AppSecret.
You don't have a wechat OA account?
Join [WeChat Space] https://plus.google.com/communities/102783597675617808511
You may go to http://dev.wechat.com/ to sign up for a developer account.
After you sign up, you will get your App ID and AppKey via your signup email.
Then, you can go to http://admin.wechat.com/wiki/index.php?title=Main_Page to obtain more information.
I wrote a code snippet on github that explains the entire process. The code is for django but can be used with any python framework
here is a snippet
import xml.etree.ElementTree as ET
from wechat.views import WeChatView
MyCustomView(WeChatView):
token = "ad4sf65weG7Db6ddWE"
on_message(self, message):
root = ET.fromstring(message)
from = root[1].text
message_type = root[3].text
content = root[4].text
print('from: {}'.format(from))
print('message type: {}'.format(message_type))
print('content: {}'.format(content))
The full code is here https://github.com/tawanda/django-wechat
Here's my code,maybe you can try it.
//Getting access_token from customize menus
static function get_access_token($appid,$secret){
$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
$json=http_request_json($url);//here cannot use file_get_contents
$data=json_decode($json,true);
if($data['access_token']){
return $data['access_token'];
}else{
return "Error occurred while geting the access_token";
}
}
//Though URL request is https',cannot use file_get_contents.Using CURL while asking the JSON data
function http_request_json($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}

How to get useID/Email of logged in user in Google Contacts API after OauTh Token

I developed a program which works well and I can import data from gmail but. I want to keep track how is the user given permission to manage contacts. But after a hard search I did not get any Idea about the loged in user. My code is as follows.
============================================
var parameters = new OAuth2Parameters
{
ClientId = ConfigurationManager.AppSettings["ClientID"].ToString(),
ClientSecret = ConfigurationManager.AppSettings["ClientSecret"].ToString(),
RedirectUri = ConfigurationManager.AppSettings["RedirectURL"].ToString(),
Scope ="https://www.googleapis.com/auth/userinfo.profile"
};
parameters.AccessCode = Request.QueryString["Code"].ToString();
OAuthUtil.GetAccessToken(parameters);
Session["Token"] = parameters.AccessToken;
==================================
But I dont how to get email of logged in user. Please let me that
Thanks in advance
Request an additionall scope of https://www.googleapis.com/auth/userinfo.email and then you can access the user info as well. There is also a userinfo.profile witch contains other info on the user like name, profile picture, language and so on.
Your code looks like C# but I only have a Python example of using multiple scopes and sharing tokens.
Code: https://code.google.com/p/google-api-oauth-demo/
Article: http://www.hackviking.com/2013/10/python-get-user-info-after-oauth/

Using Twitter API on shared server - Rate limit exceeded even though I am caching the response

I have written a php script which gets the latest status update for 12 different twitter accounts by pulling an xml for each and caching it on my server. This currently runs every 30 minutes.
Unfortunately I keep getting the "Rate limit exceeded. Clients may not make more than 150 requests per hour." error event though i'm only making 24 requests from the 150 I should have.
I assume this is because my domain is on a shared server and twitter is counting other requests against me.
How can I authorise my requests so i'm not restriced by the standard IP limit?
I have no experience of OAuth so need step by step instructions if possible.
Thanks in advance!
OK so I managed to get the most of this working with no previous experience of API's etc.
Here is my step by step guide:
Step 1.
Create a Twitter list.
Go to: https://twitter.com/username/lists
Click "Create list"
Enter details and save.
Go to a twitter user you wish to add to the list and click the gear dropdown and select "Add or remove from lists". Tick the checkbox next to your list.
Step 2.
Create a Twitter App via: https://dev.twitter.com/apps/new
Log in using your Twitter credentials.
Give your app a name, description etc.
Go to the Settings tab and change the Access type to Read and Write then click "Update this Twitter application's settings".
Click "Create my access token" at the bottom of the page.
You will now have a Consumer Key, Consumer secret, Access token and Access token secret. Make a note of these.
Step 3. Create API tokens.
Download and install onto your server the Abraham Twitter oAuth library from: https://github.com/abraham/twitteroauth (I'll use a folder called "twitter").
Create a new file, name it authorise.php in the oAuth folder and put the following code inside (with your generated keys in place of the named text). (Put the code between < ? PHP and ?> brackets).
// Create our twitter API object
require_once("twitteroauth/twitteroauth.php");
$oauth = new TwitterOAuth('Put-Consumer-Key-here', 'Put-Consumer-secret-here',
'Put-Access-Token-here', 'Put-Access-token-secret-here');
// Send an API request to verify credentials
$credentials = $oauth->get("account/verify_credentials");
echo "Connected as #" . $credentials->screen_name;
// Post our new "hello world" status
$oauth->post('statuses/update', array('status' => "hello world"));
This has now authorised your twitter App for the API and posted a "hello world" status on your twitter account.
Note: The Read / Write access change we did earlier alowed the code to post the status update, it's not actually needed to pull the list from the API but I did it to make sure it was working OK. (You can turn this off again by going back to the Settings).
Step 4.
Create PHP file to pull your list and cache the file.
Create an XML file (YOUR-FILE-NAME.xml) and save it in the oAuth folder.
Create a PHP file (YOUR-PHP-FILE.php) and save it in the oAuth folder
Edit the below code with your twitter API keys, file name and twitter list details and save it in your PHP file. (Put the code within < ? PHP and ?> brackets).
/* Twitter keys & secrets here */
$consumer_key = 'INSERT HERE';
$consumer_secret = 'INSERT HERE';
$access_token = 'INSERT HERE';
$access_token_secret = 'INSERT HERE';
// Create Twitter API object
require_once('twitteroauth/twitteroauth.php');
// get access token and secret from Twitter
$oauth = new TwitterOAuth($consumer_key, $consumer_secret, $access_token, $access_token_secret);
// fake a user agent to have higher rate limit
$oauth->useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071025 Firefox/2.0.0.9';
// Send an API request to verify credentials
$credentials = $oauth->get('account/verify_credentials');
echo 'Connected as #' . $credentials->screen_name . '\n';
// Show API hits remaining
$remaining = $oauth->get('account/rate_limit_status');
echo "Current API hits remaining: {$remaining->remaining_hits}.\n";
$ch = curl_init();
$file = fopen("YOUR-FILE-NAME.xml", "w+");
curl_setopt($ch, CURLOPT_URL,'https://api.twitter.com/1/lists/statuses.xml?slug=INSERT-LIST-NAME&owner_screen_name=INSERT-YOUR-TWITTER-USERNAME-HERE&include_entities=true');
curl_setopt($ch, CURLOPT_FILE, $file);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_exec($ch);
curl_close($ch);
fclose($file);?>
Copy the file path into your browser and test it. (e.g. http://www.yourwebsite.com/twitter/YOUR-PHP-FILE.php)
This should contact twitter, pull the list as an XMl file and save it into YOUR-FILE-NAME.xml. Test it by opening the XML file, it should have the latest statuses from the users in your twitter list.
Step 5.
Automate the PHP script to run as often as you like (up to 350 times per hour) via a Cron job.
Open your Cpanel and click "Cron jobs" (usually under Advanced).
You can choose the regularity of your script using the common settings.
In the command field add the following code:
php /home/CPANEL-USERNAME/public_html/WEBSITE/twitter/YOUR-PHP-FILE.php >/dev/null 2>&1
Your script will now run as often as you have chosen, pull the list from twitter and save it into YOUR-FILE-NAME.xml.
Step 6.
You can now pull statuses from the cached XML file meaning your visitors will not be making unnecessary calls to the API.
I've not worked out how to target a specific screen_name yet if anyone can help there?
a) don't check 12 different accounts, create a [public] list https://twitter.com/lists and check only the it => 12 times less requests
b) use this awesome oAuth lib: https://github.com/abraham/twitteroauth and use oAuth requests instead of unsigned => you will get 350 requests and they will not be affected by IP limit