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:
- Create account on SendGrid
- Create Single Sender Verification
- Create SendGrid API Key
Github:
- Create account on Github
- Create Creating a personal access token - GitHub
First setup back-end app:
git clone https://github.com/hsayed21/gtm-server.git
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 Verification’toMail@gmail.com’{: .bg-yellow-400} change to your email for receive messages_""_{: .bg-yellow-400} change to your SendGrid API Key | SendGrid API Key
def send(_json, _test=False):
# using SendGrid's Python Library
message = Mail(
from_email='fromMail@gmail.com',
to_emails='toMail@gmail.com',
subject='Track Resume',
html_content= send_template(_json,_test))
try:
sg = SendGridAPIClient("<sendGrid-APi-key>")
response = sg.send(message)
return json.dumps(True)
except Exception as e:
print(e.message)
return json.dumps(False)
After that go to update function and modify ""{: .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
g = Github("<github-token>")
repo = g.get_user().get_repo("gtm-json")
file_content = repo.get_contents("data.json")
clear_data_from_github = file_content.decoded_content.decode()
data_json = json.loads(clear_data_from_github)
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
- Create a project
1heroku create my-gtm-server-app
- Push your app to Heroku
git add .
git commit -m "modify app"
git push heroku master
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 modify_“https://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
<script>
// array of free api for get public ip
var urls = ['https://api.ipify.org/?format=json',
'https://jsonip.com', 'https://ipapi.co/json/',
'https://ident.me', 'https://ipinfo.io/json',
'https://ifconfig.me/ip',
'https://ipecho.net/json',
'https://icanhazip.com/',
'https://wtfismyip.com/text',
'https://api.hostip.info/get_json.php',
'https://api.db-ip.com/v2/free/self'];
//create instance
var xhr = new XMLHttpRequest();
//recursive function
(function loop(i, length) {
/*
i => index
length => length of array
*/
// check if reach to end of array | last element of array
if (i>= length) {
return; //go out of function
}
// get item from array
var url = urls[i];
// ajax request to open url
xhr.open("GET", url);
xhr.onreadystatechange = function() {
// if request success
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
// save response
var res = xhr.responseText;
// check if respone is json data or string
// because of different data type
if (isJSON(res)){
if ("ip" in JSON.parse(res))
res = JSON.parse(res)['ip'];
else
res = JSON.parse(res)['ipAddress'];
}
// after get ip send to back-end website
update("https://cors-proxy.herokuapp.com/https://my-gtm-server-app.herokuapp.com/update?ip="+res+"&event=Resume ge View")
return;
}
}
// if happend error or failed request
// start again with different api (recursive)
xhr.onerror = function() {
loop(i + 1, length);
};
xhr.send();
})(0, urls.length); // start with index 0 and length of urls array
// update data
function update (url) {
var xhr2 = new XMLHttpRequest();
xhr2.open("GET", url, true);
xhr2.send();
xhr2.onreadystatechange = function () {
if (xhr2.readyState === 4 && xhr2.status === 200) {
//var json2 = JSON.parse(xhr2.responseText);
}
}
}
// check data type
function isJSON(str) {
try {
return (JSON.parse(str) && !!str);
} catch (e) {
return false;
}
}
</script>
Issues
CORS Error
Create proxy to add CORS header to the request
After creating your CORS Proxy web add a web link before your gtm server in Custom HTML
update("https://your-cors-proxy.herokuapp.com/https://my-gtm-server-app.herokuapp.com/update?ip="+res+"&event=Resume Page View")
Sample Json Data
{
"page_url": "https://your-resume-website.github.io/resume/",
"page_view_count": 3,
"last_seen": "2021-11-21 09:55:06 AM",
"dataSet": [
{
"IP": "64.233.172.110",
"event": "Resume Page View",
"page_view_count": 1,
"timestamp": [
"2021-11-19 09:55:06 AM"
],
"country": "United States of America",
"city": "Mountain View",
"region": "California",
"latitude": "37.405992",
"longitude": "-122.078515",
"isp": "Google LLC",
"hostname": "google-proxy-64-233-172-110.google.com",
"device": "unknown",
"os": "unknown",
"browser": "DefaultProperties"
}
]
}
API Testing
Free API
Reference
- DEPLOYING REST-API BASED FLASK APP ON HEROKU — Part 1 | by Ashiq KS | Medium
- Deploying Fake Back-End Server & DataBase Using JSON-SERVER, GitHub, and Heroku. - DEV Community
- Automate Sending Daily Mails Using Python | by Rohan Krishna Ullas | Level Up Coding
- 3 Ways to Fix the CORS Error — and How the Access-Control-Allow-Origin Header Works | by David Katz | Medium