Track resume with GTM + Heroku + Github + SendGrid [Part2]

    4 minute read

    On this part will focus on how to build back-end app to work as a server with gtm.We will use rest-api with flask for work as get request to run our service when calling it.

    Step by step, you will understand what I mean.

    before we start, we need

    SendGrid:

    Github:

    First setup back-end app:

    1git clone https://github.com/hsayed21/gtm-server.git
    

    {: lang=“bash”}

    After clone repo open app.py file and goto send function and modify with your data.fromMail@gmail.com{: .bg-yellow-400} change to your email that you added to SendGrid | Single Sender VerificationtoMail@gmail.com{: .bg-yellow-400} change to your email for receive messages"<sendGrid-APi-key>"{: .bg-yellow-400} change to your SendGrid API Key | SendGrid API Key

     1def send(_json, _test=False):
     2 # using SendGrid's Python Library
     3 message = Mail(
     4 from_email='fromMail@gmail.com',
     5 to_emails='toMail@gmail.com',
     6 subject='Track Resume',
     7 html_content= send_template(_json,_test))
     8 try:
     9 sg = SendGridAPIClient("<sendGrid-APi-key>")
    10 response = sg.send(message)
    11 return json.dumps(True)
    12 except Exception as e:
    13 print(e.message)
    14 return json.dumps(False)
    

    {: lang=“python”}

    After that go to update function and modify "<github-token>"{: .bg-yellow-400} change to your github token | Creating a personal access token - GitHub

    In github create repo with name gtm-json then create file name data.json

    1g = Github("<github-token>")
    2repo = g.get_user().get_repo("gtm-json")
    3file_content = repo.get_contents("data.json")
    4clear_data_from_github = file_content.decoded_content.decode()
    5data_json = json.loads(clear_data_from_github)
    

    {: lang=“python”}

    After modifying everything, deploy to heroku

    • Create account on Heroku
    • Install the Heroku CLI on your computer
    • Open the terminal and log in then follow the instructions
    1heroku login
    

    {: lang=“bash”}

    • Create a project
    1heroku create my-gtm-server-app
    

    {: lang=“bash”}

    • Push your app to Heroku
    1git add .
    2git commit -m "modify app"
    3git push heroku master
    

    {: lang=“bash”}

    Back to Custom HTML on Google Tag Manager from [Part 1]({{page.url | replace:‘part2’,‘part1’}}){: .underline}, we will continue

    On this code from update function modifyhttps://your-server.herokuapp.com{: .bg-yellow-400} change to your app that was deployed on heroku

    1update("https://your-server.herokuapp.com/update?ip="+res+"&event=Resume Page View")
    
    Google Tag Manager: Custom HTML Final Result
     1<script>
     2
     3// array of free api for get public ip
     4var urls = ['https://api.ipify.org/?format=json',
     5 'https://jsonip.com', 'https://ipapi.co/json/',
     6 'https://ident.me', 'https://ipinfo.io/json',
     7 'https://ifconfig.me/ip',
     8 'https://ipecho.net/json',
     9 'https://icanhazip.com/',
    10 'https://wtfismyip.com/text',
    11 'https://api.hostip.info/get_json.php',
    12 'https://api.db-ip.com/v2/free/self'];
    13
    14//create instance
    15var xhr = new XMLHttpRequest();
    16//recursive function
    17(function loop(i, length) {
    18     /*
    19     i => index
    20     length => length of array
    21     */
    22     // check if reach to end of array | last element of array
    23     if (i>= length) {
    24     	return; //go out of  function
    25     }
    26     // get item from array
    27     var url = urls[i];
    28     // ajax request to open url
    29     xhr.open("GET", url);
    30     xhr.onreadystatechange = function() {
    31         // if request success
    32         if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
    33             // save response
    34             var res = xhr.responseText;
    35             // check if respone is json data or string
    36             // because of different data type
    37             if (isJSON(res)){
    38                 if ("ip" in JSON.parse(res))
    39                    res = JSON.parse(res)['ip'];
    40                 else
    41                    res = JSON.parse(res)['ipAddress'];
    42             }
    43
    44             // after get ip send to back-end website
    45             update("https://cors-proxy.herokuapp.com/https://my-gtm-server-app.herokuapp.com/update?ip="+res+"&event=Resume Page View")
    46             return;
    47         }
    48
    49     }
    50
    51     // if happend error or failed request
    52     // start again with different api (recursive)
    53     xhr.onerror = function() {
    54     loop(i + 1, length);
    55     };
    56
    57     xhr.send();
    58
    59})(0, urls.length); // start with index 0 and length of urls array
    60
    61// update data
    62function update (url) {
    63 var xhr2 = new XMLHttpRequest();
    64 xhr2.open("GET", url, true);
    65 xhr2.send();
    66 xhr2.onreadystatechange = function () {
    67     if (xhr2.readyState === 4 && xhr2.status === 200) {
    68     //var json2 = JSON.parse(xhr2.responseText);
    69     }
    70 }
    71}
    72
    73// check data type
    74function isJSON(str) {
    75try {
    76 return (JSON.parse(str) && !!str);
    77} catch (e) {
    78 return false;
    79 }
    80}
    81
    82</script>
    

    {: lang=“javascript”}

    Issues

    After creating your CORS Proxy web add a web link before your gtm server in Custom HTML

    1update("https://your-cors-proxy.herokuapp.com/https://my-gtm-server-app.herokuapp.com/update?ip="+res+"&event=Resume Page View")
    
    Sample Json Data
     1{
     2"page_url": "https://your-resume-website.github.io/resume/",
     3"page_view_count": 3,
     4"last_seen": "2021-11-21 09:55:06 AM",
     5"dataSet": [
     6     {
     7     "IP": "64.233.172.110",
     8     "event": "Resume Page View",
     9     "page_view_count": 1,
    10     "timestamp": [
    11     "2021-11-19 09:55:06 AM"
    12     ],
    13     "country": "United States of America",
    14     "city": "Mountain View",
    15     "region": "California",
    16     "latitude": "37.405992",
    17     "longitude": "-122.078515",
    18     "isp": "Google LLC",
    19     "hostname": "google-proxy-64-233-172-110.google.com",
    20     "device": "unknown",
    21     "os": "unknown",
    22     "browser": "DefaultProperties"
    23     }
    24]
    25
    26}
    

    {: lang=“json”}

    API Testing
    Free API
    Reference