Improve Reddit chat and media reliability

This commit is contained in:
jjbrunton committed 2026-08-08 20:37:25 +01:00
1 parent a44768c089
commit 345ec99348
14 files changed
+323 -676

No files matched your search

+1 -1
View File
@@ -14,4 +14,4 @@ This local Chrome extension exports `reddit.com` cookies and the current Reddit
The extension observes only requests to Reddit's Matrix homeservers, verifies the captured token with Matrix `whoami`, reads Reddit cookies, and saves the combined export locally. It does not send the dump to any server; you upload it directly to your RedditBot dashboard.
Before downloading, the extension independently resolves the current Reddit cookie identity and refuses the export unless its `t2` account ID matches Matrix `whoami`. Changing Reddit accounts clears the stored Matrix capture, so Reddit Chat must be reopened after every account switch.
Before downloading, the extension independently resolves the current identity through the open `www.reddit.com` tab and refuses the export unless its `t2` account ID matches Matrix `whoami`. If you switch accounts, reload Reddit Chat so the extension captures that account's current Matrix token.
@@ -3,7 +3,7 @@
"name": "RedditBot Session Exporter",
"version": "1.1.1",
"description": "Exports Reddit cookies and Reddit Chat credentials for a self-hosted RedditBot dashboard.",
"permissions": ["cookies", "downloads", "storage", "webRequest"],
"permissions": ["cookies", "downloads", "scripting", "storage", "webRequest"],
"host_permissions": [
"https://reddit.com/*",
"https://*.reddit.com/*",
@@ -26,27 +26,40 @@ chrome.webRequest.onBeforeSendHeaders.addListener(
});
await chrome.action.setBadgeText({ text: 'OK' });
await chrome.action.setBadgeBackgroundColor({ color: '#198754' });
await chrome.action.setTitle({ title: 'Reddit Chat token captured. Click to export.' });
},
{ urls: MATRIX_URLS },
['requestHeaders', 'extraHeaders'],
);
chrome.cookies.onChanged.addListener(async ({ cookie }) => {
if (!['reddit_session', 'token_v2'].includes(cookie.name)) return;
await chrome.storage.local.remove('matrixCapture');
await chrome.action.setBadgeText({ text: '' });
await chrome.action.setTitle({
title: 'Reddit account changed. Open Reddit Chat before exporting.',
});
});
async function getRedditIdentity() {
const response = await fetch('https://www.reddit.com/api/me.json', {
credentials: 'include',
cache: 'no-store',
const tabs = await chrome.tabs.query({
url: ['https://reddit.com/*', 'https://www.reddit.com/*'],
});
if (!response.ok) throw new Error('Reddit cookies did not authenticate. Sign in and try again.');
const payload = await response.json();
const tab = tabs.find((candidate) => candidate.active) ?? tabs[0];
if (tab?.id === undefined) {
throw new Error('Keep a signed-in www.reddit.com tab open while exporting.');
}
const [{ result } = {}] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
world: 'MAIN',
func: async () => {
try {
const response = await fetch('https://www.reddit.com/api/me.json', {
credentials: 'include',
cache: 'no-store',
});
if (!response.ok) return { error: 'Reddit cookies did not authenticate. Sign in and try again.' };
return { payload: await response.json() };
} catch {
return { error: 'Could not read the current Reddit account. Reload Reddit and try again.' };
}
},
});
if (result?.error) throw new Error(result.error);
const payload = result?.payload;
const account = payload?.data ?? payload;
if (!account?.name || !account?.id) {
throw new Error('Reddit did not return an authenticated account identity.');
@@ -93,6 +106,8 @@ chrome.action.onClicked.addListener(async () => {
...createSessionExportDownload(cookies, { ...matrixCapture, userId: identity.user_id }),
saveAs: true,
});
await chrome.action.setBadgeText({ text: 'OK' });
await chrome.action.setTitle({ title: 'RedditBot session export created.' });
} catch (error) {
await showError(error instanceof Error ? error.message : 'Could not create the session dump.');
}