Skip to content

Instantly share code, notes, and snippets.

@garyhtou
Last active October 16, 2024 02:02
Show Gist options
  • Save garyhtou/8b8a0df4f399ce657f5b3a8240251f27 to your computer and use it in GitHub Desktop.
Save garyhtou/8b8a0df4f399ce657f5b3a8240251f27 to your computer and use it in GitHub Desktop.
Venmo: Automatically switch privacy level to Private

So, here's a problem that likely no one has (except myself πŸ˜„).

First, some context: I use Venmo on both my phone and laptop. When on my phone, I generally want my Venmo transactions to have the Friends privacy level. However, when on my laptop, I usually use Private.

Now you may be wondering why? ~tangent~

My roommates & I usually do large grocery/Costco runs. I make Venmo requests from my laptop; each containing a "receipt" of items bought β€” all generated using a very elaborate Google Sheet. I'll save that story for another time. Since my roommates likely don't want their list of items out there for everyone to see, I'll use Private for these types of transactions. Other than that, I'll generally use Friends.

Anyways, the goal is to have Venmo default to Private on laptop, and Friends on mobile. Venmo does offer a default privacy setting. But that's account-wide, obviously.

Conveniently, the only Venmo requests I make from my laptop are these grocery run splits. So, my solution consists of:

  • Leaving my Venmo default privacy setting as Friends
  • Writing and using the following Arc Boost β€” oh yeah, I forgot to mention that I use Arc Browser

How does it work?

On page load, the Arc Boost will find the Privacy picker and change it to Private β€” pretty simple!

The only complicated portion was... "on page load". Venmo uses Next.js (yay), which means that there's not a true page load to trigger the Arc Boost to re-run. Instead, I had to create a MutationObserver to listen for Venmo's page load progress bar.

If you find this handy but hate the Arc requirement, you could most certainly throw this into a regular old Chrome/browser extension!

const privacyPicker = () => document.querySelector('button[class*="pay_privacyPicker"]');
const privacyValue = (button) => button.querySelector("h6").textContent;
const privacyOption = (option) => document.querySelector(`li[data-testid="item-${option}"]`);
const privacyPickerObserver = () => {
const observer = new MutationObserver((_mutationList, observer) => {
const picker = privacyPicker();
if (!picker) return; // Wait until button is in DOM
const defaultSetting = privacyValue(picker); // Get current privacy setting
// Let's change it to Private
if (defaultSetting === "Private") {
console.log(`Transaction's privacy is currently set to ${defaultSetting}.`);
observer.disconnect(); // No changes needed; we're done!
return;
};
picker.click(); // Open picker
const option = privacyOption("Private");
if (!option) return; // Wait for picker option to load; if false, it'll come in a future mutation
option.click();
console.log(`Transaction's privacy is now Private (was ${defaultSetting}).`);
observer.disconnect();
});
observer.observe(document, {childList: true, subtree: true});
return observer;
}
// Start observing on initial page load
let currentObserver = privacyPickerObserver();
new MutationObserver(() => {
// Listen specifically for React page routes
if(!document.querySelector("#nprogress")) return;
// Let's start listening for the privacy picker
if(currentObserver) currentObserver.disconnect(); // First disable old listener (in case it wasn't used)
currentObserver = privacyPickerObserver(); // Create new observer
}).observe(document, {childList: true, subtree: true});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment