Here's how you can modify the existing script to include storing and retrieving the user_id
from local storage, and using it in the Google Tag for Google Analytics:
// ... existing script ...
// Async function to hash email and store in local storage
async function hashEmailAndStore(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase());
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
localStorage.setItem('user_id', hashHex); // Store hashed email as user_id in local storage
return hashHex;
}
document.getElementById('natsPreJoinForm').addEventListener('submit', async function(event) {
// ... existing code ...
try {
const email = document.getElementById('usernameemail').value;
const hashedEmail = await hashEmailAndStore(email); // Hash and store the email
// ... existing code ...
const eventDetails = {
// ... existing event details ...
'user_id': hashedEmail // Use the hashed email as user_id
};
gtag("event", "sign_up", eventDetails);
console.log("Event sent with dynamic values: ", eventDetails);
// ... existing code ...
} catch (error) {
console.error("Error:", error);
} finally {
// ... existing code ...
}
});
Later, when you want to compare the user_id
sent by the payment processor with the one stored in local storage, you can retrieve it like this:
// Retrieve the user_id from local storage
const localUserId = localStorage.getItem('user_id');
Then, you can compare localUserId
with the user_id
sent by the payment processor. If they match, you confirm the identity of the user.
You can also add the user_id
retrieved from local storage to the Google Tag for GA by updating the eventDetails
object before sending the event with gtag()
:
const eventDetails = {
// ... other event details ...
'user_id': localUserId // Retrieved from local storage
};
gtag("event", "conversion", eventDetails);
Remember to respect user privacy and comply with regulations such as GDPR when using and storing personal identifiers. Ensure proper consent is obtained and secure methods are used when handling personal data.
Guerilla PreJoin – NATS Vars
{literal}
<!-- ANALYTICS -->
<script>
// Define the decodeNats function
function decodeNats() {
var data = document.getElementById('nats').value;
var chars = data.length;
var add = 4 - (chars % 4);
if (add < 4) {
while (add) {
data += '=';
add -= 1;
}
}
var decodedData = atob(data);
var splitData = decodedData.split('.');
var labels = [ 'AffiliateID', 'ProgramID', 'SiteID', 'TourID', 'CampaignID', 'AdtoolID', 'AdToolSub1ID', 'AdToolSub2ID'];
var siteNames = {
3: 'Affiliate Referral',
25: ' BarracksBoys',
27: ' beta.trentonducati.com',
6: ' Celebrity Sword',
13: ' DemandGay',
4: ' Dirty Rascals The Movie',
32: ' FalconStudios',
34: ' FistingInferno',
22: ' Guerilla Porn',
10: 'HDKPorn',
8: ' HuntForMen',
2: ' I Want Your Love',
14: ' ManHuntFlix.com',
9: ' MrMan',
35: ' mrman-trailertrashboys',
1: ' NakedSword',
20: ' NakedSword-MrMan',
29: ' nakedsword-peterfever.com',
11: ' NakedSwordXXX',
31: ' peterfever-nakedsword.com',
15: ' PlayGirlBlue',
19: ' QReel',
21: ' Qreel TVOD',
24: ' Quantox',
17: ' QueerMeTv',
33: ' RagingStallion',
5: 'Shes Watching',
18: ' Str8upGayPornMovies',
26: ' TIM-VideoVault',
7: ' TimPorntv',
12: ' Titan-Men',
30: ' trailertrashboys',
16: ' TrentonDucati',
28: ' www-qa.nakedsword.org'
};
var decodedValues = {};
splitData.forEach((value, index) => {
if (index < labels.length) {
decodedValues[ `nats_${labels[ index]}`] = value;
if (labels[ index] === 'SiteID') {
decodedValues[ "nats_SiteName"] = siteNames[ value] || 'Unknown Site';
}
}
});
return decodedValues;
}
let precomputedNatsValues = {}; // Global variable to store precomputed values
document.addEventListener('DOMContentLoaded', function() {
// Precompute the natsValues as soon as the page loads
precomputedNatsValues = decodeNats();
//check preconfig values
console.log('Precomputed nats values: ' + JSON.stringify(precomputedNatsValues));
let isSubmitting = false;
document.getElementById('natsPreJoinForm').addEventListener('submit', async function(event) {
if (isSubmitting) return;
isSubmitting = true;
event.preventDefault();
// Async function to hash email
async function hashEmail(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase());
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
try {
const email = document.getElementById('usernameemail').value;
const hashedEmail = await hashEmail(email);
document.getElementById('hashedEmailInput').value = hashedEmail;
document.getElementById('hashedEmailInputRkt').value = hashedEmail;
document.getElementById('waiter').style.visibility = 'visible';
// Use the precomputed nats values directly
console.log('Using precomputed nats values: ' + JSON.stringify(precomputedNatsValues));
const selectedOption = document.querySelector('.option.pressed-button');
if (!selectedOption) {
throw new Error('No option selected');
}
const optionId = selectedOption.id.split('-')[ 1];
const priceCurrency = selectedOption.querySelector('.price-currency')?.textContent || '$';
const priceWhole = selectedOption.querySelector('.price-init')?.textContent || '0';
const priceCents = selectedOption.querySelector('.price-cents')?.textContent || '.00';
const signUpValue = parseFloat(priceWhole + priceCents).toFixed(2);
const eventDetails = {
"send_to": "G-CVZ4RHQ130",
"user_id": hashedEmail,
"method": "email",
"event_category": "registration",
"event_action": optionId,
"event_label": hashedEmail,
"event_currency": priceCurrency,
"event_value": signUpValue,
...precomputedNatsValues
};
gtag("event", "sign_up", eventDetails);
console.log("Event sent with dynamic values: ", eventDetails);
event.target.submit(); // Programmatically submit the form
} catch (error) {
console.error("Error:", error);
} finally {
document.getElementById('waiter').style.visibility = 'visible';
}
});
});
</script>
{/literal}
<!-- rewrote get natstour --<
{assign var=nats_TourID}
{nats_decode nats=$nats_code}
{if $decoded.tourid}
{assign var=nats_TourID value=$decoded.tourid}
{/if}
<!-- // find tour ID -->
</head>
<body class="nocoupon">
{literal}
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-WGG88K" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->
{/literal}
<div id="natstourid{$nats_TourID}">
<!-- // Form elements -->
<form class="rel" id="natsPreJoinForm" target="_top" action="signup.php">
<input type="hidden" id="nats" name="nats" value="{$nats_code}">
<input type="hidden" name="step" value="signup">
<input type="hidden" name="tpl" value="default_join">
<input type="hidden" name="formloaded" value="1">
<input type="hidden" name="username" value="{$vars.username}">
<input type="hidden" name="signup[ rename_old_member]" value="1">
<input type="hidden" name="signup[ custom1]" value="{$smarty.request.jlinkcloc}">
<input type="hidden" id="hashedEmailInput" name="signup[ custom10]" value=""><!-- // adding hash to custom 10 -->
<input type="hidden" id="hashedEmailInputRkt" name="nextra[ RGNATIVE][ udf02]" value=""><!-- // sending hash to rockegate so they can pass back on approval -->
<input style="width:15px;" type="hidden" name="signup[ mailok]" value=1 checked></input>
Guerilla Registration page – no NATS vars
VERSION 2
{literal}
<!-- ANALYTICS -->
<script>
async function hashEmail(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase());
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
return hashHex;
}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('natsPreJoinForm').addEventListener('submit', async function(event) {
event.preventDefault();
// Fetch dynamic values right before form submission
const email = document.getElementById('usernameemail').value;
const hashedEmail = await hashEmail(email);
// to custom 10
hashEmail(email).then(hashedEmail => {
document.getElementById('hashedEmailInput').value = hashedEmail;
console.log("Before sending registration event");
// Identify the selected option with 'pressed-button' class
const selectedOption = document.querySelector('.option.pressed-button');
if (!selectedOption) {
console.error('No option selected');
return; // Optionally handle the error
}
// Extract optionId from the selected element's id attribute
const optionId = selectedOption.id.split('-')[1]; // Assumes id format is "option-XXXX"
// Extract pricing details
const priceCurrency = selectedOption.querySelector('.price-currency')?.textContent || '$';
const priceWhole = selectedOption.querySelector('.price-init')?.textContent || '0';
const priceCents = selectedOption.querySelector('.price-cents')?.textContent || '.00';
const signUpValue = priceWhole + priceCents; // Concatenate whole number and cents
// Construct the event details with dynamic values
const eventDetails = {
"send_to": "G-1688HPPTWW",
"user_id": hashedEmail,
"method": "email",
"event_category": "registration",
"event_action": optionId,
"event_label": hashedEmail, // can't use memberid
"event_currency": priceCurrency,
"event_value": signUpValue
};
// Send the event with dynamic values
gtag("event", "sign_up", eventDetails);
console.log("Event sent with dynamic values: ", eventDetails);
console.log("hashedEmail: ", hashedEmail); // Corrected console.log to display the hashed email
console.log("optionID: ", optionId);
console.log("priceCurrency: ", priceCurrency);
console.log("signUpValue: ", signUpValue);
console.log("After sending registration event");
event.target.submit();
}).catch(error => {
console.error("Hashing failed:", error);
document.getElementById('waiter').style.visibility = 'hidden';
});
});
});
</script>
{/literal}
=====================================================
VERSION 1
{literal}
<script>
async function hashEmail(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase()); // Encode as (lowercase) UTF-8
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // Hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // Convert bytes to hex string
return hashHex;
}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('guerillaPreJoinForm').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the form from submitting immediately
// Show the loading spinner
document.getElementById('waiter').style.visibility = 'visible';
const email = document.getElementById('usernameemail').value;
hashEmail(email).then(hashedEmail => {
// Set the hashed email in the hidden input
document.getElementById('hashedEmailInput').value = hashedEmail;
alert("hashed email: " + hashedEmail);
console.log("Before sending registration event");
// Now that we have the hashed email, update GA4 tracking to mark a registration event
gtag('event', 'registration', {
'send_to': 'G-1688HPPTWW',
'user_id': hashedEmail, // Use the hashed email as the user_id for consistent tracking
// You can include additional parameters here as needed
});
console.log("hashedEmail: ", hashedEmail); // Corrected console.log to display the hashed email
console.log("After sending registration event");
// After setting the user_id and sending the registration event, submit the form
event.target.submit();
}).catch(error => {
console.error("Hashing failed:", error);
// Optionally, handle the error, e.g., by hiding the spinner and notifying the user
document.getElementById('waiter').style.visibility = 'hidden';
}); // This closes the .catch block
}); // This closes the addEventListener for 'submit'
}); // This closes the addEventListener for 'DOMContentLoaded'
</script>
{/literal}
Guerilla Registration page – expanded (not working yet)
{literal}
<script>
async function hashEmail(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase()); // Encode as (lowercase) UTF-8
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // Hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // Convert bytes to hex string
return hashHex;
}
document.getElementById('guerillaPreJoinForm').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the form from submitting immediately
// Show the loading spinner
document.getElementById('waiter').style.visibility = 'visible';
const email = document.getElementById('usernameemail').value;
hashEmail(email).then(hashedEmail => {
document.getElementById('hashedEmailInput').value = hashedEmail;
// Now that we have the hashed email, set it as the user_id for GA4 tracking
gtag('config', 'G-CVZ4RHQ130', {'user_id': hashedEmail});
// Send a specific event to track the registration
{/literal}
gtag('event', 'registration', {
'send_to': 'G-CVZ4RHQ130',
"currency": "{$option_parts.1|addslashes}",
"transaction_id": "{$member.memberidx|addslashes}",
"value": {$option_parts.2}.{$option_parts.3},
"affiliation": "{$signup.nats}",
"items": [{
"item_id": "{$signup.optionid}",
"item_name": "{$option.details.name|addslashes}",
"affiliation": "{$signup.nats}",
"coupon": null,
"discount": 0,
"item_brand": "{$site.site|addslashes}",
"item_category": "Membership",
"price": {$member.spent/100},
"quantity": 1
}]
});
{literal}
// After setting the user_id and sending any events, submit the form
event.target.submit();
}).catch(error => {
console.error("Hashing failed:", error);
// Optionally, handle the error, e.g., by hiding the spinner and notifying the user
document.getElementById('waiter').style.visibility = 'hidden';
});
});
</script>
{/literal}
Guerilla Approval Page
VERSION 2
<!-- Guerilla Porn Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-1688HPPTWW"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date()); gtag('config', 'G-1688HPPTWW');
window.onload = function() {
gtag('event', 'purchase', {
{/literal}
"currency": "{$transaction.biller_currency|addslashes}",
"transaction_id": "{$member.memberidx|addslashes}",
"value": {$member.spent/100},
"affiliation": {$member.memberid},
{literal}
"items": [
{
{/literal}
"item_id": {$member.optionid},
"item_name": "{$option.details.name|addslashes}",
"affiliation": {$member.memberid},
"coupon": null,
"discount": 0,
"item_brand": "{$site.site|addslashes}",
"item_category": "Membership",
"price": {$member.spent/100},
"quantity": 1
{literal}
}
]
});
};
</script>
NS PreJoin Page
{literal}
<script>
async function hashEmail(email) {
const msgUint8 = new TextEncoder().encode(email.toLowerCase()); // Encode as (lowercase) UTF-8
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8); // Hash the message
const hashArray = Array.from(new Uint8Array(hashBuffer)); // Convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // Convert bytes to hex string
return hashHex;
}
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('guerillaPreJoinForm').addEventListener('submit', function(event) {
event.preventDefault(); // Prevent the form from submitting immediately
// Show the loading spinner
document.getElementById('waiter').style.visibility = 'visible';
const email = document.getElementById('usernameemail').value;
hashEmail(email).then(hashedEmail => {
// Set the hashed email in the hidden input
document.getElementById('hashedEmailInput').value = hashedEmail;
alert("hashed email: " + hashedEmail);
console.log("Before sending registration event");
// Now that we have the hashed email, update GA4 tracking to mark a registration event
gtag('event', 'registration', {
'send_to': 'G-CVZ4RHQ130',
'user_id': hashedEmail, // Use the hashed email as the user_id for consistent tracking
// You can include additional parameters here as needed
});
console.log("hashedEmail: ", hashedEmail); // Corrected console.log to display the hashed email
console.log("After sending registration event");
// After setting the user_id and sending the registration event, submit the form
event.target.submit();
}).catch(error => {
console.error("Hashing failed:", error);
// Optionally, handle the error, e.g., by hiding the spinner and notifying the user
document.getElementById('waiter').style.visibility = 'hidden';
});
});
});
</script>
{/literal}
NS Approval Page
{literal}
<script>
document.addEventListener('DOMContentLoaded', function() {
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-CVZ4RHQ130');
gtag('event', 'purchase', {
{/literal}
"currency": "{$transaction.biller_currency|addslashes}",
"transaction_id": "{$member.memberidx|addslashes}",
"value": {$member.spent/100},
"items": [
{
"item_id": {$member.optionid},
"item_name": "{$option.details.name|addslashes}",
"affiliation": "{$member.memberid}",
"coupon": null,
"discount": 0,
"item_brand": "{$site.site|addslashes}",
"item_category": "Membership",
"price": {$member.spent/100},
"quantity": 1
}
{literal}
]
});
});
</script>
{/literal}
{literal}
<!-- NakedSword.com Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CVZ4RHQ130"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date()); gtag('config', 'G-CVZ4RHQ130');
gtag('event', 'purchase', {
{/literal}
"currency": "{$transaction.biller_currency|addslashes}",
"transaction_id": "{$member.memberidx|addslashes}",
"value": {$member.spent/100}
{literal}
"items": [
{
{/literal}
"item_id": {$member.optionid},
"item_name": "{$option.details.name|addslashes}",
"affiliation": {$member.memberid},
"coupon": null,
"discount": 0,
"item_brand": "{$site.site|addslashes}",
"item_category": "Membership",
"price": {$member.spent/100},
"quantity": 1
{literal}
}
]
});
</script>