Main Idea
I am working on a project and I need to use Google Analytics server side. I do not need to retrieve information, but I need to send information. I could eventually send js script client side, but in this scenario it is not an option.
Most of the following links are really old. 2012~
Retrieving - Not what I need
I have read multiple StackOverflow posts, but they only mention ways to retrieve information.
PHP API for Google Analytics(SO)
Sending - What I need
There is this one post talking about sending information but the GitHub has been deprecated for that library.
Google Analytics PHP API Redirect URI (SO)
Google api php client(GOOGLE)
Question
How do I send information to my Google Analytics account in PHP? Thanks
Be very careful...
Google is able to retrive lot of user informations regarding user-agent, location, ip, campaign, language and so on, using cookies and browser features.
All commands are usually sent using a client-side js script because of that.
If you want to work in server-side you have to handle all the necessary information you need to collect in your statistics before to send the HIT.
For example, if you don't handle UUID properly, google will consider every HIT as "new visitor". If you want to know the geo location of users and your server is in Ireland, every hit made by user will be considered made by an Irish guy. Every ip will be the same of your server, and so on.
I made a custom library using php that consider all these problems.
Basically you can use curl:
function SendGoogleEvent($userid,$category,$action, $label='',$eventvalue=0,$campaign_name='direct',$campaign_source='organic',$campaign_medium='organic'){
$strCookie='';
foreach ($_COOKIE as $key => $value) {
$strCookie.=$key.'='.$value.'; ';
}
$fields_string='';
$fields = array (
'v' => 1,
'tid' => "YOUR GA ID",
'cid' => $userid,
'uip' => $_SERVER['REMOTE_ADDR'],
'dh' => "your site address",
'ul' => 'it-it', // In this case i dont care the user language
't' => 'event',
'ec' => urlencode($category),
'ea' => urlencode($action),
'el' => urlencode($label),
'ev' => $eventvalue
);
if ($campaign_name!='direct') {
$fields["cn"]=$campaign_name;
}
if ($campaign_source!='organic') {
$fields["cs"]=$campaign_source;
}
if ($campaign_medium!='organic') {
$fields["cm"]=$campaign_medium;
}
if (!(substr($_SERVER['HTTP_REFERER'], 0, strlen("your site url")) === "your site url")&&$campaign_name=='direct') {
$fields["dr"]=$_SERVER['HTTP_REFERER'];
}
foreach($fields as $key=>$value) {
$fields_string .= $key.'='.$value.'&';
}
rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, utf8_encode($fields_string));
curl_setopt($ch,CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_URL,"https://ssl.google-analytics.com/collect");
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt( $ch, CURLOPT_COOKIE, $strCookie );
curl_exec( $ch );
curl_close($ch);
You send data via the Measurement Protocol. No special library or dev kit is required, you simply append parameters to the GA endpoint and send them via Curl/fopen/sockets/whatever to Google Analytics.
Each calls includes at least the ID of the account you want to send data to, a client id that allows to group interactions into sessions (so it should be unique per visitor, but it must not identify a user personally), an interaction type (pageview, event, timing etc., some interactions types require additional parameters) and the version of the protocol you are using (at the moment there is only one version).
So the most basic example to record a pageview would look like this:
www.google-analytics.com/collect/v=1&tid=UA-XXXXY&cid=555&t=pageview&dp=%2Fmypage
Related
I came across this problem with a friend's website. It's a Wordpress installation with several plugins. One of those plugins is used to update several images (gathering them from remote locations and storing them locally to save bandwidth). But when running the plugin, the website seemingly refused to display the updated images and continuously gave me the old version which were definetly no longer present on the server.
Browser cache was ruled out quickly as the cause. Wordpress can be a bit tricky, so I checked all other plugins, drop-ins and whether any form of object cache was active. After also ruling that out, it came to me that the hosting provider must be the issue. I didn't know and had to find out that they use Cloudflare as DNS provider to have a valid SSL certificate for their website. However by default Cloudflare also comes with caching which can be quite aggressive.
Since they liked the caching and wanted to keep it turned on, I told my friend to manually purge the cache at Cloudflare. Ta-Da - the updated images were showing just as they should.
So in order to avoid the process of logging into Cloudflare everytime the plugin is called, I was looking for a way to use their API to solve this in a convenient way. I needed some php-code (to integrate into the Wordpress-Plugin)...
I wrote a small and surely improveable php-script which serves exactly this purpose. It uses the given credentials (user-email and API key) to connect to Cloudflare's API. To retrieve the API key:
Login to the Cloudflare account.
Go to My Profile.
Scroll down to API Keys and locate Global API Key.
Click API Key to see your API identifier.
In the first step the script queries the so called Zone-ID which is a unique identifier for the domain you want to control. Since Cloudflare to date gives no option to view this ID in their backend it can only be obtained through an API request.
In the second step we again connect to Cloudflare's API, this time instructing to purge the entire cache for that Zone.
Here's my solution (I put this on the bottom of my plugin updater-script, to run after everything else has finished):
<?php
//Credentials for Cloudflare
$cust_email = ''; //user#domain.tld
$cust_xauth = ''; //retrieved from the backend after loggin in
$cust_domain = ''; //domain.tld, the domain you want to control
if($cust_email == "" || $cust_xauth == "" || $cust_domain == "") return;
//Get the Zone-ID from Cloudflare since they don't provide that in the Backend
$ch_query = curl_init();
curl_setopt($ch_query, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones?name=".$cust_domain."&status=active&page=1&per_page=5&order=status&direction=desc&match=all");
curl_setopt($ch_query, CURLOPT_RETURNTRANSFER, 1);
$qheaders = array(
'X-Auth-Email: '.$cust_email.'',
'X-Auth-Key: '.$cust_xauth.'',
'Content-Type: application/json'
);
curl_setopt($ch_query, CURLOPT_HTTPHEADER, $qheaders);
$qresult = json_decode(curl_exec($ch_query),true);
curl_close($ch_query);
$cust_zone = $qresult['result'][0]['id'];
//Purge the entire cache via API
$ch_purge = curl_init();
curl_setopt($ch_purge, CURLOPT_URL, "https://api.cloudflare.com/client/v4/zones/".$cust_zone."/purge_cache");
curl_setopt($ch_purge, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch_purge, CURLOPT_RETURNTRANSFER, 1);
$headers = [
'X-Auth-Email: '.$cust_email,
'X-Auth-Key: '.$cust_xauth,
'Content-Type: application/json'
];
$data = json_encode(array("purge_everything" => true));
curl_setopt($ch_purge, CURLOPT_POST, true);
curl_setopt($ch_purge, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch_purge, CURLOPT_HTTPHEADER, $headers);
$result = json_decode(curl_exec($ch_purge),true);
curl_close($ch_purge);
//Tell the user if it worked
if($result['success']==1) echo "Cloudflare Cache successfully purged! Changes should be visible right away.<br>If not try clearing your Browser Cache by pressing \"Ctrl+F5\"";
else echo "Error purging Cloudflare Cache. Please log into Cloudflare and purge manually!";
?>
I have a link from the via which I can send sms. It works when I put it in the address bar and fill the required get params and press enter. But how can I load it in the middle of controller action (the framework is Yii2 if that matters) ? I tried with mail() but couldn't reach any result.
The link is like below:
http://sms.***********.com/httpApi/Send.aspx?phone=359.........&body=message&username=xxx&password=xxx
Can I make it with plain php or I have to it via javascript ? Thank you in advance!
cURL allows transfer of data across a wide variety of protocols, and is a very powerful system. It's widely used as a way to send data across websites, including things like API interaction and oAuth. cURL is unrestricted in what it can do, from the basic HTTP request, to the more complex FTP upload or interaction with an authentication enclosed HTTPS site. We'll be looking at the simple difference between sending a GET and POST request and dealing with the returned response, as well as highlighting some useful parameters.
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'YOUR API URL',
CURLOPT_USERAGENT => 'cURL Request'
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Close request to clear up some resources
curl_close($curl);
The basic idea behind the cURL functions is that you initialize a cURL session using the curl_init(), then you can set all your options for the transfer via the curl_setopt(), then you can execute the session with the curl_exec() and then you finish off your session using the curl_close().
You should use сURL.
$query = http_build_query([
'phone' => '359.........',
'body' => 'message',
'username' => 'xxx',
'password' => 'xxx'
]);
$c = curl_init();
curl_setopt($c , CURLOPT_URL , 'http://sms.***********.com/httpApi/Send.aspx/?' . $query);
curl_exec($c);
curl_close($c);
I'm trying to add a new Deal with the Pipedrive API.
To do so I've followed this tutorial: http://support.pipedrive.com/customer/portal/articles/1271064-how-to-send-in-deals-using-a-web-form
But there's something I didn't understand:
"Email API gives your company a special email address you can use to
automate lead generation and adding of new contacts and
organizations."
Where can I get this email address, there's no other mention of it at the tutorial?
Since I'm unable to follow the tutorial I'm trying to add a new deal with cURL, this is the code:
<?php
$deal = array("item_type" => "deal","stage_id" => 1,"title" => "Atendimento Web Site","organization" => "Company","owner" => "johndoe#company.com.br","visible_to" => 2,"person" => array("name" => $nome,"email" => $email,"organization" => $empresa,"phone" => $tel));
$deal_string = json_encode($deal);
$ch = curl_init('https://api.pipedrive.com/v1/deals?api_token=TOKEN');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $deal_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json, charset=UTF-8',
'Content-Length: ' .strlen($deal_string))
);
echo $deal_string;
echo curl_exec($ch);
?>
And this is what I get:
iten sent -> {"item_type":"deal","stage_id":1,"title":"Atendimento","organization":"Company","owner":"owner#mail.com.br","visible_to":2,"person":{"name":"Jo\u00e3o Neto","email":"mail#mail.com.br","organization":"Company 2","phone":"7112345678"}}
return from api -> {"success":false,"error":"Deal title must be given.","data":null,"additional_data":null}
Where's the error?
About the email support it's true that you are mixing two thing, although it was also happened to me the first time. I admit it would seem strange, an API in which you can use emails.
Anyway, I was working on a simple integration between Pipedrive and another platform and I used the full REST API.
I noticed every time you have an error creating a Deal or you make a mistake in the Json (even if title is ok), you always get the same answer "error":"Deal title must be given.". Of courses it won't help you too much.
So, I recommend you to use some tools like RESTClient for Firefox to simplify the problem at the beginning or even Firebug to sniff it from https://developers.pipedrive.com/v1 making use of their tools to understand the request a little bit better. After that, you can do it more complex.
I am putting you a screenshot in which you can see the simplest example. I hope it will be useful for anyone
I'd receive an email from Pipedrive Support with a full anwser.
*Hi,
Thanks for reaching out!
I'm sorry to hear about the trouble!
So you're mixing up two completely separate things. You're sending in the JSON object needed for the Email API into the REST API.
You have 2 options.
You could go full on with the email API. To do this you need to log into your Pipedrive account, navigate to the Settings, Features page and enable the Email API feature. Then click through to the email API page and get the email address you need to send the object to. And then alter your PHP code to send in that object to that email address as a plain text email. No curl or API token needed for that.
You could clean up the data object you're sending in with the REST API. But you need to understand that the REST API works a little different from the Email API. So you can't just send in the person object along with the deal. You would first need to POST in the person with all the details to the persons endpoint and get back the ID. You can then use the person ID in the deals POST.
I hope this helps
Martin Henk | Co-Founder, Head of Customer Support
Pipedrive*
I want to implement an 'robot' that could automatically fill forms.
Is there an solution when you can fill data on page for example,form1.html and submit it, wait to next page and submit with data on form2.html,and so on...
In the end it should also 'click' on a button to get a file that the form creates.
I want this 'robot' would use some confidential information, so it cant be done using client side technologies.
I was thinking about PHP - building it as a web site-web service, so you could transfer data to a web address, or a Web Service in .Net.
If it's important,the site I want to fill automatically is runs with ASP.NET.
I kind a new here...Can anyone give some examples or tutorials doing this thing. If exist some technologies that I didn't mention here to realize it I would be glad trying them also.
Forms work by posting data, so instead of making a robot that would type something into every field and click submit, you can just POST the data to the server.
First grab the form fields names, and the action of the form.
Then CURL:
//set POST variables
$url = 'http://domain.com/get-post.php';
$fields = array(
'lname' => urlencode($last_name),
'fname' => urlencode($first_name),
'title' => urlencode($title),
'company' => urlencode($institution),
'age' => urlencode($age),
'email' => urlencode($email),
'phone' => urlencode($phone)
);
//url-ify the data for the POST
foreach($fields as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string, '&');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Snippet from this site.
Use Selenium.
"Selenium automates browsers. That's it. What you do with that power is entirely up to you. Primarily it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well."
See examples here.
I am writing a PHP application that's supposed to allow users to add certain events to a private Google Calendar. The calendar is owned by me, and I need a way for PHP to communicate with the calendar API using fixed credentials (everyone can add events using a form on the website, but the calendar itself is not publicly visible).
From what I have read, this is possible using ClientLogin in the v1 API. In the v3 API, however, the available options are OAuth2.0 or the API key. Using the API key doesn't seem to work, since it can only be used for requests that don't require authorization, and OAuth doesn't seem right either, because users are not supposed to access their own calendars, but the one my application uses.
I thought about getting the OAuth token programatically, but that's bound to break sooner or later, since the OAuth dialog can use captchas.
This seems to be such a standard use case — a web application that lets users interact with a single calendar in some predefined ways — yet I can't find any documentation on how to make it happen in the v3 API. Can anyone help me?
I have found a solution that I think that is "the official" for what you want to do.
First, you have to activate a Google API "Client ID for installed applications".
Go to the Google API console and create the project.
Then, activate the calendar.
Go to the "API access" option, and use the "Create OAuth 2.0 client" button.
Give a name (and a logo, if you want) to the product. Click "next".
Choose the "Installed application" option and click "Create Client Id".
Now you have your access configurated. Now, you will need some codes. To obtain them:
*The "Authentication Code". To get it, you need the following information:
SCOPE: https://www.google.com/calendar/feeds/ (if you want to access the calendar API. There are others you can find them at the OAuth 2.0 Playground)
CLIENT_ID: You will find it at the API Access Section at the Google API Console.
REDIRECT_URI: Get it at the same place.
Now, copy the following code into a file, put the values into the variables, execute the code (php -q script_name.php), and go to the URL printed.
<?php
$scope = '';
$client_id = '';
$redirect_uri = '';
$params = array(
'response_type' => 'code',
'client_id' => $client_id,
'redirect_uri' => $redirect_uri,
'scope' => $scope
);
$url = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($params);
echo $url."\n";
?>
The web page will ask you to allow the access. Do it, and you will get a code, which is your Authentication Code.
*The "Refresh Code". To get it, you will need:
The data you used before, plus the "client secret" code in the API Console, between the "client id" and the "redirect URI".
As you did before, copy the following code, and put the variables in place (the code field is the Authentication Code).
Execute and the result is the "Refresh Token".
<?php
$url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
'code' => '',
'client_id' => '',
'client_secret' => '',
'redirect_uri' => '',
'grant_type' => 'authorization_code',
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$token = json_decode($result);
echo $token->refresh_token . "\n";
?>
At this moment, you have all you need. Be careful if one day you change the Authentication Code. You will have to get new keys.
To access a calendar service, here you have the example:
Change the variable values before using it.
This example gets the primary calendar events, but you can change the address for any in the calendar API (http://code.google.com/intl/ca/apis/calendar/v3/getting_started.html#background_operations)
<?php
$scope = 'https://www.google.com/calendar/feeds/';
$client_id = '';
$client_secret = '';
$redirect_uri = '';
$refresh_token = '';
$token_url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
'client_secret' => $client_secret,
'grant_type' => 'refresh_token',
'refresh_token' => $refresh_token,
'client_id' => $client_id
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$token_object = json_decode($result);
$access_token = $token_object->access_token;
// Get the results
$rest_url = 'https://www.googleapis.com/calendar/v3/calendars/primary/events';
$header = "Authorization: OAuth " . $access_token;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
curl_setopt($ch, CURLOPT_URL, $rest_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$rest_result = curl_exec($ch);
print_r(json_decode($rest_result));
?>
First, the script asks for an "Access Token", which is valid for an hour. Then, the script gets the REST service (any in the calendar scope), sending the access token in the header.
To give a best speed at the scrip, it would be good to store the access token in a cache until it's older than 3600 seconds. This way, the script would avoid one of the two calls.
Tips:
Visit OAuth 2.0 Playground to understand all the information sent in the OAuth process. It helped me a lot
A post by Eric Nagel in his blog gave me the solution. All the merit is to him. I can't link it since I haven't got enough "reputation".
You will need to use both the Developer Key (API Key) and OAuth2. The developer key authenticates who wrote the software and is used for things like quota which is on a per developer basis not a per user basis. OAuth2 is for user authentication and will be need to access the non-public calendar.
OAuth2 has a renew token from which you can generate a session token and this means that you will not need to screen scrape the OAuth screens to get authenticated. To get this I would write a little command line application, or you use a one off PHP page.
Under the Google Api Console go to API Access
Generate a new Client ID and choose Installed Application ( as you will be authenticating you server as you not as your user)
Either using a console app or a one off PHP page authenticate using OAuth and your google account (the one with the calendar you want access to)
In the return from the authentication there should be a renew token, (called renew or refresh or something similar). Save this string and make it available to your PHP site.
When you need to access the service your OAuth library should have a renew/refresh call. There is an example using .Net below.
private IAuthorizationState CreateAuthorization(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { AdsenseService.Scopes.AdsenseReadonly.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
if (refreshToken.IsNotNullOrEmpty()) // refreshToken you stored in step 4
{
try
{
state.RefreshToken = refreshToken;
if (arg.RefreshToken(state)) // This is calling out to the OAuth servers with the refresh token getting back a session token, returns true if successful.
{
if (state.RefreshToken != refreshToken) // if the refresh token has changed, save it.
{
PersistRefreshToken(authorization.RefreshToken);
}
return this.authorization = state; // Retain the authorization state, this is what will authenticate your calls.
}
}
catch (ProtocolException ex) {...}
The AuthorisationState that has now been renewed can then be used to authenticate call you make to the API. this state can be used many time until it expires and then can be refreshed. As you are authenticating your application as yourself not as a user this AuthorisationState can be shared by all you sessions. Both the current AuthorisationState and the refresh token should be kept securely on your server and never sent to the client, if you ever sent these as part of a response your clients would have the same privileges as your code application
Can also be used with the Google php library. The access token for the $client->setAccessToken() function has to be formatted in the following way:
$at= '{"access_token":"' . $access_token . '",' .
'"token_type":"Bearer",' .
'"expires_in":3600,' .
'"refresh_token":"' . $refresh_token . '",',
'"created":' . time() . '}';
Where $access_token is the access token found by you and $refresh_token is the refresh token. Tested with the useless simple.php google example.
Authentication is then just:
$client->setAccessToken($at);