Instantly share code, notes, and snippets.
Created
October 25, 2021 18:58
-
Save djirdehh/c4b28c072a54957398bf4363c8739a75 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Override Instacart Ads Manager flippers | |
// @namespace https://ads.instacart.com/ | |
// @version 0.6 | |
// @updateURL https://gist.githubusercontent.com/jiang925/94b31524a7f38d32000c20797f1d53db/raw/override-flippers.user.js | |
// @downloadURL https://gist.githubusercontent.com/jiang925/94b31524a7f38d32000c20797f1d53db/raw/override-flippers.user.js | |
// @description Override Instacart Ads Manager flippers from UI. Note that this only affects pure UI flippers. This does not affects the flippers on the backend. | |
// @author Tian Jiang | |
// @include *://*.instacart.com/* | |
// @include *://*-web-ads-stg.instacart.team/* | |
// @include *://localhost:4000/* | |
// @require http://code.jquery.com/jquery-3.5.0.min.js | |
// @run-at document-start | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// ==/UserScript== | |
(function () { | |
"use strict"; | |
const toggleStyle = ` | |
<style> | |
/* Change header colour*/ | |
._ko16_widget_top_cntr { | |
background-color: white; | |
padding: 25px 10px 14px 37px; | |
} | |
/* Align title left and update color. */ | |
._ko16_widget_title { | |
color: #424242; | |
text-align: left; | |
font-size: 18px; | |
} | |
/* Update close button styles. */ | |
._ko16_widget_close_cntr svg { | |
fill: #757575; | |
height: 18px; | |
width: 18px; | |
position: absolute; | |
right: 16px; | |
bottom: 2px; | |
} | |
/* Update back button styles. */ | |
._ko16_widget_back svg { | |
fill: #757575; | |
top: 24px; | |
position: absolute; | |
left: 8px; | |
height: 20px; | |
width: 20px; | |
} | |
.override-flipper-drawer textarea.full { | |
width: 100%; | |
height: 300px; | |
} | |
.override-flipper-drawer textarea.half { | |
width: 100%; | |
height: 150px; | |
} | |
</style>`; | |
const $ko = $(` | |
<div id="_ko16-widget-wrapper" class="_ko16-widget-wrapper override-flipper-drawer" style="width: 480px;"> | |
<input type="hidden" id="rgroups" name="groups" value="5d5d98b58e121c3022464519"> | |
<div class="_ko16_widget_top_cntr"> | |
<div class="_ko16_widget_back" style="display:none;"> | |
<svg viewBox="0 0 34 60" preserveAspectRatio="xMinYMid"> | |
<path d="M1.2,32.8l26,26c0.7,0.7,1.7,1.2,2.8,1.2c2.2,0,4-1.8,4-4c0-1.1-0.4-2.1-1.2-2.8L9.7,30 L32.8,6.8C33.6,6.1,34,5.1,34,4c0-2.2-1.8-4-4-4c-1.1,0-2.1,0.4-2.8,1.2l-26,26C0.4,27.9,0,28.9,0,30C0,31.1,0.4,32.1,1.2,32.8z"></path> | |
</svg> | |
</div> | |
<div class="_ko16_widget_title">Overrider Flippers</div> | |
<div id="_ko16_widget_close_cntr" class="_ko16_widget_close_cntr"> | |
<svg viewBox="0 0 60 60" preserveAspectRatio="xMinYMid"> | |
<path d="M35.7,30L58.8,6.8C59.6,6.1,60,5.1,60,4c0-2.2-1.8-4-4-4c-1.1,0-2.1,0.4-2.8,1.2L30,24.3 | |
L6.8,1.2C6.1,0.4,5.1,0,4,0C1.8,0,0,1.8,0,4c0,1.1,0.4,2.1,1.2,2.8L24.3,30L1.2,53.2C0.4,53.9,0,54.9,0,56c0,2.2,1.8,4,4,4 | |
c1.1,0,2.1-0.4,2.8-1.2L30,35.7l23.2,23.2c0.7,0.7,1.7,1.2,2.8,1.2c2.2,0,4-1.8,4-4c0-1.1-0.4-2.1-1.2-2.8L35.7,30z"></path> | |
</svg> | |
</div> | |
</div> | |
</div> | |
`); | |
const interestingData = {}; | |
(function (open) { | |
XMLHttpRequest.prototype.open = function () { | |
this.addEventListener( | |
"readystatechange", | |
function () { | |
if (this.readyState != 4) { | |
return; | |
} | |
if (this.responseURL.endsWith("/api/auth")) { | |
const json = JSON.parse(this.response); | |
console.log(JSON.parse(this.response)); | |
const overridenFlippers = JSON.parse( | |
GM_getValue("override-flippers") || '{ "on": [], "off": [] }' | |
); | |
const overridenFlippersOn = [].concat(overridenFlippers.on); | |
const overridenFlippersOff = [].concat(overridenFlippers.off); | |
if ( | |
!json || | |
!json.data || | |
!json.data.attributes || | |
!json.data.attributes.flippers | |
) { | |
console.log("no flippers"); | |
return; | |
} | |
const flippers = [] | |
.concat(json.data.attributes.flippers, overridenFlippersOn) | |
.filter( | |
(v, i, a) => | |
a.indexOf(v) === i && !overridenFlippersOff.includes(v) | |
); | |
interestingData.user_id = json.data.attributes.user_id; | |
interestingData.user_type = json.data.attributes.user_type; | |
interestingData.user_uuid = json.data.attributes.user_uuid; | |
json.data.attributes.flippers = flippers; | |
Object.defineProperty(this, "response", { writable: true }); | |
Object.defineProperty(this, "responseText", { writable: true }); | |
this.response = JSON.stringify(json); | |
this.responseText = JSON.stringify(json); | |
} | |
}, | |
false | |
); | |
open.apply(this, arguments); | |
}; | |
})(XMLHttpRequest.prototype.open); | |
const toggleDrawer = function ($drawer) { | |
const closed = "_ko16-widget-closed"; | |
const open = "_ko16-widget-open"; | |
if ($drawer.hasClass(open)) { | |
$drawer.addClass(closed).removeClass(open); | |
} else { | |
$drawer.removeClass(closed).addClass(open); | |
} | |
}; | |
const $toggle = $( | |
'<div class="override-flippers-toggle open"><div></div></div>' | |
); | |
const injectDrawer = function () { | |
if ($(".override-flipper-drawer").length) | |
return $(".override-flipper-drawer"); | |
const $button = $('div[data-testid="change-account"] button'); | |
// inject css | |
$( | |
'<link rel="stylesheet" href="https://instacart-ads.knowledgeowl.com/css/widget_responsive_min.css" />' | |
).appendTo("head"); | |
$(toggleStyle).appendTo("head"); | |
const $clone = $ko.clone(); | |
const $title = $clone.find("._ko16_widget_title"); | |
$title.text("Overrider Flippers"); | |
const $close = $clone.find("._ko16_widget_close_cntr"); | |
$clone.find("._ko16_widget_top_cntr").nextAll().remove(); | |
$close.click(function () { | |
toggleDrawer($clone); | |
}); | |
$clone.addClass("override-flipper-drawer"); | |
$("body").append($clone); | |
const pageFlippers = JSON.parse(sessionStorage.getItem("flippers")); | |
const overridenFlippers = JSON.parse( | |
GM_getValue("override-flippers") || '{ "on": [], "off": [] }' | |
); | |
const overridenFlippersOn = [].concat(overridenFlippers.on); | |
const overridenFlippersOff = [].concat(overridenFlippers.off); | |
$("<div />").html("Flippers on the page").appendTo($clone); | |
$("<textarea readonly />") | |
.addClass("full") | |
.html(pageFlippers.join("\n")) | |
.appendTo($clone); | |
$("<div />").html("Flippers to enforce on").appendTo($clone); | |
const $on = $("<textarea />") | |
.addClass("half") | |
.html(overridenFlippersOn.join("\n")) | |
.appendTo($clone); | |
$($button.clone()[1]) | |
.html("clear") | |
.appendTo($clone) | |
.click(function () { | |
$on.val(""); | |
}); | |
$("<div />").html("Flippers to enforce off").appendTo($clone); | |
const $off = $("<textarea />") | |
.addClass("half") | |
.html(overridenFlippersOff.join("\n")) | |
.appendTo($clone); | |
$($button.clone()[1]) | |
.html("clear") | |
.appendTo($clone) | |
.click(function () { | |
$off.val(""); | |
}); | |
$($button.clone()[1]) | |
.html("Save") | |
.appendTo($clone) | |
.click(function () { | |
const on = $on.val().split("\n"); | |
const off = $off.val().split("\n"); | |
const overrides = { on, off }; | |
GM_setValue("override-flippers", JSON.stringify(overrides)); | |
}); | |
// Add the interesting data | |
$("<div />") | |
.html( | |
"user_id: " + | |
interestingData.user_id + | |
"<br />user_type: " + | |
interestingData.user_type + | |
"<br />user_uuid: " + | |
interestingData.user_uuid | |
) | |
.appendTo($clone); | |
return $clone; | |
}; | |
const handleButtonClick = function () { | |
const $drawer = injectDrawer(); | |
toggleDrawer($drawer); | |
console.log("my button clicked"); | |
}; | |
const injectButton = function ($box) { | |
const $button = $box.find("button:first").clone(); | |
$button.addClass("override-flipper-button"); | |
$button.click(handleButtonClick); | |
$button.css("margin-right", "24px"); | |
$button.text("Override Flippers"); | |
$box.prepend($button); | |
return $button; | |
}; | |
const injectUI = setInterval(function () { | |
// const $boxes = $('div[data-testid="change-account"]'); | |
const $boxes = $('div[data-testid="change-account__new-nav"]'); | |
if ($boxes.length) { | |
$boxes.each(function (i, box) { | |
const $box = $(box); | |
if ($box.find("button.override-flipper-button").length) return; | |
const $button = injectButton($box); | |
}); | |
} | |
}, 200); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment