We are using a GTM container server.
We want to send different events from the back-end of our web application directly to our GTM server container.
The idea is to be able to activate tags that will send these events to different sources (Mixpanel, SendinBlue,...)
In the GTM server-side documentation we discovered that it is possible to use the measurement protocol used by Google Analytics.
To do this, you need to create or use a MeasurementProtocol client
So we created a new client with the path /mp/collect and tried to use the MeasurementProtocole for GA4 because we also use GA4 for Analytics.
https://developers.google.com/analytics/devguides/collection/protocol/ga4
But in the example request, it is asked for a measurementId and an apiSecret.
These are provided by GA.
What information should we give if we want to send the event to the GTM server client directly?
This is our script to test:
function myFunction() {
const measurementId = `G-XXXXXXX`;
const apiSecret = `FFFFFFFFFFFFDDDDDDDDD`;
UrlFetchApp.fetch(`https://xxxxx.xxxxxxxx.com/mp/collect?measurement_id=${measurementId}&api_secret=${apiSecret}`, {
method: "POST",
payload: JSON.stringify({
"client_id": "client_id",
"events": [{
"name": "generate_lead",
"params": {
"currency": "USD",
"value": 99.99
}
}]
})
});
}
But we have this error
So to be able to send events from my back-end to sGTM (GTM Server container) I used this repo on Github:
https://github.com/square/server-to-server-gtm-client
1 - To install it you must download the template.tpl file from the repo.
2 - Then on sGTM you go at the bottom of the left menu and click on "Template"
3 - You must click on New in the Client Template section.
4 - After you can click on the three dot menu in the top right corner and select import.
5 - This is the moment where you import the template.tpl file you download before.
6 - Now you can click on "Client" item on the left menu and create a new Client
7 - For the client configuration select the template you created before.
8 - Then follow the readme of the repo on Github :-)
With this solution you will be able to send event from your back-end directly to the sGTM container (server).
You should give measurementId only. Without apiSecret.
Then if you are in gtm preview mode you should take X-Gtm-Server-Preview HTTP header (inside gtm preview mode find 3 dots in the upper right coner). You should add it in request.
Then you create mp client.
My python example:
# for GA4
import requests
import json
data = { "client_id": '111222333',
"events": [{"name":"page_view",
"params":{
"external_id": '123123123',
"action_source": "app"}
}]
}
data = json.dumps(data).encode("utf-8")
url = "https://yourserverdomain.com/mp?measurement_id=G-XXXXXXX"
headers = {
"x-gtm-server-preview" : "ASDADASDASDASFASFASFASFASF",
"Content-Type": "application/json",
"Origin": "https://google.com"
}
resp = requests.post(url, headers=headers, data=data)
print(resp.status_code)\
# for Facebook conversion API
url = "https://yourserverdomain.com/mp"
data = {"client_id": '123123',
"events":[{ "name":"PageView",
"params":{"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36",
"ip_override": "89.1.1.1",
"page_location":"https://google.com/",
"action_source": "app",
"external_id": "12345",
"user_data": { "email_address": 'asdasd',
"phone_number": "123",
"external_id": "12345",
"adress": {"country": "uk"}
}
}
}]
}
data = json.dumps(data).encode("utf-8")
headers = {
"x-gtm-server-preview" : "ASDASFDFAFASDFASDFASDFASDF=",
"Content-Type": "application/json",
"Origin": "https://google.com"
}
resp = requests.post(url, headers=headers, data=data)
print(resp.status_code)
If it still doesn't work, try path wuthout "collect", just "/mp".
In my experience, you will get 400 error if you have invalid event format (e.g. lost necessary params.
Related
Can't find a way to set the debug_mode parameter using Measurement Protocol 4.
Tried to put it everywhere (and naming it all i can think of) but without luck :)
Documentation is still very light and doesn't mention the debug_mode.
With web/js and GA4 it works fine!
Weird. Suddenly the debug mode started to work with code I'm 100% sure didn't work before.
Adding the parameter "debug_mode": true to the measurement protocol request will make it show up in Analytics' DebugView.
Sample json payload that works:
{
"client_id": "XXXXXXXXXX.YYYYYYYYYY",
"events": [
{
"name": "page_view",
"params": {
"page_location": "...",
"page_path": "...",
"page_title": "...",
"debug_mode": true
}
}
]
}
To add to the answers of #DalmTo and #bang - I wasn't seeing events I was sending over the Measurement Protocol show up in our GA4 Debug View. The root cause in my case was that the Measurement Protocol expects a funky format for the user_properties, but the following steps should help others debug other problems as well.
Steps I took to resolve:
Add the debug_mode: true field to individual event params as described in #bang's answer
Use the /debug/mp endpoint as described in #DalmTo's answer - this pointed me towards the errors in my user_properties format
Regarding the user_properties field, I was sending something along these lines:
{
"client_id": "XXX.XXX",
"user_id": "YYY",
"user_properties": {
"property_a": "value_a",
"property_b": "value_b"
},
"events": ...
}
Turns out GA4 / Measurement Protocol expect something like this:
{
"client_id": "XXX.XXX",
"user_id": "YYY",
"user_properties": {
"property_a": { "value": "value_a" },
"property_b": { "value": "value_b" }
},
"events": ...
}
At the time of writing, the only way to figure this out is to carefully check out the example here.
The measurment protocol for ga4 has two endpoints just like the measurment protocol for the old Google anlaytics
Measurement Protocol /mp/collect
Measurement Protocol Validation Server /debug/mp/collect
So if you send a event to it will be sent to Google anlaytics ga4
POST /mp/collect HTTP/1.1
HOST: www.google-analytics.com
<payload_data>
So if you send a event to it will be sent to debug endpoint for Google anlaytics ga4
POST /debug/mp/collect HTTP/1.1
HOST: www.google-analytics.com
<payload_data>
I'm trying to generate a dynamic link in firebase using the REST API. I've tried following instruction on the following page of the documentation: https://firebase.google.com/docs/dynamic-links/rest#create_a_short_link_from_parameters
My apologies in advance for bad formatting, but my request looks something like this:
POST https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=
with headers:
Content-Type: application/json
and body:
{
"dynamicLinkInfo":{
"domainUriPrefix":"https://<myDomain>.page.link/",
"link":"https://www.google.com/",
"androidInfo":{
"androidPackageName":"com.<companyName>.<appname>"
}
}
}
The response i get is:
{
"error": {
"code": 400,
"message": "Invalid Dynamic Link domain: '' or Domain Uri Prefix: 'https://<myDomain>.page.link/'. Expecting exactly one. Dynamic Link Domain isPresent = false, Domain URI prefix isPresent = false, [https://firebase.google.com/docs/dynamic-links/rest#create_a_short_link_from_parameters]",
"status": "INVALID_ARGUMENT"
}
}
My firebase project has a the .page.link domain registered within the project. In the dynamic links section of the firebase project it does show up. I've tested creating links in the firebase console and i've even been able to manually make dynamic short-links using the react-native-firebase package so i'm pretty sure nothing is wrong with my project.
You cannot have / at the end of domainuriprefix. Can you try removing it?
I want to add another solution.
In my case a simple white space in front of 'https' was the trigger.
"message": "Invalid Dynamic Link domain: '' or Domain Uri Prefix: ' https://[...]'
You do need to add the https:// portion to your domainUriPrefix ->
{
"dynamicLinkInfo":{
"domainUriPrefix":"<myDomain>.page.link",
"link":"https://www.google.com/",
"androidInfo":{
"androidPackageName":"com.<companyName>.<appname>"
}
}
}
I am trying to send information from user submissions (Contact Form 7) to third-party app. I am using this plugin
https://wordpress.org/support/plugin/cf7-to-api/
The third-party app provided an access token and this example of creation request for me
curl -X "POST" "https://api.example.com/initial-params" \
-H 'Content-Type: application/json' \
-H 'X-Landing-Page-Access-Token: your-value-here ' \
-d $'{
"move": {
"date": "2018-09-01"
},
"consumer": {
"givenName": "Mike",
"phone": "234234242",
"email": "mike#example.com",
"familyName": "Simon"
},
"origin": {
"zip": 3245,
"beds": 8
},
"destination": {
"zip": 12342
}
}'
and this is their documentation
An end consumer enters details onto a landing page. Once all details have been entered, the landing page POSTs to our API's Initial Params endpoint. Our app stores the parameters and generates a unique identifier. Once the API call to create Initial Params succeeds, the landing page automatically redirects to the survey web app with the identifier set as a URL parameter (e.g., ?identifier=xxx... )
- Important : Our survey web app must have received this import in order for follow-up
messaging to work if the consumer drops off. As a result, it is recommended to automatically
redirect to our survey web app after the Initial Params have been created as opposed to
requiring a button click.
When our survey web app loads, it queries our API to retrieve the parameters. With the
parameter information, it then initializes the survey web app and API to the state specified in the
Initial Parameters. Each screen that has input completely satisfied is automatically skipped. The consumer finishes the process on our survey web app. One this identifier has been generated, the landing page can redirect to our survey web app. This identifier should be passed along to our survey web app via the identifier URL parameter, which will in turn allow the provided consumer details to be loaded inside our app. Example link: https://api.example.com/?identifier=xxx
This is a creation response example the third-party app also provided
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Date: Wed, 18 Jul 2018 16:55:04 GMT
Server: nginx
Content-Length: 380
Connection: Close
{
"status": [
{
"type": "ok"
}
],
"identifier":
"some-unique-identifier",
"serverTime": "247.334 ms"
}
So, I used this https://api.example.com/initial-params as the URL to post to, added the access token using this piece of code in functions.php
add_filter( 'qs_cf7_api_get_args', 'add_http_header' );
function add_http_header( $args ) {
$args['headers']['X-Landing-Page-Access-Token'] = 'example-access-token';
return $args;
}
and I used this in the JSON template
-d $'{
"move": {
"date": "[date]"
},
"consumer": {
"givenName": "[givenName]",
"phone": "[phone]",
"email": "[email]",
"familyName": "[familyName]"
},
"origin": {
"zip": [zip1]
},
"destination": {
"zip": [zip2]
}
}'
My questions are:
How can I check the result I get from them, to see if they are receiving the info and generating the identifier?
How to redirect to their landing page with the identifier in the end when a form is submitted? That identifier is a variable and is unique each time, which means somehow I have to redirect to a variable after submission.
Any help is much appreciated.
Thank you!
I've gone through the authentication and am receiving the correct data from LinkedIn and receiving a response as shown in this link:
https://developer.linkedin.com/docs/ref/v2/profile/profile-picture
However, I'm unsure how to extract the image from this:
"displayImage": "urn:li:digitalmediaAsset:C4D03AQGsitRwG8U8ZQ",
Do I need to make another request for the image url next?
For anyone else looking, I overlooked there is an identifier field like so with a url:
"identifiers": [
{
"identifier": "https://media.licdn.com/dms/image/C4D03AQGsitRwG8U8ZQ/profile-displayphoto-shrink_100_100/0?e=1526940000&v=alpha&t=12345",
"file": "urn:li:digitalmediaFile: (urn:li:digitalmediaAsset:C4D03AQGsitRwG8U8ZQ,urn:li:digitalmediaMediaArtifactClass:profile-displayphoto-shrink_100_100,0)",
"index": 0,
"mediaType": "image/jpeg",
"identifierExpiresInSeconds": 1526940000
}
To get the above response in ruby I'm doing the following:
url = 'https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))'
res = RestClient.get(url, Authorization: "Bearer #{access_token}")
Use this:
url = 'https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,emailAddress,profilePicture(displayImage~:playableStreams))&oauth2_access_token=' + access_token
All the old questions are 3-8 years out of date. Need help with V3 of Google calendar API.
I don't get how to specifically invite an email to the calendar from this documentation: https://developers.google.com/calendar/v3/reference/acl
I see how to set the share permissions of the selected calendar, but where do we put the email that we want to share to??
so i guess that you want to share your calendar with an email, this is my working code in python:
#ACL INSERT add partecipant to a calendar
def update_calendar_by_adding_partecipant_to_a_calendar():
id = "mail#gmail.com"
url = "https://www.googleapis.com/calendar/v3/calendars/"+ id +"/acl"
payload = {
"role": "reader",
"scope": [{
"type": "user",
"value": "mail#gmail.com"
}]
}
response = requests.request("POST", url, headers=headers, data=json.dumps(payload))
json_response = response.text
json_share=json.loads(json_response)
print(json_share)