<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Hardal</title>
    <description>The latest articles on Forem by Hardal (@hardal).</description>
    <link>https://forem.com/hardal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F5745%2F3e489554-a6fa-4c66-96ee-40a1ae2f0996.png</url>
      <title>Forem: Hardal</title>
      <link>https://forem.com/hardal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hardal"/>
    <language>en</language>
    <item>
      <title>122 Milyon Satır Analytics Datasını Nasıl Türkiye’ye Getirdik?</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Tue, 25 Feb 2025 21:23:29 +0000</pubDate>
      <link>https://forem.com/hardal/122-milyon-satir-analytics-datasini-nasil-turkiyeye-getirdik-2bc6</link>
      <guid>https://forem.com/hardal/122-milyon-satir-analytics-datasini-nasil-turkiyeye-getirdik-2bc6</guid>
      <description>&lt;h2&gt;
  
  
  122 Milyon Satır Analytics Datasını Nasıl Türkiye’ye Getirdik?
&lt;/h2&gt;

&lt;p&gt;Selam!&lt;/p&gt;

&lt;p&gt;Yakın zaman içerisinde &lt;strong&gt;Google Cloud — europe&lt;/strong&gt; sunucularından, Hardal’ın Türkiye sunucuları için kullandığı &lt;strong&gt;Huawei Cloud — Istanbul&lt;/strong&gt; sunucularına transfer ettiğimiz &lt;strong&gt;122 Milyon&lt;/strong&gt; satır analytics datasının transfer sürecinden bahsedeceğim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Özetle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tablo yapılarımızı değerlendirerek iki seçenek arasından karar verdik ve sunucular arası transferi, ClickHouse’un yerel tablo transfer fonksiyonunu kullanarak gerçekleştirdik. Bu süreç yaklaşık 24 saat sürdü ve akıl sağlığımızdan bir miktar götürdü.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndt44963vo80l1tc5pdb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndt44963vo80l1tc5pdb.png" width="750" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Transfer sürecinden önce mevcut tablo yapımızdan ve önümüzdeki seçeneklerden bahsetmem gerek:&lt;/p&gt;

&lt;h2&gt;
  
  
  Tablo Yapımız
&lt;/h2&gt;

&lt;p&gt;Sunucularımızda veritabanı olarak ClickHouse’un &lt;strong&gt;MergeTree Engine&lt;/strong&gt; tablolarını kullanıyoruz. Toplamda dört tablomuz bulunuyor: Analytics, Config, Telemetry ve iki adet optimize edilmiş &lt;strong&gt;Materialized View&lt;/strong&gt;. ClickHouse’u tercih etmemizin en önemli nedenlerinden biri, aşağıda PostgreSQL ile yapılan karşılaştırmada da görebileceğiniz performans farkı. 👇&lt;a href="https://clickhouse.com/comparison/postgresql" rel="noopener noreferrer"&gt;Detaylar burada&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc60ogz8f9bm7vzbqdrh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc60ogz8f9bm7vzbqdrh3.png" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tüm event verileri ham (raw) biçimde &lt;strong&gt;analytics&lt;/strong&gt; tablosunda saklanıyor. Daha verimli okuma işlemleri için, bu ham veriyi iki ayrı tabloya aktardığımız bir optimizasyon sürecimiz var. Yani &lt;strong&gt;analytics&lt;/strong&gt; tablosuna gelen her veri, otomatik olarak belirttiğim iki &lt;strong&gt;Materialized View&lt;/strong&gt; tablosuna formatlanarak yazılıyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz575oa6o8uf7hgool2i0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz575oa6o8uf7hgool2i0.png" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Transfer Süreci
&lt;/h2&gt;

&lt;p&gt;Gelelim zurnanın zort dediği yere. Transfer süreci.&lt;/p&gt;

&lt;p&gt;Aslında bu süreç genellikle sorunsuz ilerliyor, ancak konu 120 milyon gibi devasa bir veri hacmi olunca işler biraz karmaşık hale geliyor. Bu noktada önümüzde iki seçenek vardı:&lt;/p&gt;

&lt;p&gt;1 — Mevcut dataları exportlayıp (CSV ya da native sql) yeni sunucu içine manual aktarmak&lt;/p&gt;

&lt;p&gt;2 — Clickhouse’un native transfer fonksiyonlarını kullanıp otomatik bir şekilde sürecin tamamlanmasını beklemek&lt;/p&gt;

&lt;p&gt;İlk olarak birinci yöntemi denedik. Ancak verinin büyüklüğü nedeniyle manuel dışa aktarma yönteminin sonucunu ancak çocuklarımızın görebileceğini fark edince, ikinci seçeneğe yönelmeye karar verdik.&lt;/p&gt;

&lt;p&gt;Bu noktada tablo yapımızın büyük avantajını gördük. &lt;strong&gt;Materialized View&lt;/strong&gt; tabloları, &lt;strong&gt;analytics&lt;/strong&gt; tablosunu otomatik olarak inheritlediği için, aslında yalnızca &lt;strong&gt;analytics&lt;/strong&gt; tablosunu transfer etmek, tüm tabloların otomatik olarak doldurulmasını sağlayacaktı.&lt;/p&gt;

&lt;p&gt;Plan harikaydı, ve hemen aksiyon almaya başladık. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;INSERT INTO remote(‘destination_ip:port’, ‘default.table_name’, ‘username’, ‘password’)&lt;br&gt;
SELECT * FROM target_table_name ;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bu yöntemi kullanarak işlemi başlattık. İşlemin %1’inin tamamlanması yaklaşık 5 dakika sürdü. Basit bir matematikle hesapladığımızda (5 × 100), işlemin yaklaşık 500 dakika (~8 saat) içinde tamamlanacağını öngördük.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gece yatarken bırakırız, sabah olur işte.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tabiki de öyle olmadı :D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89ssfcgbnotcxkl7hkay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89ssfcgbnotcxkl7hkay.png" width="599" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google Cloud’un tarayıcı tabanlı SSH bağlantısı bu kadar uzun süren işlemleri desteklemiyordu ve sık sık &lt;strong&gt;timeout&lt;/strong&gt; hatası alıyorduk. Ancak asıl sorun bu değildi. Zamanla yarışıyorduk — her geçen saniye &lt;strong&gt;analytics&lt;/strong&gt; tablosuna binlerce yeni satır ekleniyor ve bu da transfer sürecinin giderek uzaması anlamına geliyordu.&lt;/p&gt;

&lt;p&gt;Üst üste yaşadığımız 3–4 başarısız denemenin (fazladan 24 saat kayıp) ardından artık daha sağlam bir yöntem deneme zamanı gelmişti. Bu yüzden, &lt;strong&gt;tarayıcı tabanlı SSH yerine doğrudan kendi terminalimizden SSH bağlantısı kurarak&lt;/strong&gt; süreci yeniden başlattık.&lt;/p&gt;

&lt;h2&gt;
  
  
  Neden Kendi Terminalimizden SSH Bağlantısı Daha Sağlıklı?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Google Cloud’un &lt;strong&gt;tarayıcı tabanlı SSH&lt;/strong&gt; bağlantıları, belirli bir süre işlem yapılmadığında &lt;strong&gt;otomatik olarak kapanır (timeout)&lt;/strong&gt;. Uzun süren işlemler için bu büyük bir dezavantajdır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lokal terminal üzerinden yapılan SSH bağlantıları&lt;/strong&gt;, timeout sınırlarına takılmadan kesintisiz çalışabilir.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tarayıcıdan yapılan SSH bağlantıları &lt;strong&gt;ağ kesintilerine ve sekme kapanmalarına karşı daha hassastır&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lokal terminalden bağlandığımızda, ağ dalgalanmalarına rağmen bağlantıyı sürdürebiliriz.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;tmux veya screen&lt;/strong&gt; gibi araçlar kullanarak bağlantıyı kopsa bile işlemi arka planda çalıştırabiliriz.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tarayıcı kapansa bile süreç devam eder.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wp2j5hrf8ydpadpkw8w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wp2j5hrf8ydpadpkw8w.png" width="569" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;12 saatin sonunda transferin %50’si tamamlanmıştı ve artık &lt;strong&gt;timeout&lt;/strong&gt; problemi yaşamıyorduk. Süreç sorunsuz ilerliyordu.&lt;/p&gt;

&lt;p&gt;Ancak, &lt;strong&gt;“Kaçırdığımız 24 saat içinde ne kadar veri eklenmiş olabilir ki?”&lt;/strong&gt; sorusunu fazlasıyla hafife aldık. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03j0ykv2bkplo34kg7v5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F03j0ykv2bkplo34kg7v5.png" width="728" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ve zafer! 🎉 Yaklaşık &lt;strong&gt;24 saat&lt;/strong&gt; sonunda, tüm verileri &lt;strong&gt;Google Cloud’un Avrupa sunucularından&lt;/strong&gt; &lt;strong&gt;Huawei Cloud’un Türkiye sunucularına&lt;/strong&gt; başarıyla taşıdık. Bu süreç boyunca yaşadığımız tüm zorluklara rağmen, sonunda transferi tamamlamış olmanın haklı gururunu yaşadık. 🚀&lt;/p&gt;

&lt;p&gt;Bize de on numara bir anı kalmış oldu.&lt;/p&gt;

&lt;p&gt;Daha &lt;strong&gt;optimize&lt;/strong&gt; bir çözüm mümkün müydü? &lt;strong&gt;Tabii ki.&lt;/strong&gt;&lt;br&gt;
Sonuca ulaştık mı? &lt;strong&gt;Kesinlikle.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🎯 &lt;strong&gt;Mission completed.&lt;/strong&gt; 🚀&lt;/p&gt;

&lt;p&gt;Sevgiler ve saygılar&lt;/p&gt;

&lt;p&gt;by.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to use Hardal Signal Unity SDK</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Wed, 12 Feb 2025 15:39:00 +0000</pubDate>
      <link>https://forem.com/hardal/how-to-use-hardal-signal-unity-sdk-37b0</link>
      <guid>https://forem.com/hardal/how-to-use-hardal-signal-unity-sdk-37b0</guid>
      <description>&lt;h2&gt;
  
  
  How to use Hardal Signal Unity SDK
&lt;/h2&gt;

&lt;p&gt;Greetings, mighty internet!&lt;/p&gt;

&lt;p&gt;Let’s talk about our fresh product: Hardal Signal Unity SDK&lt;/p&gt;

&lt;h3&gt;
  
  
  TL:DR
&lt;/h3&gt;

&lt;p&gt;Hardal Signal Unity SDK is a lightweight and easy-to-use tool for Unity projects, allowing developers to track game events seamlessly. This guide will walk you through the installation, setup, and usage of the SDK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt6q4yzo91g30slig4fl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt6q4yzo91g30slig4fl.png" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use it
&lt;/h2&gt;

&lt;p&gt;Let’s create a boilerplate Unity 2D game and implement Hardal Signal SDK to it step by step. From &lt;strong&gt;learning&lt;/strong&gt; section, i’ll be selecting &lt;strong&gt;2D Platformer Microgame.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kx104g2jk0a2q7nx1pd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kx104g2jk0a2q7nx1pd.png" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigating to &lt;strong&gt;Window -&amp;gt;&lt;/strong&gt; &lt;strong&gt;Package&lt;/strong&gt; &lt;strong&gt;Manager&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2w94olicwkin5zgsido.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb2w94olicwkin5zgsido.png" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will open a popup. All i need to do is copy Hardal Signal Unity SDK git repository URL and paste it to the input that stays in &lt;strong&gt;Install package from git URL&lt;/strong&gt; option.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/usehardal/unity-sdk.git" rel="noopener noreferrer"&gt;https://github.com/usehardal/unity-sdk.git&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3401kuf1hp38mf7gco97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3401kuf1hp38mf7gco97.png" width="800" height="674"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll be able to see that Hardal package is successfully installed and ready to go!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zxyjynltedvnepn2lm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7zxyjynltedvnepn2lm6.png" width="715" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s send our first event. I’ll be triggering event every time when player dies. First, i need to initialize hardal sdk. Let’s do it by &lt;strong&gt;right click at the scene -&amp;gt; select Hardal -&amp;gt; Create Hardal Manager and replace placeholder domain at the Hardal Manager&lt;/strong&gt; script with my own Hardal Signal domain.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;HardalManager will automatically manage initializing the sdk&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbq6jux4x49mq1dm09ji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzbq6jux4x49mq1dm09ji.png" width="666" height="764"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uzbyqcnmc0gyqnoh8yz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9uzbyqcnmc0gyqnoh8yz.png" width="651" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now it’s time to implement our tracking code. It’ll be inside of PlayerDeath script file so lets do it. &lt;em&gt;You can check technical documentation from repository itself!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop57fg34tj96u6xtnewp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop57fg34tj96u6xtnewp.png" width="800" height="145"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you enable Debug option, you’ll start to see event flow from console!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaidue994pz9tbswnlu7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaidue994pz9tbswnlu7.png" width="485" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, i can confirm that events are successfully landing via Hardal Analytics Dashboard!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffee400q1ggshgzae3wk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffee400q1ggshgzae3wk5.png" width="800" height="104"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So with that being said, it’s time to go. I hope this one helps you to measure your Game Analytics.&lt;/p&gt;

&lt;p&gt;Cya.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Send your analytics data wherever you want with Hardal</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Sun, 12 Jan 2025 21:37:11 +0000</pubDate>
      <link>https://forem.com/hardal/send-your-analytics-data-wherever-you-want-with-hardal-5dmj</link>
      <guid>https://forem.com/hardal/send-your-analytics-data-wherever-you-want-with-hardal-5dmj</guid>
      <description>&lt;h2&gt;
  
  
  Send your analytics data wherever you want with Hardal
&lt;/h2&gt;

&lt;p&gt;Greetings, mighty internet.&lt;/p&gt;

&lt;p&gt;Today, I'd like to make a guidance about how you can transfer &lt;strong&gt;any&lt;/strong&gt; kind of web events to literally &lt;strong&gt;any platform you want&lt;/strong&gt; with Hardal Signal’s &lt;strong&gt;Custom Destinations&lt;/strong&gt; feature that is published with version 1.0.4.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmsf8xohbmo85ao3ho3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxmsf8xohbmo85ao3ho3g.png" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept
&lt;/h2&gt;

&lt;p&gt;Basically, you can forward incoming request to any kind of service that is accepts http POST and GET requests. The craziest part is, you can manage payload format as well!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnngyvni33oidvwdcq2e9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnngyvni33oidvwdcq2e9.png" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It all starts with clicking &lt;strong&gt;“Add Destination”&lt;/strong&gt; button that is placed on your Signal’s Connection tab. You’ll encounter with this dialog below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlxwjbwchqbebb06m8kc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlxwjbwchqbebb06m8kc.png" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may also use built-in templates!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdir6g7uoi4xkjkvbe1p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdir6g7uoi4xkjkvbe1p.png" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Endpoint Label&lt;/strong&gt;: Display Name of your connection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Endpoint ID&lt;/strong&gt;: Unique identifier for your connection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Endpoint URL:&lt;/strong&gt; Destination URL that data will sent&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Request Method&lt;/strong&gt;: HTTP Request method&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content Type (POST Method Only):&lt;/strong&gt; You can select either &lt;em&gt;application/json *or *application/x-www-form-urlencoded&lt;/em&gt; option for your &lt;strong&gt;Content-Type Header&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Request Format (POST Method Only):&lt;/strong&gt; This is the payload format that can be shaped with your destinations requirements. You can use build-in variables to form all kind of JSON format to use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Query Parameters (GET Method Only):&lt;/strong&gt; And this one stands for defining your query parameters within get requests. You can also use variables for this one!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Additional Headers:&lt;/strong&gt; You can specify custom headers. This is the place that you want to take a look if your server has some kind of authentication mechanism.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now i’ll be creating 3 custom destination to cover all the possible ways of transfer your data. Here goes my configs&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzur99ssual3xbj4dffqf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzur99ssual3xbj4dffqf.png" width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyky9ukyfg0iysdmb41b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyky9ukyfg0iysdmb41b.png" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayw49u1t4x09ogdc4685.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fayw49u1t4x09ogdc4685.png" width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh1jz69wl9zw21k059edc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh1jz69wl9zw21k059edc.png" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And as you can see down below, i am successfully receiving my own analytics data with Hardal Signal SDK&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yekw09wp9wqkiaaak13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4yekw09wp9wqkiaaak13.png" width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46f8jt398jox5zi76h14.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F46f8jt398jox5zi76h14.png" alt="Here goes my server logs" width="579" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let us cook&lt;/em&gt; ️‍🔥&lt;/p&gt;

&lt;p&gt;Peace.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Server-side GTM With Huawei</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Thu, 03 Oct 2024 09:28:40 +0000</pubDate>
      <link>https://forem.com/hardal/server-side-gtm-with-huawei-253m</link>
      <guid>https://forem.com/hardal/server-side-gtm-with-huawei-253m</guid>
      <description>&lt;p&gt;Hello everyone!&lt;/p&gt;

&lt;p&gt;Let’s explore implementing server-side Google Tag Manager using Huawei Cloud Turkey, using &lt;a href="https://usehardal.com" rel="noopener noreferrer"&gt;Hardal&lt;/a&gt; for improved performance, better data accuracy, and enhanced user privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;TLDR&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We utilized &lt;a href="https://www.huaweicloud.com/intl/tr-tr/product/cci.html" rel="noopener noreferrer"&gt;Cloud Container Instance&lt;/a&gt; (CCI) to deploy the server-side GTM container image, configured &lt;a href="https://www.huaweicloud.com/intl/tr-tr/product/elb.html" rel="noopener noreferrer"&gt;Elastic Load Balancer&lt;/a&gt; (ELB) and CCI Service for each workload, and created a DNS record using the ELB public IP.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y8hmshh47v7vrvhtpk8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y8hmshh47v7vrvhtpk8.jpeg" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;p&gt;At the end of the day, we require a total of two running containers for the server-side Google Tag Manager.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;One for Preview Server&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One for Tagging Server&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this project, we chose to utilize the Cloud Container Instance (CCI) service on Huawei Cloud. This service is designed to run containerized applications, which perfectly aligns with our requirements. For more detailed information on how server-side Google Tag Manager functions, please refer to the &lt;a href="https://developers.google.com/tag-platform/tag-manager/server-side/manual-setup-guide" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the full workflow:&lt;/p&gt;

&lt;p&gt;1 — Import the Google Tag Manager image into Huawei Cloud’s &lt;a href="https://www.huaweicloud.com/intl/tr-tr/product/swr.html" rel="noopener noreferrer"&gt;Software Repository for Container&lt;/a&gt; (SWR).&lt;/p&gt;

&lt;p&gt;2 — Set up a Preview Server CCI Workload using the imported SWR image.&lt;/p&gt;

&lt;p&gt;3 — Configure Elastic Load Balancer (ELB) for the Preview Server workload&lt;/p&gt;

&lt;p&gt;4 —Create a DNS record for the Preview Server.&lt;/p&gt;

&lt;p&gt;5 — Deploy the Preview Server using CCI.&lt;/p&gt;

&lt;p&gt;With these five steps, the preview server is successfully running on Huawei Cloud! We will repeat this process for our tagging server, with the only difference being that we will use the preview server’s URL as an environment variable in the tagging server’s image. Here’s the flowchart:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sJRkp9kP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4084/1%2Akc09v0pRpEw4Dq86CNwXDw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sJRkp9kP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/4084/1%2Akc09v0pRpEw4Dq86CNwXDw.png" width="800" height="2626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Managing SSL Certificates&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Managing SSL certificates for the custom domain was the most challenging part of the entire process. Fortunately, with &lt;a href="https://certbot.eff.org/" rel="noopener noreferrer"&gt;Certbot &lt;/a&gt;and &lt;a href="https://letsencrypt.org/tr/" rel="noopener noreferrer"&gt;Let’s Encrypt&lt;/a&gt;, we are able to generate free SSL certificates and store them in Huawei Cloud, allowing us to incorporate them into our CCI service configuration files.&lt;/p&gt;

&lt;p&gt;In conclusion, the successful implementation of server-side Google Tag Manager on Huawei Cloud would not have been possible without the support of the Huawei team. Their assistance and expertise have been invaluable throughout this process. We are grateful for their guidance, which has significantly contributed to our project’s success. Thank you, Huawei team, for your continued support!&lt;/p&gt;

&lt;p&gt;Until next time!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Server-side GTM With Azure App Service</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Thu, 19 Sep 2024 21:18:38 +0000</pubDate>
      <link>https://forem.com/hardal/server-side-gtm-with-azure-app-service-4gdk</link>
      <guid>https://forem.com/hardal/server-side-gtm-with-azure-app-service-4gdk</guid>
      <description>&lt;p&gt;Hello, everyone!&lt;/p&gt;

&lt;p&gt;Explore implementing server-side Google Tag Manager using Azure App Service, using Hardal for improved performance, better data accuracy, and enhanced user privacy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL:DR&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;We create a container registry and a &lt;a href="https://azure.microsoft.com/en-us/products/container-apps" rel="noopener noreferrer"&gt;container app&lt;/a&gt; on Azure. After that, we map the container app to our desired custom domain. You can accomplish this with a single click on &lt;a href="https://usehardal.com/" rel="noopener noreferrer"&gt;*Hardal&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F10176%2F1%2AmwJlIyzXsU9b0N1qj2zQXQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F10176%2F1%2AmwJlIyzXsU9b0N1qj2zQXQ.png" alt="Your Server-side GTM Container is one-click away!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5a5np8l1vld5p3nalz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5a5np8l1vld5p3nalz7.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plan
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a server-side GTM and obtain a configuration key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up a server-side GTM &lt;a href="https://azure.microsoft.com/en-us/products/container-registry" rel="noopener noreferrer"&gt;container registry&lt;/a&gt; on Azure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a container app on Azure that runs the server-side GTM registry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Map a custom domain to the server-side GTM container app.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjnac482o1deh0j38ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjnac482o1deh0j38ah.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, let’s start with the basics of server-side GTM infrastructure. This diagram is from the official &lt;a href="https://developers.google.com/tag-platform/tag-manager/server-side/manual-setup-guide" rel="noopener noreferrer"&gt;Google documentation&lt;/a&gt;. I won’t go into the details of how it works, but it’s essential to understand the framework of what we are doing.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Deployment Details&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We need to focus on two important topics when deploying our container:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We need to set the Ingress value to "enabled" to access our Container App with a domain.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need two container apps: one for the preview server and one for the tagging server. Environment values vary depending on the container type.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Preview Server Environment Variables&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CONTAINER_CONFIG=config_string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RUN_AS_PREVIEW_SERVER=true&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tagging Server Environment Variables&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CONTAINER_CONFIG=config string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PREVIEW_SERVER_URL=HTTPS preview server url&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;DNS Mapping&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For the final step, we need to configure our domain to point to the container app. By selecting “Managed Certificate,” we need to add two DNS records to our domain.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Type: CNAME
Name: www or {subdomain}
Value: &amp;lt;DNS VALUE THAT AZURE PROVIDES&amp;gt;

Type: TXT
Name: asuid.www or asuid.{subdomain}
Value: &amp;lt;DNS VALUE THAT AZURE PROVIDES&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After a short delay, our container will be accessible via our custom domain!&lt;/p&gt;

&lt;p&gt;With everything set up, you’re now ready to leverage server-side GTM on Microsoft Azure with your custom domain. This setup not only enhances your tracking capabilities but also ensures better performance and flexibility. Happy tracking!&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>serverside</category>
      <category>gtm</category>
      <category>hardal</category>
    </item>
    <item>
      <title>Server-side GTM With Yandex Cloud</title>
      <dc:creator>Mert Enercan</dc:creator>
      <pubDate>Thu, 19 Sep 2024 21:13:37 +0000</pubDate>
      <link>https://forem.com/hardal/server-side-gtm-with-yandex-cloud-1pc0</link>
      <guid>https://forem.com/hardal/server-side-gtm-with-yandex-cloud-1pc0</guid>
      <description>&lt;h2&gt;
  
  
  Server-side GTM With Yandex Cloud
&lt;/h2&gt;

&lt;p&gt;Greetings, internet!&lt;br&gt;
Since Server-Side GTM can operate as a simple Docker image, we’ve decided to expand our cloud provider options to include Yandex Cloud, in addition to Azure, GCP, and AWS. Today, I’d like to share how we made this happen!&lt;/p&gt;

&lt;p&gt;First, let’s dive into how the &lt;a href="https://developers.google.com/tag-platform/tag-manager/server-side/manual-setup-guide" rel="noopener noreferrer"&gt;Manual Setup&lt;/a&gt; works with Server-Side Google Tag Manager. I’ll be using some helper images from the official Google Docs after listing what we need in bullet points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--p4r9l6ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/10176/1%2AzCyrqKvof2QYFclwqKzmZA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--p4r9l6ku--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/10176/1%2AzCyrqKvof2QYFclwqKzmZA.png" alt="Your Server-side GTM Container is one-click away!" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What we need
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Server-side GTM Container, obviously xd &lt;em&gt;(if you don’t have one, make it happen with &lt;a href="https://usehardal.com" rel="noopener noreferrer"&gt;Hardal&lt;/a&gt; for **free&lt;/em&gt;&lt;em&gt;)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Custom Domain&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yandex Cloud account&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these ingredients and a bit of Hardal magic, we’re able to deploy our server-side Google Tag Manager on Yandex Cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Structure of Server-side Google Tag Manager&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjnac482o1deh0j38ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcyjnac482o1deh0j38ah.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This diagram essentially shows how it works. You’re already familiar with how Web GTM operates, but now it’s time to move it to the server that Hardal provides on Yandex Cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flowchart
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9651bcy512yebsx1d1s5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9651bcy512yebsx1d1s5.png" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start with the first step: creating a Serverless Container on Yandex Cloud that runs the Server-Side Google Tag Manager image. To accomplish this, we’ve created a &lt;a href="https://yandex.cloud/en/docs/container-registry/" rel="noopener noreferrer"&gt;Container Registry&lt;/a&gt; for the sGTM image. Now, we’re ready to create our Serverless Container.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Remember, we need Preview Server and Tagging Server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For the preview server, we ran the sGTM registry with the RUN_AS_PREVIEW_SERVER=true variable.&lt;/p&gt;

&lt;p&gt;After successfully deploying the Preview Server image, we’re now ready to map a custom URL to the container. While Yandex Cloud doesn’t provide a direct way to manage domains for your containers, there’s no such thing as “impossible.” So, we found a workaround to make it happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Solution&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FZ4TII0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AzgRxvfB0BstyWDnR" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FZ4TII0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/2000/0%2AzgRxvfB0BstyWDnR" width="626" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The plan was to create an &lt;a href="https://yandex.cloud/en/docs/api-gateway/" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt; and integrate it with the sGTM container. Instead of mapping the custom domain directly to the container, we mapped it to the API Gateway and connected the container to the gateway. After generating a Let’s Encrypt certificate for our custom domain, we were nearly at the final result. It was time to map our domain to the API Gateway.&lt;/p&gt;

&lt;p&gt;The tricky part is that you can connect the domain &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;**www.example.com&lt;/a&gt;&lt;strong&gt;, but not **example.com&lt;/strong&gt;. This is due to how CNAME records are processed by DNS hosting. To resolve this, we created an ANAME DNS record on &lt;a href="https://yandex.cloud/en/docs/dns/concepts/resource-record#aname" rel="noopener noreferrer"&gt;Yandex Cloud DNS.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the configurations provided below, our API Gateway is now ready to use with a custom domain and serverless container. 🎊&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/{proxy+}:
    x-yc-apigateway-any-method:
      x-yc-apigateway-integration:
        type: serverless_containers
        container_id: containerID
        service_account_id: serviceAccountID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we have the sGTM Preview Server with a custom domain working on Yandex Cloud. For the Tagging Server, we follow the same process, but instead of using the RUN_AS_PREVIEW_SERVER=true variable, we need to use the PREVIEW_SERVER_URL='' variable for the registry deployment.&lt;/p&gt;

&lt;p&gt;Until next time.&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>serverside</category>
      <category>gtm</category>
      <category>hardal</category>
    </item>
    <item>
      <title>Cookieless tracking in web2 and web3</title>
      <dc:creator>Berkay</dc:creator>
      <pubDate>Sun, 27 Nov 2022 11:52:13 +0000</pubDate>
      <link>https://forem.com/hardal/cookieless-tracking-in-web2-and-web3-4p25</link>
      <guid>https://forem.com/hardal/cookieless-tracking-in-web2-and-web3-4p25</guid>
      <description>&lt;p&gt;&lt;strong&gt;Cookieless tracking&lt;/strong&gt; is basically a type of web analytics that does not require any cookies on your browser. &lt;/p&gt;

&lt;p&gt;This type of marketing engineering has been around for a while but it has only recently become popular with GDPR regulations. This regulation states that if an organization collects data from users which using your website, web apps, or dApps. it must be able to delete this information at any time. &lt;/p&gt;

&lt;p&gt;With cookieless tracking, companies can now keep their users' data private by deleting it from their servers straight away instead of keeping it there for years on end. Cookieless tracking is becoming more prevalent on the internet and so marketers are relying largely on it to keep their user's data private.&lt;/p&gt;

&lt;p&gt;Cookieless tracking is a solution for the GDPR and cookie consent compliance problem. With the help of this technology, companies can track the user's activity on the website without collecting any personal data.&lt;/p&gt;

&lt;p&gt;Using a &lt;strong&gt;server-side&lt;/strong&gt; technology that doesn't use any cookies to identify or track visitors on your website. It does so by using other methods like IP address, device fingerprinting, and browser fingerprinting like 🌭&lt;a href="https://usehardal.com/web2?utm_source=devto"&gt;Hardal for web2&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web3 Analytics in marketing
&lt;/h2&gt;

&lt;p&gt;In web3 Analytics allows for marketing engineers to track the user’s journey from the first visit to the last visit, without having to place a cookie on their device while they are using your dApps.&lt;/p&gt;

&lt;p&gt;Integration this server-side technology that can identify and track the user events on a website which does not require any third-party cookies or scripts with on-chain wallet platforms like &lt;strong&gt;Metamask&lt;/strong&gt; 🦊. &lt;/p&gt;

&lt;p&gt;Hardal also provide us a gateway to web3 analytics with integrating wallets that using Ethereum and other platforms. It can be used to track all kinds of events on the blockchain, including user interactions with smart contracts and decentralized blockchain apps.&lt;/p&gt;

&lt;p&gt;Marketing engineers are now able to create more better marketing campaigns, audience engineering and provide better customer experience due to this new tracking method.&lt;/p&gt;

&lt;p&gt;Hardal also records user actions from blockchain and dApp. It helps marketers and business owners to create custom web3 audiences, generate targeted segments using custom events and activate them with automated marketing campaigns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why privacy is matter?
&lt;/h2&gt;

&lt;p&gt;Privacy is an important issue for web3 Analytics, so they provide a cookieless solution that allows them to track users without having to store any of the data in a browser or add-ons.&lt;/p&gt;

&lt;p&gt;Web developers and marketers need to respect the privacy of their users. However, with the advent of GDPR, this has become even more important.&lt;/p&gt;

&lt;p&gt;This means that companies need ways to track their ads, offers, and website audiences without using cookies.&lt;/p&gt;

&lt;p&gt;While cookieless tracking might sound like a challenging task for marketers, there are solutions that can help them with this by integrating it into their existing technology stack with ease.&lt;/p&gt;

&lt;p&gt;Hardal web2 and web3 analytics provides an powerful solution for businesses who are using on-chain marketing tools and want to achieve compliance with GDPR regulations. &lt;/p&gt;

&lt;p&gt;All of the analytics are done server-side, so there is no need to worry about cookies or third party integrations.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>cookieles</category>
      <category>serverside</category>
      <category>analytics</category>
    </item>
  </channel>
</rss>
