PractiScore Neo icon

PractiScore Neo

A personal Discord bot that watches PractiScore club pages and DMs you when matches are posted, when registration opens, and when anything about a match you care about changes.

DM-only Owner-only Catches early opens Catches closes & reopens

Quick start

Everything happens in your DMs with the bot. Nobody else can use it, and it never posts in a server channel.

  1. Open a DM with the bot. In your server, click PractiScore Neo in the member list and choose Message. Type / to see its commands.
  2. Check it's healthy. Run /status. You want Scraping: On and Health: OK.
  3. See what's tracked. /clubs lists your clubs and /matches lists their upcoming matches.
  4. Add a club. /addclub url:https://practiscore.com/clubs/<club>. The reply lists its matches with a picker to star the ones you care about.
  5. Tune the noise. Use the Star / Normal / Mute buttons on alerts, /manage to change several matches at once, or set rules so new matches of a type start at the right level.
New to it? Remember two words.

A club's tier decides how often it's checked. A match's level decides what you're told about it. Muting a match never slows checking, and starring one never costs extra.

How it works

The bot loads each club's PractiScore page, such as practiscore.com/clubs/tps-uspsa. Every listed match has a registration label, which the bot reads as a state:

Label on the club pageStateMeaning
🟒 green openOpenYou can register now.
⏳ grey opens in 2 daysNot yet openRegistration opens later. The countdown is rounded down: 11 days shows as "1 week".
πŸ”’ grey closedClosedThe match director set it to Closed. The match stays listed.
❔ anything elseUnknownA label the bot hasn't seen before, such as full or waitlist. You get a DM so you can check the match yourself.

Alerts come from changes between checks: a match appearing, its state changing, its date changing, or it disappearing from the page.

That's why an early manual opening is caught. It doesn't matter what date registration was supposed to open: the moment the label turns green, the next check sees it.

Club tiers

A tier sets how often a club's page is checked. Change it with /tier.

TierCheckedDetails
watchedEvery 3 hoursDuring the day (8 AM – 9 PM ET). For clubs where you can't miss anything. New matches start ⭐ starred.
standardEvery 12 hoursFor clubs you follow casually. New matches start normal.
manualOnly when you askChecked when you /scan, then once a day only while a starred match is waiting to open. New matches start πŸ”‡ muted.
pausedNeverEverything is kept. When you un-pause, you get one summary of what changed instead of a flood of alerts.

One page load covers every match at a club, so the cost of a club depends only on its tier, not on how many matches it has.

Match levels

A level sets which alerts you get for a match. Change it with the buttons on any alert, /star, /unstar, /mute, /manage, the /scan picker, or rules.

Alert⭐ StarredNormalπŸ”‡ Muted
New match postedβœ“βœ“β€“
Registration now openβœ“βœ“β€“
Registration reopenedβœ“βœ“β€“
Registration closed / closed againβœ“β€“β€“
Match date changedβœ“β€“β€“
Match removed from listingβœ“β€“β€“
Match back on listingβœ“β€“β€“
Unrecognized registration labelβœ“βœ“βœ“
Extra checks around the opening timeβœ“βœ“β€“

Where a new match starts: the matching rule if there is one, otherwise the club tier's default (watched β†’ starred, standard β†’ normal, manual β†’ muted).

Alerts

Every alert is a DM. The coloured edge tells you what kind it is at a glance.

New Match Posted
TPS USPSA November
Date · Type · Registration: ⏳ Opens in 2 weeks
A match appears for the first time.
New Match β€” Registration ALREADY OPEN
TPS Steel - November
Registration: 🟒 Open
Posted with registration already open. Act fast.
Registration Now Open
Tactical Team Challenge
Register Now button
Opened, on schedule or early.
Registration Reopened
…
Register Now button
Opened again after being closed.
Registration Closed Again
…
Registration: πŸ”’ Closed
Was open, now closed or pushed back. Often an early open undone. Starred only.
Match Date Changed
TPS PCSL Carbine
October 24, 2026 β†’ January 23, 2027
The listed date changed. Starred only.
Match Removed from Listing
…
No link. The page is gone.
Missing on 2 checks in a row before its date: cancelled or deleted. Starred only.
Unrecognized Registration Label
…
Quotes the label, e.g. "full"
The bot can't read the state. Always sent, even for muted matches.
Catching up
Club summary
The club's listing plus "Changes: 2 new, 1 opened…"
After adding a club, un-pausing it, or turning scraping back on.

Every alert except "Match Removed" has Star Β· Normal Β· Mute buttons, and alerts with a match page have a View Match or Register Now link.

You'll also get a red Scraping is failing DM if checks keep failing (three in a row by default), and a green Scraping recovered DM when they work again. That's one pair per outage, not a DM every time a check fails.

When checks run

The bot looks every 5 minutes for anything that's due.

Regular checks

Regular checks follow each club's tier, and only between 8 AM and 9 PM Eastern. A watched club is checked about 8, 11 AM, 2, 5 and 8 PM, depending on when it was last checked. Restarting the bot doesn't trigger extra checks.

Registration-time checks

When a starred or normal match's label says "opens in N hours" or "opens in N minutes", the bot schedules extra checks around that moment. These run at any hour, including overnight.

They work the same at every tier except paused: a starred or normal match at a standard or manual club gets exactly the same extra checks as one at a watched club. The tier only decides how often a regular check comes along to read the countdown.

Label seenOpening is betweenExtra checks at
opens in 5 hours5 and 6 hours from now+5h 30m and +6h 2m
opens in 40 minutes40 and 41 minutes from now+42m
opens in 2 days / 1 weektoo far offnone yet. A later check will see hours

The evening checks see any opening before the next morning as hours, so an opening at 2 AM gets checked at about 2 AM.

How close to the opening the alert arrives

The first extra check lands halfway through the hour the countdown points to:

  • Opening in the second half of that hour: the halfway check sees "opens in N minutes" and schedules one more for just after. The alert arrives about 1–2 minutes after opening.
  • Opening in the first half: the halfway check finds it already open. The alert arrives up to 30 minutes after opening.
Blind spots: early opens and short notice.

If a match director opens registration early, before its listed time, there's no countdown to schedule from, so the bot sees it at the club's next regular check. During the day that's up to about 3 hours for a watched club and about 12 for a standard one. At night it's the first morning check (~8 AM).

A countdown is only seen in hours during the last day before opening. If a match is posted or rescheduled with less than a day's notice, a standard or manual club may not be checked in that window, and the opening is caught at the next regular check instead. For matches where minutes matter, make the club watched.

Rules

A rule sets the starting level of a club's newly posted matches based on their type or title.

/rule club:TPS USPSA text:Steel level:normal
/rule club:TPS USPSA text:PCSL level:muted

How text matches

  • It's compared against the match's type (e.g. Steel Challenge: Blank, USPSA level I, PCSL 1-GUN) and its title together.
  • Case doesn't matter, and it matches anywhere, even inside a word (pcsl matches PCSL 1-GUN).
  • It's literal text: no wildcards and no "or". Spaces and punctuation count.
  • If several rules match, the longest text wins, so a specific rule can override a broad one.
  • No match? The tier default applies (watched β†’ starred, standard β†’ normal, manual β†’ muted).
  • Rules only apply to matches posted after you create them. Change existing matches with /star, /unstar, /mute or the buttons.

Example at a watched club

MatchTypeRules Steel β†’ normal, PCSL β†’ muted
TPS USPSA OctoberUSPSA level Ino rule matches β†’ ⭐ starred
TPS HALLOWEEN Night SteelSteel Challenge: Blanknormal
Guardian Steel Training EventSteel Challenge: Blanknormal
TPS PCSL CarbinePCSL 1-GUNπŸ”‡ muted
Watch out for titles.

Challenge would also catch "Tactical Team Challenge", a USPSA match. USPSA catches almost every TPS match because the club name is in the titles. Copy the distinctive part of the Type field shown on any alert instead: it's more consistent than title words.

To remove a rule, run it again with level:remove. Every /rule reply lists the club's current rules, and /clubs shows them too.

Commands

All commands work in the bot's DMs only. Club and match names autocomplete as you type. /help command:<name> shows the same details inside Discord.

/status

/status

Whether scraping is on, whether recent checks succeeded, how many clubs are in each tier, when the next regular check is due, and the next registration-time check.

/clubs

/clubs

Each tracked club with its tier, when it was last checked, upcoming and starred match counts, its rules, and a link to its page.

/matches

/matches [club:<club>]

Upcoming matches with date, registration state and level (⭐ starred, πŸ”‡ muted). Reads the bot's saved data, so it's free and instant, but only as current as each club's last check.

Examples: /matches Β· /matches club:TPS USPSA

/manage

/manage club:<club>

One message for looking after a club, built from saved data, so opening it costs nothing. It lists the club's upcoming matches with their levels and has these controls:

Match menu + ⭐ Star Β· Normal Β· πŸ”‡ Mute
Select any number of matches, then press a level. The list redraws with the new icons, so you can do several batches in a row. Unlike the /scan picker, matches you don't select are never changed.
Tier menu
Same as /tier.
πŸ”„ Scan now 1 request
Checks the club and redraws the list with what changed. The only control that costs a request.
πŸ—‘ Remove club
Asks you to confirm first, then does the same as /removeclub.

Clubs with more than 25 upcoming matches get β—€ Prev / Next β–Ά buttons. The controls stop working after 30 minutes or a bot restart; run /manage again for fresh ones.

Example: /manage club:TPS USPSA

/addclub 1 request

/addclub url:<club page URL> [tier:<tier>]

url
The club's PractiScore page, https://practiscore.com/clubs/<club>. Find it by searching the club on practiscore.com and copying the address.
tier
watched (default), standard, manual or paused.

Loads the page once to confirm the club exists and get its name, then replies with its upcoming matches and a picker to star some. Existing matches don't each trigger a "new match" alert.

Example: /addclub url:https://practiscore.com/clubs/gainesville_practical_shooters tier:standard

/removeclub

/removeclub club:<club>

Stops tracking the club and deletes its matches, rules and scheduled checks. To stop checking but keep everything, use /tier with paused instead. /manage has a Remove button too.

/tier

/tier club:<club> tier:<watched|standard|manual|paused>

Changes how often a club is checked (see Club tiers). Leaving paused sends one catch-up summary on the next check. Existing matches keep their levels.

Example: /tier club:Friendly Gun Club tier:paused

/scan 1 request

/scan club:<club>

Checks a club right now, whatever its tier (even paused), and replies with its upcoming matches plus a picker. Use it to check on demand, or to pick matches at a manual club. Starring a manual club's match is how you ask to be told when its registration opens.

/star Β· /unstar Β· /mute

/star match:<match> Β· /unstar match:<match> Β· /mute match:<match>

Set one match's level: starred, normal (unstar) or muted. The match list autocompletes from upcoming matches and shows each one's current level.

/rule

/rule club:<club> text:<text> level:<starred|normal|muted|remove>

Sets the starting level for a club's new matches whose type or title contains text. See Rules.

Examples: /rule club:TPS USPSA text:Steel Challenge level:normal Β· /rule club:TPS USPSA text:PCSL level:remove

/scraping

/scraping state:<on|off>

Turns every scheduled check off or on. The bot stays online and commands still work. Handy for a break or to save requests. The setting survives restarts. Turning it back on sends one catch-up summary per club.

/usage

/usage

What the scraping service (Zyte) has charged this billing period, against the $100 monthly cap: dollars spent, requests and cost per 1,000, failed requests, a projection to the reset date, and the last 7 days. It asks Zyte's stats service, which doesn't use up any requests. The bot also DMs you once per period as spend passes 50%, 80% and 95% of the cap.

/help

/help [command:<command>]

Without a command: the command list plus a tier and level cheat sheet. With one: its description, usage and examples.

Example: /help command:rule

Buttons & picker

Star Β· Normal Β· Mute buttons

On every alert except "Match Removed". Tap one to set that match's level; the bot confirms with a short reply. The buttons keep working after the bot restarts. The highlighted button shows the level when the alert was sent.

The match picker

Replies to /addclub and /scan include a Choose matches to be alerted about menu (up to 25 matches):

  • Matches you select become ⭐ starred.
  • Matches that were starred and you deselect go back to normal (muted at a manual club).
  • Matches you never touched keep their level.

The picker stops working after an hour or a bot restart. Run /scan again for a fresh one.

The /manage panel

Select matches in its menu, then press ⭐ Star, Normal or πŸ”‡ Mute. Only the selected matches change. See /manage for its tier, scan and remove controls.

Recipes

Never miss a squad at your home club

Make it watched (the default). New matches arrive starred, so early opens, closes and reopens all reach you. Add /rules for match types you don't shoot.

Follow a club casually

/tier it to standard. You'll hear about new matches and openings within about 12 hours, for a fraction of the requests.

One match at a far-away club

/addclub with tier:manual and pick that match. The bot checks once a day until registration opens, then DMs you.

Unstar several matches at once

/manage club:…, select the matches, press Normal (or Mute). Free, no scan needed.

Stop steel alerts

/rule club:… text:Steel level:muted for future ones, then /mute any already listed.

Going on vacation

/scraping state:off. When you're back, state:on gives you one summary per club.

Check right now

/scan club:… costs one request and shows the live listing.

Request usage

Each check loads one club page through the scraping service, which costs one request no matter how many matches the club lists. Commands that only read saved data (/matches, /clubs, /status, and /manage unless you press Scan now) cost nothing. /usage shows what's actually been spent.

WhatApprox. requests / month
One watched club (~5 checks a day)150
One standard club (2 a day)60
One manual club with a starred match waiting30 while waiting, 0 otherwise
Registration-time checksabout 2 per starred or normal match as it nears opening
/addclub, /scan1 each time

Limits worth knowing

  • No exact registration times yet. Club pages only show a rounded countdown, and match pages hide exact times behind a login. Registration-time checks work from the "hours" and "minutes" countdowns. Exact times from PractiScore's search index are planned.
  • Removal takes two checks. A match must be missing twice in a row, so one bad page load never causes a false alarm. At a watched club that's about 3–6 hours after it disappears.
  • An empty page is treated as a failed check, not as every match being cancelled.
  • Past matches drop off the listing naturally and are never reported as removed.
  • Full and waitlist labels haven't been seen yet. When one appears you get an "Unrecognized Registration Label" DM.
  • Manual clubs aren't checked at all unless a starred match is waiting to open, so news about their other matches only arrives when you /scan.

Troubleshooting

ProblemWhat to do
Commands don't appear, or an option is missingClose and reopen the DM, or restart Discord. New commands can take a minute to show up.
"This is a private bot."You're not the bot's owner. It only answers one account.
No alerts for a clubCheck /clubs: is it paused or manual? Check /status: is scraping on? Are the matches muted?
"Scraping is failing" DMThe scraping service or PractiScore is having trouble. The DM includes the error. The bot keeps retrying on its normal schedule and tells you when it recovers.
A picker or button says the interaction failedThe picker expired (1 hour, or a restart). Run /scan again. /manage controls expire after 30 minutes; run /manage again. Level buttons on alerts don't expire.
"Unrecognized Registration Label"Open the match and check it yourself. The label is quoted in the DM so the bot can be taught it.