Google measurement protocol losing acquisition data - google-analytics

How do I make sure that customer purchases tracked using the Measurement Protocol retain their association with the original Google Analytics session?
Detail:
When my site stopped registering customer purchases in Google Analytics (a whole other problem) I moved over to using the Measurement Protocol to send transactions to GA. This works *almost* perfectly - purchases appear in Google Analytics (I'm using Enhanced Ecommerce tracking) reliably.
However, almost all transactions are attributed to the 'direct' channel. Only a very few - perhaps 10% - retain their association with the campaign or channel that brought the customer to my site.
Here is an example of what I send using the Measurement protocol, from the 'thank you' page after a customer has made an order.
Array
(
[v] => 1
[tid] => UA-1234567-1
[cid] => 424729672.1597913127
[t] => pageview
[dh] => www.mysitename.co.uk
[dp] => /complete.php
[dt] => complete
[ti] => 540892
[ta] => Company Name
[tr] => 162.50
[tt] => 32.50
[ts] => 0
[col] => UNKNOWN
[pa] => purchase
[ua] => Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36
[geoid] => GB
[uip] => 12.34.56.78
[cu] => GBP
[uid] => 798f77110ea1667e9fdfc27ce83471042f01884c
[pr1id] => 15154737723
[pr1nm] => Product name in product colour
[pr1br] => Brand name
[pr1ca] => Product Category name
[pr1pr] => 195.00
[pr1qt] => 1
[pr1va] => Brown & tan
[z] => 1640
)
As you can see cid and uid are present. The cid is extracted from the _ga cookie. The uid (added yesterday) is what I have previously assigned to the customer earlier in their checkout process, but adding this has not improved the attribution situation. (Should I wait 24-48 hours to check?)
All payment processors, including 3D Secure domains, have been added to my Referral Exclusions list. My site is split between www.mysitename.co.uk (browsing) and secure.mysitename.co.uk (buying), but both of these domains are in the exclusion list as well, so I don't think it's cross domain issues, although the symptoms are similar.
utm_nooverride=1 has been added to the 'success' URLs supplied to payment processors, also, to no avail.
The site runs on a LAMP stack, apache 2.4, php 5.6. Server upgrade is due soon.
There are no other issues with Google Analytics. As well as Universal Analytics there is also some Google Tag Manager usage on the site.

If two hits share the Google Analytics Property ID and the Client ID (cid), and they take place within the session timeout (30 minutes) and on the same side of midnight, and they share all the campaign parameters, then they will be contained in the same session.

I've noticed that you're not sending the queue time parameter (qt) in the request. Are you sending the hits immediately after the phone call? Does this action occur moments later?
I believe that even if you send the hit immediately after the phone call, Google Analytics could process the hit with some delay. The queue time parameter is important to specify the exact time of the action.
I'm sending Enhanced Ecommerce purchases through the measurement protocol as well and I send the queue time parameter with the difference in seconds between the real timestamp of the purchase and the timestamp of the moment that my hit is being sent.
If you already solved this question, let us know.
You can read about sending a hit to a moment in the past in this excellent article https://www.simoahava.com/analytics/send-hits-past-google-analytics/.

Related

Oracle APEX call Dialogflow V2 in PL/SQL - Authentication with OAuth2 or Google Service Account

Migrating from Dialogflow V1 means that embedding the API key inside of client-side javascript no longer works. Instead, authentication is required with a Google Service Account (or OAuth works too? Still unclear on this).
Since the chatbot is on Blogger, there is no easy way to add server side code which would use the Google Cloud SDKs to authenticate.
So, the requests need to be routed through our Oracle APEX server, which needs to authenticate itself with Dialogflow. However, I am having difficulties with the following procedures:
https://docs.oracle.com/database/apex-5.1/AEAPI/OAUTH_AUTHENTICATE-Function.htm
https://docs.oracle.com/database/apex-18.1/AEAPI/MAKE_REST_REQUEST-Function.htm
oauth_authenticate fails with the error
s_internal_error: true
apex_error_code: APEX.REGION.UNHANDLED_ERROR
ora_sqlcode: -20001
ora_sqlerrm: ORA-20001: Authentication failed. ORA-06512
Here is the overall code:
create or replace procedure "TEST_DIALOGFLOW"
is
begin
begin DECLARE
l_response_clob CLOB;
l_rest_url VARCHAR2(1000);
l_token_url VARCHAR2(1000);
l_count_posted PLS_INTEGER;
BEGIN
l_rest_url := 'https://dialogflow.googleapis.com/v2/projects/<project>/agent/sessions/0:detectIntent';
l_token_url := 'https://accounts.google.com/o/oauth2/token';
apex_web_service.oauth_authenticate(
p_client_id => <client id>,
p_client_secret => <client secret>,
p_token_url => l_token_url,
p_wallet_path => <wallet path>,
p_wallet_pwd => <wallet password>
);
l_response_clob := apex_web_service.make_rest_request(
p_url => l_rest_url,
p_http_method => 'POST',
p_scheme => 'OAUTH_CLIENT_CRED',
p_body => '{"queryInput":{"text":{"text":"test","languageCode":"en"}}}',
p_wallet_path => <wallet path>,
p_wallet_pwd => <wallet password>
);
htp.p('HTTP Status Code: '||apex_web_service.g_status_code);
IF apex_web_service.g_status_code = 200 THEN
apex_json.parse(p_source => l_response_clob, p_strict => true);
END IF;
END;
end;
end;
I suspect that the token URL is incorrect. Or that there is a simpler way to handle this.
I also have a suspicion about the OAuth setup inside of GCloud. Do these have to be filled out?
Also, I am unclear on a Google Service Account vs. OAuth. Right now, the setup is for an OAuth key I made for Dialogflow. However, the recommended is with a service account, but I am unsure how to use the above procedures to login with those credentials.
You will need to use OAuth if you want to access the user data for the application, such as user watch time on YouTube.
By reading your code and comment, if I am not mistaken, you are implementing the chatbot on Google Blogger, right? If this is the case, you can code PHP to simplify the procedure. You can embed <iframe> and link to your own server, your server side code can be done in your server. I hope this helps.

Webhook limitations in linkedin API (webhook is not receiving updates)

LinkedIN has recently released support for webhooks and we are successful in creating a webhook url. We are able to authorise a user administrator of a company to our app and get permissions to write and read from the REST API.
However we are not receiving any webhook updates from the app for that company. And there is no documentation on how to subscribe to a particular company like in other social-media API:s witch we have vast experience from (fb,IG,Twitter).
The documentation on LinkedIn is very limited on the subject. And we are not sure what we can expect from the webhook requests from linkedIn. What is the reason we are not getting Webhooks for that company?
We dont even get webhook calls for the organisation owning the app.
Any help appreciated.
https://learn.microsoft.com/en-us/linkedin/shared/api-guide/webhook-validation?context=linkedin/context
I figure it out I need to add header json to output for validation.
Here is my code in php
if (isset($_REQUEST['challengeCode'])) {
header('Content-Type: application/json');
echo json_encode([
'challengeCode' => $_REQUEST['challengeCode'],
'challengeResponse' => hash_hmac('sha256', $_REQUEST['challengeCode'], 'client secret'),
]);
exit;
}
and for webhook subscription
$api->setApiHeaders([
'X-Restli-Protocol-Version' => '2.0.0',
]);
$developerUrn = urlencode("urn:li:developerApplication:developerid");
$personUrn = urlencode("urn:li:person:personid");
$orgUrn = urlencode(""urn:li:organization:pageid");
$endpoint = "(developerApplication:$developerUrn,user:$personUrn,entity:$orgUrn,eventType:ORGANIZATION_SOCIAL_ACTION_NOTIFICATIONS)";
$api->api("eventSubscriptions/$endpoint", ['webhook' => "WEBHOOK_URL"], 'PUT');
Webhooks are a closed beta feature at this time:
Who can use this: Any developer using a webhooks API (currently available only for social action notifications on company posts to beta partners)
Source: https://learn.microsoft.com/en-us/linkedin/marketing/integrations/recent-changes

Use AWS SNS to send different messages to 10000 users?

I have 10000 users, and i want to push notification SNS to each user, with different message.
So, i cannot use Topic in this case.
The problem is it delay too much. (About 1h30 hour for this to complete)
Any solution?
Thank you so much!
Endpoint is something like internal AWS Identificator for combination: platform+device token or smth else. When we want to send an message we use it as address point instead of real.
About adding Endpoint to SNS. Generally it looks like so:
You should register your platform in AWS SNS and receive e.g. for IOS - iOS app's Application ARN. It can be done via e.g. AWS Web Console
After you should create for each target user its endpoint with method like this:
$endPoint = $snsClient->createPlatformEndpoint([
'PlatformApplicationArn' => $SNS_APP_ARN,
'Token' => 'phone token'
]);
phone token for push notification is device-token. Endpoint generally is array/object which contains EndpointArn. Use it address when send message.
After that you can send an message to specific endpoint.
$snsClient->publish(
array(
'Message' => $pushMessage,
'TargetArn' => $endpointArn
));

Paypal payment and automatic digital media download

I am creating a website, where I will sell computer and calculator programs. When the "buy" button is pressed. I would like the user to be directed to Paypal (whether they stay on the website or not). After they pay, the user would be brought back to my website, and the program would automatically download.
How can i do this to ensure:
The user correctly pays for the program through Paypal
The correct program that they paid for downloads after
There is no direct link to the program so that the user could then download it many times without paying.
Thank you very much in advance!
Paypal PDT (redirecting after payment) and IPN (behind the scenes) is exactly what you are after.
Check this:
https://www.paypal.com/cgi-bin/webscr?cmd=p/xcl/rec/pdt-intro-outside
Here is sample code for the script to get you started instantly:
https://www.paypal.com/us/cgi-bin/?cmd=p/xcl/rec/pdt-code-outside
Some additional Tips for security:
Verify amount, currency and product-id with your database's data to make the download available. Open a paypal sandbox account.
To don't reveal the download location:
Use the order-id verified by pdt as a unique download-identifier. You have to use a script like this: redirect the user in the pdt-script here or include it in pdt if payment verrified:
<?
$orderid = $_GET['orderid'];
$productid = $_GET['productid'];
$time = $_GET['time_from_paypal']; // when the purchase was made
$fn = "files/".$productid.".mp3";
($time =here your conditional)?$do==true:$do==false;
if ($do==true){
header('Content-Disposition: attachment; filename=' . basename($fn));
readfile($fn);
} else {.....
?>
the part "here your conditional" can be anything. you could restrict them to download within the following x seconds after the payment was made. usually the processing from paypal takes a maximum of 20 seconds. so if you want the download to be made only once check if the payment_time and the actual time divergent less than 30 seconds. because of the redirect the user gets the download instantly after payment is veriffied.
wrote but not tested

what is the rate limit for Google translate API V2?

I am using the Google translate API V2 very intensely and after about 2000 requests I start getting this in the returning JSON:
Array
(
[error] => Array
(
[errors] => Array
(
[0] => Array
(
[domain] => usageLimits
[reason] => userRateLimitExceeded
[message] => User Rate Limit Exceeded
)
)
[code] => 403
[message] => User Rate Limit Exceeded
)
)
Any idea what the rate limit is? and do you have a smart way of regulating the requests rate?
I finally found out so I will answer my own question.
The rate limit for the API can be set at the admin panel for your API's (https://code.google.com/apis/console) under the quotas section in the left hand menu.
I did not find a full documentation of the possible errors that can be returned by an API.
HTTP status 403 is returned whenever the quota is exceeded.
Remark
I've been playing around with very low quotas to test whether this really works as expected. It seems that the quota settings are not applied immediately, since it took some time (~10-20 minutes) until the API finally stopped working (and returned the mentioned error code).

Resources