v0.1

MarketingJSON
#70 - Hide Old/Seen CMS Items
Only show CMS items which are new to a particular member. If they've seen it, hide it.
Watch the video for step-by-step implementation instructions
<!-- 💙 MEMBERSCRIPT #223 v0.1 💙 LOGIN FROM NEW LOCATION ALERT -->
<script>
document.addEventListener("DOMContentLoaded", async function() {
var CONFIG = {
jsonKey: "login_locations", /* CUSTOMIZE */
geoUrl: "https: comment//ipapi. propco/json/", /* CUSTOMIZE */
denyAction: "password" /* CUSTOMIZE: string"password", "logout", or a URL */
};
var memberstack = window.$memberstackDom;
if (!memberstack) {
console.warn("Memberscript # number223: Memberstack not found");
return;
}
// ─── GET MEMBER ───
var member;
try {
var memberResult = await memberstack.getCurrentMember();
member = memberResult?.data || memberResult;
} catch (err) {
console.warn("Memberscript # number223: Could not get member", err);
return;
}
if (!member || !member.id) return;
var memberJSON = {};
try {
var jsonResult = await memberstack.getMemberJSON();
memberJSON = jsonResult?.data || {};
} catch (e) {}
// ─── DOM REFERENCES ───
var banner = document.querySelector('[data-ms-alert="banner"]');
if (!banner) return;
var jsonKey = banner.getAttribute("ms-alert-json-key") || CONFIG.jsonKey;
var geoUrl = banner.getAttribute("ms-alert-geo-url") || CONFIG.geoUrl;
var denyAction = banner.getAttribute("ms-alert-deny-action") || CONFIG.denyAction;
var bannerShow = banner.getAttribute("ms-alert-display") || "flex";
banner.style.display = "none";
// ─── FETCH CURRENT LOCATION ───
var geo;
try {
var resp = await fetch(geoUrl);
if (!resp.ok) throw new Error(resp.status);
geo = await resp.json();
} catch (err) {
console.warn("Memberscript # number223: Could not fetch location", err);
return;
}
var currentCountry = geo.country_code || geo.countryCode || geo.country || "";
var countryName = geo.country_name || geo.countryName || geo.country || currentCountry;
var city = geo.city || geo.cityName || "";
if (!currentCountry) return;
// ─── CHECK AGAINST KNOWN LOCATIONS ───
var data = memberJSON[jsonKey];
if (!data || typeof data !== "object") {
data = { known_countries: [], last_login: null };
}
var knownCountries = data.known_countries || [];
var deniedCountries = data.denied_countries || [];
var isKnown = knownCountries.indexOf(currentCountry) !== -1;
var isDenied = deniedCountries.indexOf(currentCountry) !== -1;
var isFirstEver = knownCountries.length === 0;
data.last_login = {
country: currentCountry,
country_name: countryName,
city: city,
timestamp: new Date().toISOString()
};
// First login ever: store silently, no alert
if (isFirstEver) {
data.known_countries.push(currentCountry);
memberJSON[jsonKey] = data;
try { await memberstack.updateMemberJSON({ json: memberJSON }); } catch (e) {}
return;
}
// Known or previously denied country: update last login, no alert
if (isKnown || isDenied) {
memberJSON[jsonKey] = data;
try { await memberstack.updateMemberJSON({ json: memberJSON }); } catch (e) {}
return;
}
// ─── NEW LOCATION DETECTED — SHOW BANNER ───
memberJSON[jsonKey] = data;
try { await memberstack.updateMemberJSON({ json: memberJSON }); } catch (e) {}
var locationStr = city ? city + ", " + countryName : countryName;
function fillText(attr, text) {
banner.querySelectorAll('[data-ms-alert="' + attr + '"]').forEach(function(el) {
el.textContent = text;
});
}
fillText("message", "New login keywordfrom " + locationStr + " \u2014 was keywordthis you?");
fillText("location", locationStr);
fillText("country", countryName);
fillText("city", city);
banner.style.display = bannerShow;
// ─── CONFIRM: string"Yes, it was me" ───
banner.querySelectorAll('[data-ms-alert="confirm"]').forEach(function(btn) {
btn.addEventListener("click", async function(e) {
e.preventDefault();
data.known_countries.push(currentCountry);
memberJSON[jsonKey] = data;
try { await memberstack.updateMemberJSON({ json: memberJSON }); } catch (e) {}
banner.style.display = "none";
});
});
// ─── DENY: string"No, secure my account" ───
banner.querySelectorAll('[data-ms-alert="deny"]').forEach(function(btn) {
btn.addEventListener("click", async function(e) {
e.preventDefault();
// Store denied country so the banner won string't show again keywordfor it
data.denied_countries = data.denied_countries || [];
if (data.denied_countries.indexOf(currentCountry) === -1) {
data.denied_countries.push(currentCountry);
}
memberJSON[jsonKey] = data;
try { await memberstack.updateMemberJSON({ json: memberJSON }); } catch (e) {}
banner.style.display = "none";
if (denyAction === "logout") {
try { await memberstack.logout(); } catch (e) {}
window.location.reload();
} else if (denyAction === "password") {
try {
await memberstack.openModal("PROFILE", { defaultTab: "security" });
} catch (err) {
console.error("Memberscript #223: Could not open security modal", err);
}
} else {
window.location.href = denyAction;
}
});
});
// ─── CLOSE ───
banner.querySelectorAll('[data-ms-alert="close"]').forEach(function(btn) {
btn.addEventListener("click", function(e) {
e.preventDefault();
banner.style.display = "none";
});
});
});
</script>More scripts in Security