Skip to content

Instantly share code, notes, and snippets.

@vogler
Last active June 30, 2025 12:15
Show Gist options
  • Save vogler/5bb22703e2dc95f6bc4eb0c35abcd600 to your computer and use it in GitHub Desktop.
Save vogler/5bb22703e2dc95f6bc4eb0c35abcd600 to your computer and use it in GitHub Desktop.
Download all Videos from Ring Event History website
// Even with a subscription, videos are saved online only for 180 days.
// Downloading videos manually is a pain since you can only download 150 at a time, and 'Select Multiple' only has up to 'First 150'.
// Tried API, but only gave last 100 videos: https://github.com/vogler/ring-video-downloader
const b = 150; // videos to download at a a time
const sleep = s => new Promise(r => setTimeout(r, s*1000));
// 1. Go to https://account.ring.com/account/activity-history
// 2. Click button 'Manage'.
// 3. Scroll down in the event list to load as many events as you want.
// 4. Open Chrome Dev Tools (cmd+alt+i) and open Console to paste the following:
const f = async (xs, i) => {
const n = xs.length;
xs.slice(Math.max(0, n-i*b), Math.max(0, n-(i-1)*b)).map(x => x.click());
document.querySelector('button[data-testid="manage-events__download"]').click(); // Download; TODO somehow this does not work anymore -> click download manually
document.querySelector('button[data-testid="manage-events__select-multiple"]').click(); // Deselect
};
es = Array.from(document.querySelectorAll('[role=checkbox]'));
// alternative: select not yet downloaded videos
// let n = 0;
// for (const e of es) {
// const labels = e.querySelector('section')?.innerText ?? '';
// if (labels.includes('Downloaded')) continue;
// e.click();
// n++;
// if (n == 150) break;
// }
// manual:
es.length; // to see how many entries there are
f(es, 1); // downloads the first pack of 50 videos from the end of the list
f(es, 2); // ... continue until you reach the top
// or in a loop with waiting for downloads inbetween:
let go = true;
for (let i = 1; i <= es.length/b; i++) {
if (!go) break;
console.log(`${i} out of ${es.length/b}`);
await f(es, i);
await sleep(60);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment