<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ruben Vezzoli</title>
	<atom:link href="https://www.rubenvezzoli.online/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.rubenvezzoli.online/</link>
	<description>Web Analytics</description>
	<lastBuildDate>Tue, 10 Oct 2023 21:14:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.4</generator>

<image>
	<url>https://www.rubenvezzoli.online/wp-content/uploads/2017/11/cropped-favicon-32x32.jpg</url>
	<title>Ruben Vezzoli</title>
	<link>https://www.rubenvezzoli.online/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>MeasureCamp Stockholm 2023: my takeaways</title>
		<link>https://www.rubenvezzoli.online/measurecamp-stockholm-2023/</link>
					<comments>https://www.rubenvezzoli.online/measurecamp-stockholm-2023/#respond</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Tue, 10 Oct 2023 21:14:31 +0000</pubDate>
				<category><![CDATA[Web Analytics]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1428</guid>

					<description><![CDATA[<p>The wind and the cold weather accompanied the weekend in Swedish land as I attended Measurecamp in Stockholm. In this post, I&#8217;ll gather some tips and thoughts I collected during the sessions I attended. Make Google Analytics great again [discussion with Googlers] The fact that traffic from Google Ads is counted as organic within the [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-stockholm-2023/">MeasureCamp Stockholm 2023: my takeaways</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The wind and the cold weather accompanied the weekend in Swedish land as I attended <strong>Measurecamp in Stockholm</strong>. In this post, I&#8217;ll gather some tips and thoughts I collected during the sessions I attended.</p>
<h2>Make Google Analytics great again [discussion with Googlers]</h2>
<p>The fact that <strong>traffic from Google Ads is counted as organic within the BigQuery export is not a bug</strong>; it was intentionally designed this way by Google&#8217;s product team. Therefore, we will need to continue to integrate Google Ads data in the GA4 export.</p>
<p>There won&#8217;t be a <strong>built-in attribution model within the BigQuery</strong> export.</p>
<p>They&#8217;ll investigate why some<strong> rollup properties</strong> only populate with data several days after collection.</p>
<p>There was a request to <strong>improve the GA4 course in Skillshop</strong> by integrating more general web analytics concepts, similar to what was done in the old course.</p>
<p>The idea of c<strong>reating a kind of cookbook for custom reports within GA4</strong> was discussed. I&#8217;m not entirely convinced about this idea, mainly because the request was made to replicate GA3 reports in GA4.</p>
<p>Then, <strong>a series of missing features in the platform&#8217;s UI were highlighted</strong>, including the ability to export report data in multiple formats, the option to copy table data with CTRL + C (not just right-click), and having the percentage weight of a cell compared to the total column, similar to how it was in GA3.</p>
<h2>Automatize GA4 data workflow using Dataform and Terraform</h2>
<p>My favourite session of the day was the one by <a href="https://www.linkedin.com/in/moritzjbauer/" target="_blank" rel="noopener">Moritz Bauer</a>, probably because I&#8217;ve recently started studying Dataform to understand how it works and how to use it.<br />
<img fetchpriority="high" decoding="async" class="alignnone size-large wp-image-1435" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285-1024x517.webp" alt="" width="700" height="353" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285-1024x517.webp 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285-300x152.webp 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285-768x388.webp 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285-700x354.webp 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/data-stack-e1696969500285.webp 1536w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p>He showed how he uses Dataform to create new views/table from GA4 raw data.</p>
<p>As you can see in the image above, <strong>Dataform can be used to prepare data for use as a source for dashboards or reporting in general</strong>.</p>
<p>He also shared a <a href="https://github.com/Liscor/terraform_dataform_ga4_pipeline" target="_blank" rel="noopener">GitHub repository</a> where he published the <strong>Terraform code he uses to automate the entire process</strong>.</p>
<p>All tables are automatically updated whenever Google loads GA4 data into the tables. From my perspective, this tool has tremendous potential and is still relatively unexplored.</p>
<p>I&#8217;m already conducting tests, and in a few months, I might publish something here explaining what I&#8217;m working on.</p>
<h2>Bot traffic detection with Analytics Firewall</h2>
<p><img decoding="async" class="alignnone size-large wp-image-1440" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall-1024x743.png" alt="" width="700" height="508" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall-1024x743.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall-300x218.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall-768x557.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall-700x508.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/analytics-firewall.png 1106w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p><a href="https://www.linkedin.com/in/david-vallejo-sanz/" target="_blank" rel="noopener">David Vallejo</a> showcased <a href="https://github.com/analytics-debugger/analytics-firewall" target="_blank" rel="noopener">Analytics Firewall</a>, an application he&#8217;s developing with the goal of <strong>ensuring data collection is as accurate as possible</strong>.</p>
<p>In particular, he focused on how it attempts to determine whether GA4 hits are genuinely from a <strong>user or from bot traffic</strong>.</p>
<p>His concept is to have a system similar to anti-spam systems in emails.</p>
<p>The application performs a series of checks on IP addresses, geolocation, the number of hits sent, actions taken on the site, etc., to assess the likelihood that a user is a bot or not.</p>
<p>The score can then be used to tag hits or filter them out before sending them to the endpoint.</p>
<h2>Git for data analysts</h2>
<p><img decoding="async" class="alignnone size-large wp-image-1444" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git-1024x627.png" alt="" width="700" height="429" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git-1024x627.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git-300x184.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git-768x470.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git-700x429.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/git.png 1166w" sizes="(max-width: 700px) 100vw, 700px" /></p>
<p>My colleague <a href="https://www.linkedin.com/in/claudio-ferrara-42384994/" target="_blank" rel="noopener">Claudio Ferrara</a> spoke about <strong>Git</strong> and why its use is fundamental for a data analyst team.</p>
<p><strong>The world of data is no longer a one-man band but more like an orchestra</strong>. That&#8217;s why it&#8217;s essential to have a system that allows everyone to share code and, most importantly, create variations without overwriting other people&#8217;s code.</p>
<h2>Let&#8217;s make an experimentation dashboard</h2>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1449" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard-1024x680.png" alt="" width="700" height="465" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard-1024x680.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard-300x199.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard-768x510.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard-700x465.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/experimentation-dashboard.png 1163w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>The <strong>Conductrics</strong> team then organized a brainstorming session to determine what should be displayed in a <strong>dashboard designed to showcase the success of an experimentation program</strong>.</p>
<p>One of the conclusions was that <strong>it&#8217;s impossible to measure the success of an A/B testing program with a single metric</strong> because there are various variables at play, and not all tests have a positive impact on revenue.</p>
<p>There was a <strong>discussion about the importance of learning from every test</strong>, even those that don&#8217;t lead to a winning outcome. For example, if the result of a test indicates that a particular feature should not be developed, the outcome might not be increased revenue, but rather resource savings that can be reinvested in other projects.</p>
<p>Another topic of discussion was <strong>the due diligence of ideas</strong>. Each idea should be carefully evaluated before implementation to avoid impulsive decisions based on someone&#8217;s immediate thoughts.</p>
<p>I attended other sessions as well, but I found these to be the most interesting. As always, it&#8217;s now time to roll up my sleeves and try out all the new things I learn and the new ideas I have.</p>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-stockholm-2023/">MeasureCamp Stockholm 2023: my takeaways</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/measurecamp-stockholm-2023/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>MeasureCamp London 2023: my takeaways</title>
		<link>https://www.rubenvezzoli.online/measurecamp-london-2023/</link>
					<comments>https://www.rubenvezzoli.online/measurecamp-london-2023/#respond</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Wed, 04 Oct 2023 04:50:54 +0000</pubDate>
				<category><![CDATA[Web Analytics]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1391</guid>

					<description><![CDATA[<p>Finally, I have some time to put together the notes from Measurecamp on Saturday. My 6th Measurecamp was quite an adventure this time. My outbound flight was cancelled and I took 13 hours to reach London (compared to the usual 2 hours) because I had to make a stopover in Malaga. Fortunately, it was truly worth [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-london-2023/">MeasureCamp London 2023: my takeaways</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Finally, I have some time to put together the notes from Measurecamp on Saturday.</p>
<p>My 6th Measurecamp was quite an adventure this time. My outbound flight was cancelled and I took 13 hours to reach London (compared to the usual 2 hours) because I had to make a stopover in Malaga. Fortunately, it was truly worth it.</p>
<h2>Conductrics &#8211; Include Surveys &amp; NPS in A/B Testing</h2>
<p><img loading="lazy" decoding="async" class="alignnone wp-image-1395" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/conductrics-1024x766.png" alt="" width="639" height="482" /></p>
<p>I really liked the approach used by the folks at <a href="https://www.conductrics.com/" target="_blank" rel="noopener">Conductrics</a> in developing their platform. A/B testing <strong>doesn&#8217;t always mean simply identifying the variant that maximizes revenue</strong>. In fact, certain tests may have an indirect impact on revenue but still have a <strong>positive impact on the overall CX</strong>.</p>
<p>Here&#8217;s why the platform permits the integration of <strong>surveys, feedback, and NPS measurements within tests</strong>: it allows for a more comprehensive evaluation of the qualitative aspects of the tested variations.</p>
<h2>A bunch of random GA4 tips &amp; gotchas</h2>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1397" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-1024x739.png" alt="" width="700" height="505" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-1024x739.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-300x217.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-768x555.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-1536x1109.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-2048x1479.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/ga4-tips-700x505.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>Then I attended <a href="https://www.analyticsmania.com/" target="_blank" rel="noopener">Julius Federovicious</a>&#8216;s speech, where he discussed <strong>some gotchas and workarounds</strong> he had created to make the most out of <strong>GA4</strong>. I&#8217;ll try to list below the ones that were most interesting to me.</p>
<p>He explained how to use the <strong>User Purchase Journey report</strong> and discussed why sometimes the report isn&#8217;t populated correctly. In such cases, he elaborated on why it&#8217;s necessary to recreate it within <strong>Explore</strong>.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/DSAmjFuJdaA?si=HfjKd0JMEKpJD1FW" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen"></iframe></p>
<p>As you can see in the video below, he explained how to <strong>monitor searches with zero results in GA4</strong>.</p>
<p><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/AxLHUCNPcUU?si=-9GTybKr0VGlHzmK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen"></iframe></p>
<p>Furthermore, he explained why there are <strong>slight discrepancies in GA4 between the actual transaction value and the UI value</strong>.</p>
<p>GA4 takes all orders in EUR currency, converts them to USD, and then reconverts them to EUR within the UI, leading to minor discrepancies.</p>
<p>Additionally, he shared links to <strong>two GTM templates</strong>. One, developed by <a href="https://github.com/gtm-templates-knowit-experience/sgtm-ga4-ecom-item-list-promo-attribution" target="_blank" rel="noopener">Eivind Savio</a>, allows for the passing of <strong>promotion</strong> and <strong>item list name</strong> values across the different GA4 EEC events. This ensures proper attribution throughout the user journey when interacting with a promotion or item list.</p>
<p>The second template, created by <a href="https://github.com/mohrstade/backTrack" target="_blank" rel="noopener">Mohr Stade</a>, enables the re-pushing of events in the data layer that had been pushed before the consent information was loaded.</p>
<h2>How to better understand your visitors</h2>
<p><a href="https://www.linkedin.com/in/tonwesseling/" target="_blank" rel="noopener">Ton Wessling</a>, on the other hand, delivered a speech/discussion where he aimed to define 10 tips for better understanding your users.</p>
<p>His main point was that <strong>the percentage of experiments yielding results is decreasing</strong>, so there is a need to <strong>focus more on generating new test ideas and prioritizing them effectively</strong>.</p>
<p>For instance, he recommended continuously monitoring and studying the tests that competitors are conducting. He also shared a <a href="https://chrome.google.com/webstore/detail/conversioncoms-optimizely/ejklmdggogcbjpehmmjnebehjafnkiaj?hl=en-GB" target="_blank" rel="noopener">Chrome extension</a> that allows you to track which A/B tests a website is currently running (compatible with Optimizely).</p>
<p>He also talked about how he leverages AI, such as ChatGPT, to simplify his life. For example, he uses <a href="https://scite.ai/assistant" target="_blank" rel="noopener">Scite Assistant</a> to have scientific papers summarized, allowing him to concentrate more on the conclusions drawn by the authors.</p>
<p>He also feeds ChatGPT with competitor reviews to extract their strengths and weaknesses according to their customers.</p>
<p><img loading="lazy" decoding="async" class="wp-image-1398 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/10-tips-758x1024.png" alt="" width="470" height="632" /></p>
<p>I also liked the tips that came out of the discussion. In the end, to understand our customers better, there&#8217;s nothing like engaging with them, whether through surveys, listening to customer care, or examining what they and our competitors are saying about us. This allows us to identify new opportunities for optimization.</p>
<p>He also mentioned <a href="https://usabilityhub.com/" target="_blank" rel="noopener">UsabilityHub</a>. I haven&#8217;t had the time to explore it yet, but I definitely plan to do so.</p>
<h2>How BBC Sport measure their content effectiveness</h2>
<p>The talk given by <a href="https://piano.io/it/" target="_blank" rel="noopener">Piano Analytics</a> addressed a topic that has always been widely debated.</p>
<p>In fact, at the end of the speech, there were several considerations and discussions regarding the effectiveness and results of the method used.</p>
<p>In 2021, BBC Sport decided to help their journalists understand <strong>how to write more engaging content for users</strong>.</p>
<p>They took all their content and grouped it by the number of characters used. Once they identified the median (250 characters), they took data from various studies that indicate <strong>how fast we read and calculated that, on average, a user takes 15 seconds to read a BBC article</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1419" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-1024x687.png" alt="" width="700" height="470" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-1024x687.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-300x201.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-768x515.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-1536x1030.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-2048x1374.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/reading-speed-700x469.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>They then began to collect events that were triggered after 5-10-15 seconds from the start of the user&#8217;s page reading.</p>
<p>They started <strong>monitoring how many users reached the various time thresholds for each article</strong> to understand which articles were actually being read in their entirety by users.</p>
<p>As seen in the chart below, <strong>they also calculated an estimated reading time</strong> next to each article (<em>reading speed x number of characters in the article</em>).</p>
<p>This was done because, naturally, they had articles longer than 250 characters, so analyzing only the first 15 seconds wouldn&#8217;t be sufficient to measure effectiveness.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1396" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-1024x683.png" alt="" width="700" height="467" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-1024x683.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-300x200.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-768x512.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-1536x1024.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-2048x1366.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/content-analysis-piano-700x467.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>In conclusion, they found, for example, that including fan impressions in articles appears to be a topic that greatly interests readers.</p>
<p>And it also seems that they have some very interesting trends regarding the time spent on the website.</p>
<h2>How to audit 300 GTM Containers</h2>
<p><a href="https://www.linkedin.com/in/smonnier/" target="_blank" rel="noopener">Sébastien Monnier</a>&#8216;s speech was also fascinating. He utilized a workflow automation tool called <a href="https://n8n.io/" target="_blank" rel="noopener">N8N</a> (which I haven&#8217;t tested yet, but I&#8217;ll definitely look into it) to download all his containers through GTM&#8217;s APIs and then load them into BigQuery.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1424" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-1024x763.png" alt="" width="700" height="522" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-1024x763.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-300x224.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-768x573.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-1536x1145.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-2048x1527.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2023/10/gtm-checks-700x522.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>By creating daily downloads, he examines what has changed and what isn&#8217;t working so that he can monitor numerous containers simultaneously using straightforward dashboards in Looker Studio.</p>
<p>As usual, a lot of interesting insights and talks. I can&#8217;t wait for this weekend&#8217;s <strong>Measurecamp in Stockholm</strong>.</p>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-london-2023/">MeasureCamp London 2023: my takeaways</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/measurecamp-london-2023/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Some takeaways from MeasureCamp Munich &#038; Snowplow Meetup</title>
		<link>https://www.rubenvezzoli.online/measurecamp-munich-snowplow/</link>
					<comments>https://www.rubenvezzoli.online/measurecamp-munich-snowplow/#respond</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Mon, 26 Jun 2023 22:27:24 +0000</pubDate>
				<category><![CDATA[Web Analytics]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1338</guid>

					<description><![CDATA[<p>Last weekend, I attended the 1st Snowplow Meetup in Munich, followed by MeasureCamp Munich the next day. As always, MeasureCamp far exceeded my expectations, not only in terms of the unconference content but also for the venue where it was held (the Allianz Arena!). I want to share some takeaways and comments about the sessions [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-munich-snowplow/">Some takeaways from MeasureCamp Munich &#038; Snowplow Meetup</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Last weekend, I attended the <strong>1st Snowplow Meetup in Munich</strong>, followed by <strong>MeasureCamp Munich</strong> the next day.</p>
<p>As always, MeasureCamp far <strong>exceeded my expectations,</strong> not only in terms of the unconference content but also for the venue where it was held (the Allianz Arena!).</p>
<div class="flex justify-between lg:block">
<div class="text-gray-400 flex self-end lg:self-center justify-center mt-2 gap-2 md:gap-3 lg:gap-1 lg:absolute lg:top-0 lg:translate-x-full lg:right-0 lg:mt-0 lg:pl-2 visible">
<p>I want to share some takeaways and comments about the sessions I attended.</p>

</div>
</div>
<h2>Web Analytics ≠ Google/Adobe Analytics: rethink your stack</h2>
<p>For many years, <strong>Google Analytics</strong> and <strong>Adobe Analytics</strong> have been the <strong>leaders</strong> in the web analytics market.</p>
<p>However, it is important to remember that <strong>they are also big black boxes and not very flexible solutions</strong>, especially when it comes to collecting behavioural data for <strong>product analytics</strong> and <strong>AI</strong> purposes.</p>
<p>Nicolas explained how and why BurdaForward transitioned from Adobe Analytics (and other solutions) to Snowplow Analytics after a year of work.</p>
<div id="attachment_1349" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1349" class="wp-image-1349 size-large" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe-1024x704.jpg" alt="" width="700" height="481" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe-1024x704.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe-300x206.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe-768x528.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe-700x481.jpg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/Snowplow-vs-Adobe.jpg 1536w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1349" class="wp-caption-text"><a href="https://www.linkedin.com/in/nicolas-ajram-129592a5/" target="_blank" rel="noopener">Nicolas Ajaram</a> talking about BurdaForward migration to SnowPlow</p></div>
<p>He discussed the various <strong>advantages of Snowplow</strong>, such as its flexibility, the ability to enrich data, and having control over the entire process.</p>
<p>Additionally, he highlighted the <strong>responsibilities</strong> that come with it, such as ensuring everything functions properly, managing infrastructure costs, implementing new customizations, and additional steps in the process.</p>
<div id="attachment_1356" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1356" class="wp-image-1356 size-large" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-1024x768.jpeg" alt="" width="700" height="525" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-1024x768.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-300x225.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-768x576.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-1536x1152.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities-700x525.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/snowplow-responsabilities.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1356" class="wp-caption-text"><a href="https://www.linkedin.com/in/nicolas-ajram-129592a5/" target="_blank" rel="noopener">Nicolas Ajaram</a> talking about BurdaForward migration to SnowPlow</p></div>
<p>In this <strong>constantly changing world</strong>, I really liked the presentation made by Alexander Kirtzel about Walker.js.</p>
<p>In this ever-changing world, I thoroughly enjoyed Alexander Kirtzel&#8217;s presentation on Walker.js. According to the official documentation, &#8220;<em>Walker.js is an open library to capture user events and send them to any analytics tool. It was created to enable data ownership, improve web data quality, and scale tracking implementation processes.</em>&#8220;.</p>
<div id="attachment_1353" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1353" class="wp-image-1353 size-large" style="font-size: 15px; font-weight: bold; background-color: transparent;" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-1024x768.jpeg" alt="" width="700" height="525" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-1024x768.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-300x225.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-768x576.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-1536x1152.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2-700x525.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/walker-js-2.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1353" class="wp-caption-text"><a href="https://www.linkedin.com/in/alexanderkirtzel/" target="_blank" rel="noopener">Alexander Kirtzel</a> showing how Walker.js works</p></div>
<p>I appreciate the concept of a <strong>vendor-agnostic solution</strong> that prioritizes the definition and delivery of superior data to any analytics provider.</p>
<p>I&#8217;ll definitely look into it as I believe it holds the potential to be a future-proof solution.</p>
<h2>Changing technology is easy, changing people is hard</h2>
<p>The <strong>difficulty of adapting to new solutions and changing established habits</strong> (GA4 I&#8217;m looking at you) has been a prominent and widely discussed topic during different sessions.</p>
<p>For instance, Snowplow lacks a user interface, which prompted BurdaForward to invest efforts in implementing and customizing Apache Superset, a data visualization platform.</p>
<p>This was done to ensure a certain level of data democracy across the organization and assist data analysts in conducting their daily analyses seamlessly.</p>
<div id="attachment_1357" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1357" class="wp-image-1357 size-large" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-1024x768.jpeg" alt="" width="700" height="525" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-1024x768.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-300x225.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-768x576.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-1536x1152.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key-700x525.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/humans-are-key.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1357" class="wp-caption-text"><a href="https://www.linkedin.com/in/nicolas-ajram-129592a5/" target="_blank" rel="noopener">Nicolas Ajaram</a> talking about BurdaForward migration to SnowPlow</p></div>
<p>Archit Goyal delivered an insightful presentation on the <strong>essential role of web analysts in building successful AI models</strong>.</p>
<p>A significant point of discussion revolved also around the <strong>lack of communication between web analysts and data scientists</strong> in many companies.</p>
<p>Web analysts often possess a <strong>deeper understanding of the data that should be incorporated into the models</strong> and have extensive expertise in the field. As you can see in the picture below, it has been observed that data scientists often do not frequently change the factors they utilize in their AI model development. This practice is problematic since it often overlooks valuable behavioural data, focusing solely on purchase data.</p>
<p>In conclusion, fostering better <strong>collaboration between web analysts and data scientists is crucial for leveraging their combined knowledge</strong> and optimizing AI model development.</p>
<div id="attachment_1359" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1359" class="wp-image-1359 size-large" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-1024x768.jpeg" alt="" width="700" height="525" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-1024x768.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-300x225.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-768x576.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-1536x1152.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist-700x525.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/data-scientist.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1359" class="wp-caption-text"><a href="https://www.linkedin.com/in/hello-archit-goyal/" target="_blank" rel="noopener">Archit Goyal</a> talking why Web Analysts should be always involved in AI projects</p></div>
<h2>The era of &#8220;track everything&#8221; has come to an end</h2>
<p>Last but not least, probably the hottest topic of the last few years. AdBlockers, Cookie Rejection, ITP,&#8230; are impacting the quantity and quality of the data you can collect.</p>
<div id="attachment_1373" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1373" class="wp-image-1373 size-large" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932-1024x706.jpeg" alt="" width="700" height="483" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932-1024x706.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932-300x207.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932-768x530.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932-700x483.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/too-many-problems-e1687816198932.jpeg 1536w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1373" class="wp-caption-text"><a href="https://www.linkedin.com/in/steenrasmussen/" target="_blank" rel="noopener">Steen Rasmussen</a> &#8211; <em>&#8220;The Decision Economy&#8221;</em></p></div>
<p>The era where &#8220;everything&#8221; is trackable has come to an end, you need to <strong>focus more on defining business objectives and the specific decisions you aim to address</strong>.</p>
<p><strong>Marketing-Mix Modeling</strong>, <strong>incrementality testing</strong>, and <strong>attribution</strong> are widely discussed and relevant instruments but it is crucial to complement these tools with real customer feedback.</p>
<p>Finding similarities among customer feedback, Marketing-Mix Modeling (MMM), and attribution can serve as evidence of specific behaviors occurring.</p>
<div id="attachment_1370" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1370" class="size-large wp-image-1370" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-1024x768.jpeg" alt="" width="700" height="525" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-1024x768.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-300x225.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-768x576.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-1536x1152.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond-700x525.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/attribution-james-bond.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1370" class="wp-caption-text"><a href="https://www.linkedin.com/in/simonrumble/" target="_blank" rel="noopener">Simon Rumble</a> &#8211; <em>&#8220;Attribution is (still) bullshit&#8221;</em></p></div>
<p>During the event, Steen Rasmussen presented an interesting slide about <strong>the decay of the business value of data over time</strong>.</p>
<p>For instance, he highlighted the fact that everyone is trying to get all of the data out of GA3, despite the fact that much of it may not be utilized due to constantly changing customer behaviours and market conditions.</p>
<p>In summary, the ability to swiftly collect and utilize data is key if you want to maximize its business value.</p>
<div id="attachment_1377" style="width: 710px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-1377" class="size-large wp-image-1377" src="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-1024x841.jpeg" alt="" width="700" height="575" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-1024x841.jpeg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-300x246.jpeg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-768x630.jpeg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-1536x1261.jpeg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time-700x575.jpeg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2023/06/understanding-time.jpeg 2048w" sizes="auto, (max-width: 700px) 100vw, 700px" /><p id="caption-attachment-1377" class="wp-caption-text"><a href="https://www.linkedin.com/in/steenrasmussen/" target="_blank" rel="noopener">Steen Rasmussen</a> &#8211; <em>&#8220;The Decision Economy&#8221;</em></p></div>
<p>The post <a href="https://www.rubenvezzoli.online/measurecamp-munich-snowplow/">Some takeaways from MeasureCamp Munich &#038; Snowplow Meetup</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/measurecamp-munich-snowplow/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Search and Replace Filter in GA4 using GTM</title>
		<link>https://www.rubenvezzoli.online/search-replace-ga4-gtm/</link>
					<comments>https://www.rubenvezzoli.online/search-replace-ga4-gtm/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Thu, 30 Jun 2022 19:01:21 +0000</pubDate>
				<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[Google Tag Manager]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1274</guid>

					<description><![CDATA[<p>At the time of writing this article, the Search and Replace function is not available in the new GA4 and that is why I decided to write this guide and show you a workaround I&#8217;ve recently used. A couple of days ago, I was analysing a GA4 property and I noticed that it was receiving [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/search-replace-ga4-gtm/">Search and Replace Filter in GA4 using GTM</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>At the time of writing this article, the <span class="code">Search and Replace</span> function is <strong>not available in the new GA4</strong> and that is why I decided to write this guide and show you a workaround I&#8217;ve recently used.</p>
<p>A couple of days ago, I was analysing a GA4 property and I noticed that <strong>it was receiving a lot of traffic from many different referrals</strong>.</p>
<p>After some further analysis, I realised that many of those referrals were from the same website but with different subdomains or a port number at the end.</p>
<p>Just to give you an idea of what I mean you can see two examples below:</p>
<div align="center">

<img loading="lazy" decoding="async" width="356" height="342" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/facebook-referrals.jpg" class="attachment-large size-large" alt="" columns="2" link="none" size="large" ids="1294,1295" orderby="post__in" include="1294,1295" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/facebook-referrals.jpg 356w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/facebook-referrals-300x288.jpg 300w" sizes="auto, (max-width: 356px) 100vw, 356px" />
<img loading="lazy" decoding="async" width="358" height="382" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/yahoo-referrals.jpg" class="attachment-large size-large" alt="" columns="2" link="none" size="large" ids="1294,1295" orderby="post__in" include="1294,1295" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/yahoo-referrals.jpg 358w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/yahoo-referrals-281x300.jpg 281w" sizes="auto, (max-width: 358px) 100vw, 358px" />

</div>
<p>I had also an extreme case with hundreds of different values for the same referrer.</p>
<p>This is not good, especially in <strong>GA4, where it&#8217;s important to have a low <span class="code">cardinality </span></strong>(<em>total number of unique values for a dimension</em>) <strong>in order to avoid aggregated reports</strong> (<em>the (other) row</em>).</p>
<div align="center">
<blockquote class="twitter-tweet" data-conversation="none">
<p dir="ltr" lang="en">GA3/Universal gives you the top 50k rows and aggregates everything after ( row 50,001+). That meant the report was still useful for quickly figuring out the top combinations of anything.</p>
<p>GA4 doesn&#8217;t seem to be doing that, so aggregated reports seem to no longer be directional.</p>
<p>— Charles Farina (@CharlesFarina) <a href="https://twitter.com/CharlesFarina/status/1517224598642696192?ref_src=twsrc%5Etfw">April 21, 2022</a></p></blockquote>
<p><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></p>
</div>
<h2>My solution</h2>
<p>My goal was to <strong>consolidate some referrals</strong> for better reporting and lower the risk of data aggregation.</p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-1312 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/referral-consolidation-ga4.jpg" alt="" width="758" height="333" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/referral-consolidation-ga4.jpg 758w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/referral-consolidation-ga4-300x132.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/referral-consolidation-ga4-700x308.jpg 700w" sizes="auto, (max-width: 758px) 100vw, 758px" /></p>
<p>Luckily, <span class="code">page_referrer</span> is one of the <a href="https://developers.google.com/analytics/devguides/collection/ga4/reference/config" target="_blank" rel="noopener">fields</a> that you can set in a GA4 tag in order to override the default value.</p>
<p>I used a <strong>RegEx Table variable</strong> to mimic the <strong>Search and Replace</strong> filter function. I selected <span class="code">{{Referrer}}</span> as my <span class="code">Input Variable</span> and added some regular expressions and the desired outputs as you can see below.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1280" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4-1024x661.jpg" alt="" width="700" height="452" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4-1024x661.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4-300x194.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4-768x496.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4-700x452.jpg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/regex-table-referrer-ga4.jpg 1194w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>In my case, I disabled the options <span class="code">Full Matches Only</span> and <span class="code">Enable Capture Groups and Replace Functionality</span> because I just wanted to match my regex anywhere in the value but it might not work in your case, so you should read very carefully the two information boxes.</p>
<p>Afterwards, I updated my GA4 Configuration Tag. I added page_referrer to the <span class="code">Fields to Set</span> list and used my RegExp Table as a <span class="code">Value</span> variable. <img loading="lazy" decoding="async" class="alignnone size-large wp-image-1281" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer-1024x657.jpg" alt="" width="700" height="449" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer-1024x657.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer-300x192.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer-768x493.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer-700x449.jpg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2022/06/ga4-configuration-tag-page_referrer.jpg 1135w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>This solution works with all the fields you can find on this <a href="https://developers.google.com/analytics/devguides/collection/ga4/reference/config" target="_blank" rel="noopener">list</a>. For example, you could remove a specific directory from all the page URLs.</p>
<p>The post <a href="https://www.rubenvezzoli.online/search-replace-ga4-gtm/">Search and Replace Filter in GA4 using GTM</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/search-replace-ga4-gtm/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Piwik Consent Manager integration with GTM and Google Consent Mode</title>
		<link>https://www.rubenvezzoli.online/piwik-consent-manager-consent-mode-gtm/</link>
					<comments>https://www.rubenvezzoli.online/piwik-consent-manager-consent-mode-gtm/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Sun, 15 May 2022 22:22:59 +0000</pubDate>
				<category><![CDATA[Google Tag Manager]]></category>
		<category><![CDATA[Web Analytics]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1238</guid>

					<description><![CDATA[<p>Lately, I&#8217;ve been working on the integration of Piwik Consent Manager with Google Tag Manager and Google Consent Mode API (using Simo Ahava&#8217;s template). It hasn&#8217;t been a straightforward process also because Piwik&#8217;s documentation is a bit outdated 😉 and that&#8217;s why I&#8217;m writing this post where I want to describe my own solution. Disclaimer [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/piwik-consent-manager-consent-mode-gtm/">Piwik Consent Manager integration with GTM and Google Consent Mode</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Lately, I&#8217;ve been working on the <strong>integration of Piwik Consent Manager with Google Tag Manager</strong> and <a href="https://developers.google.com/tag-platform/devguides/consent" target="_blank" rel="noopener">Google Consent Mode API</a> (using <a href="https://www.simoahava.com/custom-templates/consent-mode/" target="_blank" rel="noopener">Simo Ahava&#8217;s template</a>).</p>
<p>It hasn&#8217;t been a straightforward process also because Piwik&#8217;s documentation is a bit outdated <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> and that&#8217;s why I&#8217;m writing this post where I want to describe my own solution.</p>
<p>Disclaimer &#8211; If you want to fully understand this post, you have to know Consent Mode API and how they work. If you never used them, you should read the documentation I linked above.</p>
<h2>How does Piwik&#8217;s Consent Banner work?</h2>
<p>First of all, let&#8217;s analyze the <strong>Piwik&#8217;s consent banner</strong> (in this post, I won&#8217;t describe how to set up and implement Piwik Consent Manager). Every time a new user lands on the website a cookie <span class="code">ppms_privacy_YOUR_WEBSITE_ID</span> is created. Inside the cookie, Piwik stores the user consent choices using 3 digits:</p>
<ul>
<li><strong>-1</strong> = the user <strong>has not yet</strong> given consent</li>
<li><strong>0</strong> = the user <strong>has not</strong> given consent</li>
<li><strong>1</strong> = the user <strong>has given</strong> consent</li>
</ul>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1241" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-1024x318.png" alt="" width="700" height="217" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-1024x318.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-300x93.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-768x238.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-1536x477.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-2048x636.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/1-piwik-consent-cookie-700x217.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>In order to use them, you have to create a variable which stores the information and then pass them to the Consent Mode API.</p>
<h2>1. Store Consent Choices in a 1st party Cookie variable</h2>
<p>In GTM, you have to create a new <strong>1st-Party Cookie</strong> variable and paste your <span class="code">ppms_privacy_YOUR_WEBSITE_ID</span>. Also, tick the option <strong>URI-decode cookie</strong>. <img loading="lazy" decoding="async" class="alignnone size-large wp-image-1243" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-1024x479.png" alt="" width="700" height="327" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-1024x479.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-300x140.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-768x359.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-1536x718.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-2048x958.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/3-piwik-consent-variable-700x327.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<h2>2. Read the cookie with Custom JavaScript variables</h2>
<p><strong>Google Consent Mode API</strong> doesn&#8217;t work with -1, 0, 1 but the words <strong>granted</strong> and <strong>denied</strong>. You have to create 3 <span class="code">custom JavaScript variables</span>, one for each consent.</p>
<p>In the script below, parse the Cookie variable you created earlier, read the status of a specific consent (the example reads analytics consent) and returns <strong>granted</strong> or <strong>denied</strong> according to the number stored inside the cookie.</p>
<ul>
<li>-1 = denied</li>
<li>0 = denied</li>
<li>1 = granted</li>
</ul>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1242" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-1024x695.png" alt="" width="700" height="475" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-1024x695.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-300x204.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-768x521.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-1536x1042.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-2048x1389.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/2-customjs-variable-700x475.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p><pre class="urvanov-syntax-highlighter-plain-tag">// Analytics Consent
function () {
var cookie = {{Piwik - Consent Cookie}};
if(!cookie){return 'denied'}
var json = JSON.parse(cookie)

if (json['consents']['analytics']['status'] == 1) {

 	return 'granted' 
  
	} else {

 	return 'denied'

	}
}

// Remarketing/Adv Consent
function () {
var cookie = {{Piwik - Consent Cookie}};
if(!cookie){return 'denied'}
var json = JSON.parse(cookie)

if (json['consents']['remarketing']['status'] == 1) {

 	return 'granted' 
  
	} else {

 	return 'denied'

	}
}

// A/B Testing and Personalization Consent
function () {
var cookie = {{Piwik - Consent Cookie}};
if(!cookie){return 'denied'}
var json = JSON.parse(cookie)

if (json['consents']['ab_testing_and_personalization']['status'] == 1) {

 	return 'granted' 
  
	} else {

 	return 'denied'

	}
}</pre><p></p>
<h2>3. Build a trigger that fires when the user makes/updates his consent choices</h2>
<p>If you want to use Consent Mode, you have to be sure to update the consent choices every time the user changes his consent.</p>
<p>Luckily, you can use an <strong>event</strong> called <span class="code">stg.consentsWereSent </span>that Piwik Consent Manager pushes to the <strong>dataLayer</strong> when the user makes his choice.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1244" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-1024x457.png" alt="" width="700" height="312" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-1024x457.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-300x134.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-768x343.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-1536x686.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-2048x914.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/4-consent-sent-700x313.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>You have to create a <span class="code">Custom Event</span> which will fires whenever the user interacts with the consent banner or the <em>&#8220;Change Consent Options&#8221;</em> button.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1245" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-1024x503.png" alt="" width="700" height="344" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-1024x503.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-300x147.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-768x377.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-1536x754.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-2048x1006.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/5-custom-event-consent-sent-700x344.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<h2>4. Update Consent Mode API using Simo Ahava&#8217;s template</h2>
<p>At this point, you are ready to activate and set up Simo Ahava&#8217;s <strong>Consent Mode template</strong>. Go to the Template Gallery and search for Consent Mode (Google tags).</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1246" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-1024x567.png" alt="" width="700" height="388" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-1024x567.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-300x166.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-768x425.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-1536x851.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-2048x1135.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/6-consent-mode-template-700x388.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>Then you should create two Consent Mode tags, one with the <span class="code">Default</span> consent command that will be fired on every page. And a second tag with the <span class="code">Update</span> consent command that is fired on the dataLayer event <strong>stg.consentsWereSent </strong><em>(when the user makes his choice)</em>.</p>
<p>Inside the tags, you also have to use the custom JavaScript we created earlier. They&#8217;ll pass the user choice to the Consent Mode API.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1247" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-1024x751.png" alt="" width="700" height="513" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-1024x751.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-300x220.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-768x563.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-1536x1126.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-2048x1501.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/7-consent-mode-tag-700x513.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>And that&#8217;s it! You are done with this tutorial.</p>
<p>If you want, you can also combine the custom JavaScript variables with the dataLayer event to fire tags right after the user gave consent to analytics or advertising, this is quite important if you don&#8217;t want to lose the first pageview <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1270" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-1024x502.png" alt="" width="700" height="343" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-1024x502.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-300x147.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-768x377.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-1536x754.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-2048x1005.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/05/8-consent-trigger-700x343.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>The post <a href="https://www.rubenvezzoli.online/piwik-consent-manager-consent-mode-gtm/">Piwik Consent Manager integration with GTM and Google Consent Mode</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/piwik-consent-manager-consent-mode-gtm/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How to use Google Search Console URL Inspection API with R</title>
		<link>https://www.rubenvezzoli.online/search-console-inspection-api-r/</link>
					<comments>https://www.rubenvezzoli.online/search-console-inspection-api-r/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Tue, 01 Feb 2022 23:39:24 +0000</pubDate>
				<category><![CDATA[R Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1193</guid>

					<description><![CDATA[<p>A couple of days ago, Google announced the release of a new Google Search Console API called URL Inspection API. The URL Inspection API are a good way to access URL-level data outside of the Google Search Console interface. It provides different information like: date of the last crawl indexing status canonical tag mobile-friendliness structured [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/search-console-inspection-api-r/">How to use Google Search Console URL Inspection API with R</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>A couple of days ago, Google announced the release of a new <strong>Google Search Console API called URL Inspection API</strong>.</p>
<p><img loading="lazy" decoding="async" class="wp-image-1210 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/google-inspection-api-announcement-1024x337.png" alt="" width="578" height="197" /></p>
<p>The URL Inspection API are a good way to <strong>access URL-level data outside of the Google Search Console interface</strong>. It provides different information like:</p>
<ul>
<li>date of the last crawl</li>
<li>indexing status</li>
<li>canonical tag</li>
<li>mobile-friendliness</li>
<li>structured data</li>
<li>&#8230;</li>
</ul>
<p>If you want to know more about the Inspection API I recommend you to read the <a href="https://developers.google.com/search/blog/2022/01/url-inspection-api" target="_blank" rel="noopener">official documentation</a>.</p>
<p>In this post, I&#8217;m going to show you <strong>how to access the URL Inspection API using R</strong>. This tutorial is quite similar to the one I wrote about <a href="https://www.rubenvezzoli.online/indexing-api-googleauthr/">Google Indexing API in R.</a></p>
<h2>How to generate Google URL Inspection API credentials</h2>
<p>The code that I&#8217;m going to show you only work if you activate the <a href="https://www.rubenvezzoli.online/google-search-console-api-r-studio/">Google Search Console API</a> and generate a <span class="code">client id</span> and <span class="code">client secret</span>.</p>
<p>Open the <a href="https://console.developers.google.com/apis" target="_blank" rel="noopener">Google API Console</a> and search &#8220;Google Search Console API&#8221; in the APIs library and then you have to <strong>enable the API</strong>.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-1197 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-1-1024x473.png" alt="" width="555" height="263" /></p>
<p>Then go to the <strong>Credentials</strong> section where you&#8217;ll be able to generate your credentials. Click on <strong>Create Credentials </strong>and choose the <strong>OAuth client ID</strong> option. <img loading="lazy" decoding="async" class=" wp-image-1198 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-2-1024x485.png" alt="" width="555" height="269" /></p>
<p>Select <strong>Desktop App</strong> and choose the name you want.<img loading="lazy" decoding="async" class=" wp-image-1199 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-3-1024x806.png" alt="" width="554" height="439" /></p>
<p>Now, you should have a popup on your screen showing your <span class="code">client id</span> and <span class="code">client secret</span> credentials.<img loading="lazy" decoding="async" class=" wp-image-1200 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-4-1024x964.png" alt="" width="554" height="523" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-4-1024x964.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-4-300x282.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-4-768x723.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/credentials-4-700x659.png 700w" sizes="auto, (max-width: 554px) 100vw, 554px" /></p>
<h2>The R code for the URL Inspection API</h2>
<p>My R code uses as input a .<strong>csv file</strong> like the one you see below. I decided to use it because I know that many <a href="https://www.rubenvezzoli.online/seo/">SEO</a>s are not familiar with R and they prefer to work with Excel / CSV files.</p>
<p>But if you know how R works you can directly use a vector containing all the URLs you want to analyze.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-1201 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/urls-list.png" alt="" width="554" height="218" /></p>
<p>Let&#8217;s not forget that the <strong>URL Inspection API has a limit of 2,000 queries per day!</strong></p>
<p>Once I ran for the first time the R code, I realized that in the response of the API there are 3 different types of information:</p>
<ul>
<li><span class="code">indexStatusResult</span> &#8211; which contains the information about the last crawl, canonical tag, indexing status, sitemap,&#8230;</li>
<li><span class="code">mobileUsabilityResult</span> &#8211; which contains the result of the mobile usability test</li>
<li><span class="code">richResultsResult</span> &#8211; which returns all the structured data implemented on that url</li>
</ul>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1216 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-1024x245.jpg" alt="" width="700" height="167" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-1024x245.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-300x72.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-768x184.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-1536x368.jpg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api-700x168.jpg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/url-inspection-api.jpg 1830w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>In my case, I decided that I wanted as output only the first &#8220;sub-report&#8221; <span class="code">indexStatusResult</span>.</p>
<p>The code below accepts in input a .csv file of URLs, <strong>if you want to use it you have to replace the 4 placeholders you find in the code</strong>:</p>
<ul>
<li><span class="code">client id</span></li>
<li><span class="code">client secret</span></li>
<li><span class="code">siteURL</span> &#8211; the name of your Google Search Console Property e.g. https://www.mydomain.com/</li>
<li><span class="code">languageCode</span> &#8211; in which language you want the output</li>
</ul>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag"># LAST UPDATE: 2022-02-01
# Install &amp; Load the packages

install.packages("googleAuthR")
install.packages("tidyverse")
install.packages("readr")

library("googleAuthR")
library("tidyverse")
library("readr")

# Set credentials and scope

clientId &lt;- "PASTE HERE YOUR CLIENT ID"
clientSecret &lt;- "PASTE HERE YOUR CLIENT SECRET" 
scope &lt;- "https://www.googleapis.com/auth/webmasters"

options("googleAuthR.client_id" = clientId, 
        "googleAuthR.client_secret" = clientSecret, 
        "googleAuthR.scopes.selected" = scope,
        "googleAuthR.verbose" = 0 # Not mandatory - I just use it to debug the script
)

# Google API OAuth

gar_auth()

# List of URLs - Daily Limit of 2,000 queries per day 

urls &lt;- read_csv("~/Desktop/Your-file-name.csv")
urls &lt;- urls[ ,1]

# get_inspection_api function - you can use the function to send requestes to the inspection API using urls vector as an input
# It also GET the response from the API and stores it in a data frame

get_inspection_api &lt;- function(page) {
  
  body &lt;-  list(inspectionUrl = page,
                siteUrl = "PASTE HERE YOUR SEARCH CONSOLE PROPERTY NAME", #e.g. https://www.mydomain.com/ 
                languageCode = "it-IT" # CHANGE IT WITH YOUR LANGUAGE CODE
                )
  
  f &lt;- gar_api_generator("https://searchconsole.googleapis.com/v1/urlInspection/index:inspect",
                         "POST")
  
  result &lt;- f(the_body = body)
  result &lt;- data.frame(result[[6]][[1]][[2]])
  
  return(result)
  
}

# The API responses are stored in a data frame

api_response &lt;- map_dfr(.x = urls,
                        .f = get_inspection_api
                        )

# You can download the API response as .csv file

write.csv(api_response, "Your-file-name.csv")</pre><p>And this is an example of the output you can get from the URL Inspection API with some of the columns.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1219" src="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-1024x110.png" alt="" width="700" height="75" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-1024x110.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-300x32.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-768x83.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-1536x166.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-2048x221.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2022/02/inspection-api-output-700x75.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>The post <a href="https://www.rubenvezzoli.online/search-console-inspection-api-r/">How to use Google Search Console URL Inspection API with R</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/search-console-inspection-api-r/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>How to run an N-Gram analysis even when Google Ads hides the data</title>
		<link>https://www.rubenvezzoli.online/ngram-analysis-google-ads/</link>
					<comments>https://www.rubenvezzoli.online/ngram-analysis-google-ads/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Mon, 15 Nov 2021 23:37:19 +0000</pubDate>
				<category><![CDATA[Google Analytics]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1159</guid>

					<description><![CDATA[<p>If you are familiar with Google Ads, you probably know that Google likes to change quite often how the platform works and which data they provide through it. In particular, last year, Google released an update that had a huge impact on all the search advertisers. Since then, they are basically hiding part of the [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/ngram-analysis-google-ads/">How to run an N-Gram analysis even when Google Ads hides the data</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>If you are familiar with <strong>Google Ads</strong>, you probably know that Google likes to change quite often how the platform works and which data they provide through it.</p>
<p>In particular, last year, Google released an update that had a huge impact on all the search advertisers. Since then, they are basically <strong>hiding part of the search queries that triggered a search campaign on Google</strong>.</p>
<p>As you can see in the screenshot below, they added at the end of the search terms report an extra row called <strong>&#8220;Other search terms&#8221;</strong> where they provide costs, clicks, conversions,&#8230; but not the text of the search queries.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1160 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms-1024x200.png" alt="" width="700" height="137" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms-1024x200.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms-300x59.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms-768x150.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms-700x137.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-ads-hidden-search-terms.png 1290w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>This is a big issue for many advertisers because <strong>this &#8220;hidden group&#8221; can go up to 60-70% of all the search queries data</strong> and this information is very useful when you are optimizing a campaign and especially when you want to run <strong>an N-gram analysis</strong>.</p>
<p>In this post, I want to share an idea I had a couple of days ago and that can help you to still run an N-gram analysis on 100% of your search queries data.</p>
<h2>Search queries report in Google Analytics</h2>
<p>If you connected your Google Ads Account to Google Analytics, you should be able to see part of your Google Ads data in Google Analytics.</p>
<p>Especially, if you look at the <strong>search queries report</strong> you&#8217;ll notice that there are some search queries that generated sessions, conversions but that don&#8217;t have clicks and costs data.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1162" src="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-1024x487.jpg" alt="" width="700" height="333" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-1024x487.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-300x143.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-768x365.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-1536x731.jpg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-2048x974.jpg 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/google-analytics-hidden-keywords-700x333.jpg 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>If we want to run an N-gram analysis we have to use the Google Analytics data because it&#8217;s the only report where we still have all the search queries. The problem is that <strong>we need to know how many clicks and costs the hidden queries generated</strong>, otherwise, we would take into account all the conversions but not the costs generated by those queries.</p>
<h2>How to estimate clicks and costs for the hidden search terms</h2>
<p>If we look at the data we have, we know that for the known queries is not a problem we have everything we need.</p>
<p>But for the unknown queries, we only know how many sessions and conversions they generated. <strong>Clicks and Costs on a search term level are missing</strong>.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1170 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-1024x511.png" alt="" width="700" height="349" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-1024x511.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-300x150.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-768x384.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-1536x767.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries-700x350.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/hidden-queries.png 1602w" sizes="auto, (max-width: 700px) 100vw, 700px" />The only way I see to attribute costs and clicks to the hidden search queries is to take costs and clicks from the &#8220;Other search terms&#8221; row (either for a specific Ad Group or Keyword) and <strong>use the % of sessions that a specific search term generated as a &#8220;weight&#8221;</strong>.</p>
<p>I have chosen to use the sessions because it&#8217;s the closest metric to clicks. <img loading="lazy" decoding="async" class="alignnone size-large wp-image-1175" src="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-1024x356.png" alt="" width="700" height="243" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-1024x356.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-300x104.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-768x267.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-1536x534.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations-700x243.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2021/11/estimations.png 1658w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>In the example, I took as an example the hidden search terms for the keyword &#8220;google merchandise&#8221;. In total, the queries generated 32 sessions, 10,213 clicks and 253,049.46€ costs.</p>
<p>The search term &#8220;google merchandise home&#8221; generated 15,63% of the 32 sessions and that&#8217;s why it gets 1,596 clicks and 39,538.98€ costs.</p>
<h2>Conclusion</h2>
<p>I&#8217;m currently working on the R code that will automate the whole process and maybe I&#8217;ll share it later on.</p>
<p>I know that especially <strong>nowadays Google CPCs on search term level can vary a lot but we have to work with the data we have</strong> and I don&#8217;t see a way to attribute a CPC that is not an average but please let me know your opinion in the comments below.</p>
<p>The post <a href="https://www.rubenvezzoli.online/ngram-analysis-google-ads/">How to run an N-Gram analysis even when Google Ads hides the data</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/ngram-analysis-google-ads/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
			</item>
		<item>
		<title>How to query Google Analytics 4 data in BigQuery</title>
		<link>https://www.rubenvezzoli.online/google-analytics-4-big-query/</link>
					<comments>https://www.rubenvezzoli.online/google-analytics-4-big-query/#respond</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Tue, 24 Nov 2020 23:40:54 +0000</pubDate>
				<category><![CDATA[Google Analytics]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=1003</guid>

					<description><![CDATA[<p>Last month, Google announced the release of Google Analytics 4 (also known as App + Web property), which is basically a &#8220;new&#8221; version of the famous web analytics software. In this post, I won&#8217;t talk about the differences between the old Google Analytics (Universal Analytics) and GA4 because it&#8217;s still a beta version and they [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/google-analytics-4-big-query/">How to query Google Analytics 4 data in BigQuery</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Last month, Google <a href="https://blog.google/products/marketingplatform/analytics/new_google_analytics/">announced</a> the release of <strong>Google Analytics 4</strong> (also known as <strong>App + Web property</strong>), which is basically a &#8220;new&#8221; version of the famous web analytics software.</p>
<p>In this post, I won&#8217;t talk about the <strong>differences between the old Google Analytics (Universal Analytics) and GA4</strong> because it&#8217;s still a beta version and they are releasing every day new features. So, if you want to know all the new features of GA4 you should read <a href="https://support.google.com/analytics/answer/9964640?hl=en&amp;ref_topic=9303319" target="_blank" rel="noopener noreferrer">this post</a>.</p>
<p>Instead, I&#8217;ll try to cover all the <strong>basic aspects you should know</strong> if you want to start to <strong>analyze Google Analytics raw data</strong> that you can import (for free) in BigQuery.</p>

<p>This post is mainly for people with a basic knowledge of SQL and understanding of how a relational database works.</p>
<h2>An overview of the Google BigQuery GUI</h2>
<p>In order to get started, you have to <strong>connect Google Analytics and Google Big Query</strong>, <a href="https://support.google.com/analytics/answer/3416092?hl=en" target="_blank" rel="noopener noreferrer">here you can find the official documentation</a> which will guide you through the setup process.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1017 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-1024x424.png" alt="Google BigQuery UI" width="700" height="290" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-1024x424.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-300x124.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-768x318.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-1536x636.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui-700x290.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigQuery-gui.png 1774w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>After the initial setup, you should be able to access the <strong>BigQuery interface</strong>. On the left there is a sidebar where you&#8217;ll find:</p>
<ul>
<li><strong>Query history</strong>: where you can find all the queries you ran in the past</li>
<li><strong>Saved queries</strong>: if you don&#8217;t want to lose your queries, you can save them in the Saved queries section</li>
<li><strong>Scheduled queries</strong>: of course, you can also schedule a query and run it every day, week,&#8230;</li>
<li><strong>Resources</strong>: in this section, you&#8217;ll find all your projects. In each <strong>project</strong>, you&#8217;ll find one or more dataset and in each <strong>dataset</strong>, you&#8217;ll find one or more <strong>tables</strong></li>
</ul>
<p>While in the main section of the console you can find:</p>
<ul>
<li><strong>SQL editor</strong>: where you&#8217;ll write the SQL queries. But you&#8217;ll also be able to save, schedule and format your code</li>
<li><strong>Output &amp; dataset details</strong>: the last section of the interface contains the output area where you&#8217;ll be able to check the output of your queries but at the same time find more details about you tables (e.g. field names, dataset names, table size,&#8230;)</li>
</ul>
<h2>Google Analytics 4 export schema &amp; first queries</h2>
<p>As I said before, you can&#8217;t work with BigQuery if you don&#8217;t know a bit of SQL. So if you&#8217;ve never used it my advice is to read a guide about <a href="https://www.w3schools.com/sql/" target="_blank" rel="noopener noreferrer">the basics of SQL</a>.</p>
<p>In the BigQuery interface, you should also be able to see all your <span class="code">BigQuery projects</span> with inside multiple <span class="code">datasets</span> (one for each Google Analytics property you&#8217;ve connected).</p>
<p>Inside each dataset, you&#8217;ll find multiple <span class="code">tables</span>,  that happens because of the Google Analytics export which split the events data by day, meaning that <strong>every single table contains only the data collected during a specific day</strong>.<img loading="lazy" decoding="async" class="size-full wp-image-1032 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/google-analytics-raw-data-tables.jpg" alt="" width="313" height="300" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/google-analytics-raw-data-tables.jpg 313w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/google-analytics-raw-data-tables-300x288.jpg 300w" sizes="auto, (max-width: 313px) 100vw, 313px" /></p>
<p>And that&#8217;s why I want to show how to query multiple table at the same time.</p>
<h3>Query multiple Google Analytics 4 tables</h3>
<p>As you can see in the code below, you can <strong>query multiple tables</strong> in three different ways.</p>
<p>You can choose a <strong>static date range</strong> (e.g. 2020-10-01 / 2020-10-15), which is recommended if you are writing a query that you&#8217;ll only use once. Or, you can use a <strong>dynamic date range</strong> like &#8220;Last 30 days&#8221; which is quite often used for reports or scheduled queries.</p>
<p>You can also <strong>mix the first two methods</strong> and have a dynamic and static date range.</p><pre class="urvanov-syntax-highlighter-plain-tag">-- Option 1 - Static date range
SELECT *
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20201101' AND '20201114';

-- Option 2 - Flexible date range (e.g. Last 30 days - Yesterday)
SELECT *
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
      AND FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY));

-- Option 3 - A mix of static and flexible date range
SELECT *
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20201001'
      AND FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY));</pre><p>The last thing you should know about BigQuery before writing your first lines of SQL is how to deal with <strong>repeated records</strong>.</p>
<h3>Handle nested fields / repeated records</h3>
<p><strong>Repeated records</strong>? What? Of course, I&#8217;ll try to quickly explain it with my own words, but, if you want to know everything about <strong>nested fields / repeated records</strong>, you should read <a href="https://medium.com/firebase-developers/using-the-unnest-function-in-bigquery-to-analyze-event-parameters-in-analytics-fb828f890b42">this post</a> written by the Firebase team.</p>
<p>If you are familiar with Excel or databases, you probably know that a table has rows and columns and inside each unit (cell) there is a single piece of information.</p>
<p><img decoding="async" class="aligncenter" src="https://miro.medium.com/max/1080/1*bkfEsxe1LJaxZiVpzUg8Sw.png" alt="excel sheet classic structure" /></p>
<p>Well, Google Analytics data are organized in a slightly different way (because it&#8217;s more efficient). The <strong>structure</strong> of the Google Analytics tables <strong>looks like a JSON</strong>, which means that <strong>a column can contain a single piece of information but as well an array</strong> (a list) of values.</p>
<p><img decoding="async" class="aligncenter" src="https://miro.medium.com/max/1080/1*z9A7YnfniVxFy9ccnGpV7A.png" alt="excel sheet classic structure" /></p>
<p>So you&#8217;ll have to know how to flatten a nested field in order to be able to query the table.</p>
<p>For example, the column <span class="code">event_params</span> is a repeated record because inside it contains the value event_params.key, event_params.value,&#8230; .</p>
<p><img loading="lazy" decoding="async" class="wp-image-1055 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/repeated-fields-big-query.png" alt="" width="531" height="308" /></p>
<p>And if you open the table preview, you&#8217;ll see something like that:</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1074 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-1024x142.png" alt="" width="700" height="97" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-1024x142.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-300x42.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-768x107.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-1536x214.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-2048x285.png 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/bigquery-nested-field-700x97.png 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>Let&#8217;s say that you want to filter the table to get only the rows where the <span class="code">page_referrer</span> is &#8220;https://www.google.it&#8221;.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_date, event_timestamp, event_name, page_referrer
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20201101' AND '20201121' 
      AND event_name = 'first_visit'
      AND page_referrer = 'https://www.google.it';</pre><p><img loading="lazy" decoding="async" class="size-large wp-image-1058 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-1024x48.png" alt="" width="700" height="33" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-1024x48.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-300x14.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-768x36.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-1536x72.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query-700x33.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnest-field-big-query.png 2014w" sizes="auto, (max-width: 700px) 100vw, 700px" />If you run the query, you&#8217;ll get an error message because your <span class="code">WHERE</span> condition is using page_referrer which is nested inside the column event_param.</p>
<p>If you want to use page_referrer you have to first <strong>flatten the nested field</strong> using the command <span class="code">CROSS JOIN UNNEST</span> (or <span class="code">, UNNEST</span>)which basically creates a new column</p>
<p><img loading="lazy" decoding="async" class="aligncenter wp-image-1045 size-full" src="https://miro.medium.com/max/1200/1*pT2E2crr4DkuAcDgWJLtiQ.gif" alt="nested fields big query" width="600" height="338" /></p>
<p>You have to add the <strong>, UNNEST</strong> in the FROM statement and specify the nested field you want to flatten.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_date, event_timestamp, event_name, params
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`, UNNEST(event_params) AS params
WHERE _TABLE_SUFFIX BETWEEN '20201101' AND '20201121'
      AND event_name = 'first_visit';</pre><p>And you&#8217;ll get this. All the <span class="code">params.key</span> have their own row.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1079 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-1024x220.png" alt="" width="700" height="150" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-1024x220.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-300x64.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-768x165.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-1536x329.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-700x150.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery.png 1838w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>Then you can in the <strong>WHERE condition</strong> the filter for &#8220;https://www.google.it&#8221;</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_date, event_timestamp, event_name, params
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`, UNNEST(event_params) AS params
WHERE _TABLE_SUFFIX BETWEEN '20201101' AND '20201121'
      AND event_name = 'first_visit'
      AND params.value.string_value = "https://www.google.it/";</pre><p>Finally, you get the output you needed.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1080 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-1024x438.png" alt="" width="700" height="299" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-1024x438.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-300x128.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-768x329.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-1536x658.png 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition-700x300.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/unnested-field-bigquery-and-where-condition.png 1574w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<h3>How to create a scheduled query in BigQuery and connect it to Data Studio</h3>
<p>Last but not least, in this post, I want to explain how to <strong>schedule a query in Google BigQuery</strong>.</p>
<p><strong>Instead of manipulating your GA data in Data Studio</strong>, you can do that using an SQL query which automatically updates a table every hour, day,&#8230; .</p>
<p>For example, the query below counts the <em>daily unique users of the last 30 days</em>.</p><pre class="urvanov-syntax-highlighter-plain-tag">SELECT event_date, COUNT(DISTINCT user_pseudo_id) AS uniqueUsers
FROM `ga-data-XXXXXX.analytics_XXXXXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)) 
      AND FORMAT_DATE('%Y%m%d',DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)); 
GROUP BY event_date;</pre><p>If you want to schedule it, you have to click on <em>Schedule query</em>.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-1087 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query-1024x74.png" alt="" width="700" height="51" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query-1024x74.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query-300x22.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query-768x56.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query-700x51.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/schedule-query.png 1212w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>You should give a <strong>name</strong> to the scheduled query and choose <strong>when and how often update it</strong>.</p>
<p>In my example, I decided to update the query daily and store the results in a new table called <span class="code">test_scheduled_query</span>. The data are overwritten every day.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-1088 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-big-query-830x1024.png" alt="" width="455" height="559" /></p>
<p>Then you have to open Google Data Studio and choose the <strong>BigQuery connector</strong>. Here, you&#8217;ll find the test_scheduled_query table which you can use to create a dashboard.</p>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-1095" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-1024x301.jpg" alt="" width="700" height="206" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-1024x301.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-300x88.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-768x226.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-1536x451.jpg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-2048x602.jpg 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2020/11/scheduled-query-data-studio-1-700x206.jpg 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>The post <a href="https://www.rubenvezzoli.online/google-analytics-4-big-query/">How to query Google Analytics 4 data in BigQuery</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/google-analytics-4-big-query/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RAdwords: how to access Google Ads API using R</title>
		<link>https://www.rubenvezzoli.online/radwords-google-ads-r/</link>
					<comments>https://www.rubenvezzoli.online/radwords-google-ads-r/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Mon, 17 Aug 2020 23:05:35 +0000</pubDate>
				<category><![CDATA[R Programming]]></category>
		<category><![CDATA[SEM]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=922</guid>

					<description><![CDATA[<p>In this guide, I&#8217;m going to show you how to pull data out of Google Ads using the APIs and an R Package called RAdwords. Generate the client Id and client secret credentials Open the Google Developers Console, the platform where you can generate the credentials for every Google API (e.g. Google Analytics API, Google [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/radwords-google-ads-r/">RAdwords: how to access Google Ads API using R</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>In this guide, I&#8217;m going to show you <strong>how to pull data out of Google Ads using the APIs and an R</strong> Package called <a href="https://cran.r-project.org/web/packages/RAdwords/index.html" target="_blank" rel="noopener noreferrer">RAdwords</a>.</p>
<h2>Generate the client Id and client secret credentials</h2>
<p>Open the <a href="https://console.developers.google.com/" target="_blank" rel="noopener noreferrer">Google Developers Console</a>, the platform where you can generate the credentials for every Google API (e.g. <a href="https://www.rubenvezzoli.online/googleanalyticsr-beginners-guide/">Google Analytics API</a>, <a href="https://www.rubenvezzoli.online/automate-google-search-console-downloads/">Google Search Console API</a>, <a href="https://www.rubenvezzoli.online/indexing-api-googleauthr/">Indexing API</a>,&#8230; ) and go to the <em>APIs Library</em>.</p>
<p>Find the Google Ads API and <em>Enable</em> the service. In the <em>credentials</em> section, you can generate the <span class="code">client ID</span> and <span class="code">client secret</span> that you need for the OAuth process.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-930 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1-1024x335.jpg" alt="" width="700" height="229" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1-1024x335.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1-300x98.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1-768x251.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1-700x229.jpg 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-api-1.jpg 1152w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<p>Click on <em>OAuth client ID</em> and select <span class="code">Web application</span> in order to generate the right credentials for RAdwords.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-929 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-2.jpg" alt="" width="396" height="542" /></p>
<p>You have to save somewhere the credentials because you&#8217;ll need them in a later step.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-928 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-3.jpg" alt="" width="451" height="395" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-3.jpg 600w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-3-300x262.jpg 300w" sizes="auto, (max-width: 451px) 100vw, 451px" /></p>
<h2>Get a Developer Token for the Google Ads API</h2>
<p>You also need a <span class="code">developer token</span> which you can get in the Google Ads interface.</p>
<p>Open the <em>Tools &amp; settings</em> menu and go to <em>API Centre</em>.</p>
<p><img loading="lazy" decoding="async" class="wp-image-932 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-4.jpg" alt="" width="475" height="398" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-4.jpg 600w, https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-4-300x251.jpg 300w" sizes="auto, (max-width: 475px) 100vw, 475px" /></p>
<p>If you want to work with the Google Ads API in R you&#8217;ll need a developer token with at least a <span class="code">Basic Access</span> level, the packages don&#8217;t work with a <span class="code">Test Access</span> level.</p>
<p>In order to get a Basic Access token, you have to fill out the application form.</p>
<p><img loading="lazy" decoding="async" class="wp-image-931 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-5.jpg" alt="" width="507" height="324" /></p>
<h2>Connect the API and RAdwords using the doAuth() function</h2>
<p>Open your R Ide and install <span class="code">RAdwords</span> using the <span class="code">install.packages()</span> function. In order to access the Google Ads API you have to use the <span class="code">doAuth()</span> function which guides you through the OAuth2.0 authentication process.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Install and Load the RAdwords package
install.packages("RAdwords")
library("RAdwords")

# Launch the OAuth process using doAuth
googleAuth &lt;- doAuth()</pre><p>Run the code above and follow the messages you&#8217;ll see in your console, they&#8217;ll ask you to enter the credentials you generated earlier:</p>
<ol>
<li>The <span class="code">client ID</span> from the Google API Console</li>
</ol>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Authentication process needs your Client ID from the Adwords API project for native apps.

Paste the Client ID here :=&gt;
XXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com</pre><p></p>
<p style="padding-left: 40px;">2. The <span class="code">client secret</span> from the Google API Console</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Authentication process needs your Client secret from the Adwords API project.
Paste the Client secret here :=&gt;
XXXXXXXXXXXXXXXXXXXXX</pre><p></p>
<p style="padding-left: 40px;">3. The <span class="code">developer token</span> from Google Ads</p>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag">Authentication process needs your Developer Token from the Adwords MCC.
Paste the Developer Token here :=&gt;
XXXXXXXXXXXXXXXXXXXXXXXX</pre><p></p>
<p style="padding-left: 40px;">4. The <span class="code">client token</span> will be generated after you login in your Google Account and granted access to your Google Ads account.</p>
<p><img loading="lazy" decoding="async" class="wp-image-927 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-6.jpg" alt="" width="285" height="244" /><img loading="lazy" decoding="async" class="wp-image-926 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/08/google-ads-7.jpg" alt="" width="340" height="236" /></p><pre class="urvanov-syntax-highlighter-plain-tag">Authentication process needs your Client token in order to receive the access token from the API. 
Copy the Client token from your webbrowser and paste it here.
Paste the client token here :=&gt;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</pre><p></p>
<h2>Write your first API Request</h2>
<p>If you want to download the data from the Google Ads interface, you have to use <span class="code">getData()</span>. Don&#8217;t forget to specify the arguments:</p>
<ul>
<li><span class="code">clientCustomerId</span> &#8211; you have to specify the Id of a Google Ads account. You can&#8217;t use the Id of an MCC (manager) account!</li>
<li><span class="code">google_auth</span> &#8211; it should contain the credentials you enter with doAuth()</li>
<li>statement &#8211; an <a href="https://developers.google.com/adwords/api/docs/guides/awql" target="_blank" rel="noopener noreferrer">AWQL statement</a> where you specify <strong>dimensions</strong>, <strong>metrics</strong>, d<strong>ate range</strong> and <strong>report</strong>. <a href="https://developers.google.com/adwords/api/docs/appendix/reports#available-reports" target="_blank" rel="noopener noreferrer">Here</a> you can find the list of all the available fields</li>
</ul>
<p></p><pre class="urvanov-syntax-highlighter-plain-tag"># First of all you have to specify the data you want to get from the API
CampaignData &lt;-statement(select=c("Week",
                          "CampaignName",
                          "Clicks",
                          "Impressions",
                          "AccountDescriptiveName",
                          "Cost",
                          "Conversions"),
                          report = "CAMPAIGN_PERFORMANCE_REPORT",
                          start = "2020-01-01",
                          end = "2020-07-31"
                 )
                          

# Send a request to the API using getData
# ATTENTION - The clientCustomerId must be an account ID and it can't be an MCC (manager) ID

myData &lt;- getData(clientCustomerId = "XXX-XXX-XXXX",
                  google_auth = googleAuth,
                  statement = CampaignData,
                  transformation = T)</pre><p></p>
<h2>Get the same data for multiple accounts</h2>
<p>As I said before, you can only use an <span class="code">account ID</span> and not an <span class="code">MCC ID</span>. This could be an issue if you want to <strong>get the data from multiple accounts at the same time</strong>.</p>
<p>But, you can use a vector and <span class="code">map_dfr()</span> to run the same call over a list of account IDs, here you can find an example.</p><pre class="urvanov-syntax-highlighter-plain-tag"># Load the packages
library("tidyverse")
library("RAdwords")

# First of all you have to specify the data you want to get from the API
CampaignData &lt;-statement(select=c("Week",
                                  "CampaignName",
                                  "Clicks",
                                  "Impressions",
                                  "AccountDescriptiveName",
                                  "Cost",
                                  "Conversions"),
                         report = "CAMPAIGN_PERFORMANCE_REPORT",
                         start = "2020-01-01",
                         end = "2020-07-31"
                         )

# Vector containing the Account IDs
accounts &lt;- c("XXX-XXX-XXXX", "XXX-XXX-XXXX", "XXX-XXX-XXXX")

# The getAdsData function will get the data from the API
getAdsData &lt;- function (i) {
  
  myData &lt;- getData(clientCustomerId = i,
                    google_auth = googleAuth,
                    statement = CampaignData,
                    transformation = T)
  
  return(myData)

}

# map_dfr execute the getAdsData function over the accounts vector, the resulting data frames are merged into one
myAccountsData &lt;- map_dfr(
                        .x = accounts,
                        .f = getAdsData)</pre><p></p>
<p>The post <a href="https://www.rubenvezzoli.online/radwords-google-ads-r/">RAdwords: how to access Google Ads API using R</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/radwords-google-ads-r/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>Send requests to the Google Indexing API using googleAuthR</title>
		<link>https://www.rubenvezzoli.online/indexing-api-googleauthr/</link>
					<comments>https://www.rubenvezzoli.online/indexing-api-googleauthr/#comments</comments>
		
		<dc:creator><![CDATA[Ruben Vezzoli]]></dc:creator>
		<pubDate>Thu, 30 Jul 2020 20:50:40 +0000</pubDate>
				<category><![CDATA[R Programming]]></category>
		<category><![CDATA[SEO]]></category>
		<guid isPermaLink="false">https://www.rubenvezzoli.online/?p=898</guid>

					<description><![CDATA[<p>Two years ago, Google introduced the Indexing API with the intent of solving an issue that affected jobs/streaming websites &#8211; having outdated content in the index. The Google Developers documentation says: &#8220;You can use the Indexing API to tell Google to update or remove pages from the Google index. The requests must specify the location [&#8230;]</p>
<p>The post <a href="https://www.rubenvezzoli.online/indexing-api-googleauthr/">Send requests to the Google Indexing API using googleAuthR</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Two years ago, Google introduced the <strong>Indexing API </strong>with the intent of solving an issue that affected jobs/streaming websites &#8211; having outdated content in the index. The <a href="https://developers.google.com/search/apis/indexing-api/v3/using-api" target="_blank" rel="noopener noreferrer">Google Developers documentation</a> says:</p>
<p>&#8220;<em>You can use the Indexing API to tell Google to update or remove pages from the Google index. The requests must specify the location of a web page. You can also get the status of notifications that you have sent to Google. Currently, the Indexing API can only be used to crawl pages with either job posting or livestream structured data.</em>&#8221;</p>
<p>Many SEOs are using Indexing API also for non-job-related websites and that&#8217;s why I decided to build an R script to try out the API (and it worked).</p>
<p>I&#8217;m going to show you how the script works, but don&#8217;t forget that there is a <strong>free quota of 200 URLs sent per day</strong>!</p>
<h2>Create the Indexing API Credentials</h2>
<p>First of all, you have to generate the <span class="code">client id</span> and <span class="code">client secret</span> keys for the APIs.</p>
<p>Open the <a href="https://console.developers.google.com/apis/" target="_blank" rel="noopener noreferrer">Google API Console</a> and go to the API <strong>Library</strong>.</p>
<p><img loading="lazy" decoding="async" class=" wp-image-906 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api.jpg" alt="" width="621" height="316" /></p>
<p>Open the Indexing API page and enable the API. Then go to the <strong>Credentials</strong> page and there you&#8217;ll find your credentials.</p>
<p><img loading="lazy" decoding="async" class="size-large wp-image-908 aligncenter" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-1024x231.jpg" alt="" width="700" height="158" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-1024x231.jpg 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-300x68.jpg 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-768x173.jpg 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-1536x347.jpg 1536w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-2048x463.jpg 2048w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/indexing-api-credentials-700x158.jpg 700w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p>
<h2>googleAuthR package &amp; Indexing API options</h2>
<p>I created the script using the <a href="https://code.markedmondson.me/googleAuthR" target="_blank" rel="noopener noreferrer"><span class="code">googleAuthR</span></a> package, which allows you to send requests to Google APIs.</p>
<p>The code takes in <strong>input,</strong> a <strong>character vector of maximum 200 URLs </strong>and returns in a data frame the response of the API (see the screenshot below).</p>
<p>You can use the script to update or delete pages. You just have to change the <strong>line 38</strong>:</p>
<ul>
<li><span class="crayon-v">Use <span class="code">type <span class="crayon-o">=</span> <span class="crayon-s">&#8220;URL_UPDATED&#8221;</span></span><span class="crayon-s"> if you have to update the page</span></span></li>
<li><span class="crayon-v">Use <span class="code">type <span class="crayon-o">=</span> <span class="crayon-s">&#8220;URL_DELETED&#8221;</span></span><span class="crayon-s"> if you have to remove the page</span></span></li>
</ul>
<p><img loading="lazy" decoding="async" class="alignnone size-large wp-image-913" src="https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api-1024x132.png" alt="" width="700" height="90" srcset="https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api-1024x132.png 1024w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api-300x39.png 300w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api-768x99.png 768w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api-700x91.png 700w, https://www.rubenvezzoli.online/wp-content/uploads/2020/07/output-indexing-api.png 1268w" sizes="auto, (max-width: 700px) 100vw, 700px" /></p><pre class="urvanov-syntax-highlighter-plain-tag"># LAST UPDATE: 20-03-2021
# Install &amp; Load the packages

install.packages("googleAuthR")
install.packages("tidyverse")
install.packages("readr")

library("googleAuthR")
library("tidyverse")
library("readr")

# Set credentials and scope

clientId &lt;- "PASTE HERE YOUR CLIENT ID"
clientSecret &lt;- "PASTE HERE YOUR CLIENT SECRET" 
scope &lt;- "https://www.googleapis.com/auth/indexing"

options("googleAuthR.client_id" = clientId, 
        "googleAuthR.client_secret" = clientSecret, 
        "googleAuthR.scopes.selected" = scope,
        "googleAuthR.verbose" = 0 # Not mandatory - I just use it to debug the script
        )

# Google API OAuth

gar_auth()

# List of URLs - Daily Limit of 200 URLs 

urls &lt;- read_csv("~/Desktop/Your-file-name.csv")
urls &lt;- urls[ ,1]

# indexingApi function - you can use the function to send requestes to the indexing API using urls vector as an input
# It also GET the response from the API and stores it in a data frame

indexingApi &lt;- function(page) {
    
    body &lt;-  list(
                  url = page,
                  type = "URL_UPDATED")
    
    f &lt;- gar_api_generator("https://indexing.googleapis.com/v3/urlNotifications:publish",
                           "POST")
    
    result &lt;- f(the_body = body)
    result &lt;- as.data.frame(result[[6]][[1]][[2]])
    
    return(result)
    
}

# The API responses are stored in a data frame

APIResponse &lt;- map_dfr(
                      .x = urls,
                      .f = indexingApi)

# You can download the API responses as .csv file

write.csv(APIResponse, "Your-file-name.csv")</pre><p></p>
<p>The post <a href="https://www.rubenvezzoli.online/indexing-api-googleauthr/">Send requests to the Google Indexing API using googleAuthR</a> appeared first on <a href="https://www.rubenvezzoli.online">Ruben Vezzoli</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.rubenvezzoli.online/indexing-api-googleauthr/feed/</wfw:commentRss>
			<slash:comments>8</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Lazy Loading (feed)
Database Caching using Disk (Request-wide modification query)

Served from: www.rubenvezzoli.online @ 2026-09-05 03:02:51 by W3 Total Cache
-->