What it does
1 female + 1 male · Div 3 · free
Posted by Daniel Harrold · NEC FC need 2x players for today's game at 1.30PM - FREE
- Reads the group feed you already have open (or opens it briefly in a background tab) and pulls out each post's id, author, text and age.
- Classifies the post. Only "a team needs fill-in players" posts alert. It stays quiet for players looking to join a team, posts already sorted or cancelled, and anything with no kick-off time in it.
- Extracts the useful bits: kick-off time, day, number of players, whether they want a specific gender or a goalkeeper, division and cost.
- Alerts once, obviously. A sticky Chrome notification that stays until you deal with it, a three-beep chime, and a red badge on the toolbar icon. Clicking it opens the post.
- Optionally pushes it to your phone via ntfy. Off by default, and the only thing this extension ever sends anywhere.
Only new posts, never a backlog
- A seen-set. Every post id it has looked at is remembered locally (most recent 500). A post alerts at most once, ever.
- A baseline on first run. The first scan after install marks everything already in the feed as seen and alerts for none of it.
- An age gate. Posts older than your chosen window (default 1.5 hours) are ignored, so scrolling back can't trigger anything. Because this group holds posts for admin approval, age is the smaller of the post's written time and its visible "15m" stamp, so an approval-delayed post still counts as new.
Keeping the feed fresh
If the group is open in a tab, that tab is reloaded on a timer (default every 3 minutes) unless it currently has focus, in which case it is just re-scanned. If no group tab is open, background check (on by default) opens the group in an inactive tab, reads it, and closes it about a minute later.
Phone push (optional)
Chrome only alerts the machine it runs on. Also alert my phone sends the same alert through ntfy, a free pub/sub notification service with no account and no signup: your desktop publishes to a topic, the ntfy app on your phone is subscribed to it and rings. Setup is about two minutes: install the ntfy app, click Generate a topic in the popup, subscribe to that topic in the app, switch the option on, and Test phone push.
- Push is best-effort; the desktop notification is not. The push is sent after the desktop notification, so a dead network never costs you the alert on the machine you are at.
- One retry, then it gives up, and the failure is shown in the popup's status line.
- It still needs Chrome running on the desktop. The phone is a second screen, not an independent watcher.
- ntfy.sh is a free public service run by a third party; it can be slow, rate-limited or down. Self-host if that matters.
- The topic and token live in
chrome.storage.sync, so they follow your Chrome profile.
What it can touch
| Manifest entry | Why it is there |
|---|---|
permissions: ["storage"] | Your settings (chrome.storage.sync) and the seen-post set plus recent alert list (chrome.storage.local). |
permissions: ["notifications"] | The entire feature is a desktop notification. |
permissions: ["alarms"] | An MV3 service worker is killed within seconds of going idle; chrome.alarms is the only supported way to poll on a schedule. |
permissions: ["offscreen"] | Service workers have no DOM and cannot play audio. A tiny offscreen document exists purely to sound the chime. |
host_permissions | None. Not requested, not needed. |
optional_host_permissions: ["https://ntfy.sh/*"] | Phone push only. Optional: not granted at install, requested the moment you switch phone push on, revocable any time from chrome://extensions. One origin, no wildcards. Leave phone push off and it is never granted. |
content_scripts.matches: ["https://www.facebook.com/groups/*"] | HTTPS only, and only group pages. Your home feed, Messenger, Marketplace, profiles and every other site are never touched. |
content_scripts.all_frames: false | Top-level document only. |
content_security_policy | script-src 'self'; object-src 'self'; base-uri 'none': no remote code, no eval, no inline script. |
The tabs permission is deliberately not requested even though the extension reloads, creates and closes tabs: those specific calls don't need it, and it would grant read access to the URL and title of every tab you have open.
What data it reads, stores or sends
- Reads the text, author name, post id and timestamp of posts in the configured group, only while a group page is open in a tab.
- Stores, all locally in your browser: your settings, up to 500 already-seen post ids, the last 20 alert headlines, the id of your group tab and the last check time.
- Sends nothing at all unless you turn on phone push. With phone push off, the default, the extension makes zero network requests of its own. With it on, one HTTPS POST per new alert goes to ntfy.sh (or your own server) carrying the topic, the headline, the summary line, the post text if you allow it, the author's name and a link to the post. Nothing that identifies you, your browser or your machine is included; ntfy sees your IP address, as any server you POST to does.
What it does not do
- Does not post, comment, react, DM or click anything on your behalf. It does not even click "See more".
- Does not read your home feed, messages, friends list, or any page outside
/groups/. - Does not read cookies, tokens or credentials, and does not modify the Facebook page.
- Does not read anything back from ntfy; publishing is one-way and nothing the server returns is parsed or acted on.
- No
innerHTML,eval,localStorageor remotely loaded code. The chime is synthesised with the Web Audio API; there are no bundled downloads.
Honest limitations
- Facebook's DOM is a moving target. The extension anchors on
[role="feed"], three specific post-body attributes and the permalink'saria-label, all verified live against the real group. Facebook can rename any of them without notice; if alerts stop, that is the first thing to check. - Facebook fights scraping with decoy spans and scrambled timestamps, which is why the body is read from a specific attribute and a post without one is skipped rather than guessed at.
- Long posts truncated by "See more" are skipped if the kick-off time is behind the fold, rather than mis-reported.
- The parser is heuristic, tuned against 60+ real posts (175 checks in
tests/parser.test.mjs). It will occasionally miscount an unusual phrasing; the notification always includes the original text so you can check. - Bare times are guessed by league hours: "1.30" becomes 1:30pm because these leagues run roughly 9am to 9:30pm. A genuine 1:30am game would be reported wrong.
- Photo-only posts are never detected.
- Background check opens a real tab. It is inactive and closes itself, but it will briefly appear in your tab strip and count as a page view on Facebook. Turn it off if you'd rather only scan a tab you opened yourself.
- The service worker can be asleep. Chrome may delay alarms on battery saver or when idle, so "every 3 minutes" is a target, not a guarantee.
- It only works while Chrome is running, on the desktop or the phone.
Tests
From chrome-extensions/:
node tests/parser.test.mjs # 175 checks over 60+ real posts from the group
node tests/push.test.mjs # 54 checks on the ntfy payload builder + retries
node tests/owasp-audit.mjs # static security audit of every extension here
Install
- Download or clone the repo.
- Open
chrome://extensionsand turn on Developer mode (top right). - Click Load unpacked and choose the
chrome-extensions/facebook-group-player-wanted-alertsfolder.
Then allow notifications for Chrome if macOS or Windows prompts. On macOS also set System Settings → Notifications → Google Chrome to Alerts (not Banners) so the alert stays on screen, and click Test alert in the popup to confirm the notification and chime both land.