Skip to content

Commit 3e4a281

Browse files
ebm5025claude
andauthored
Only deliver EQNotify alerts to active Raiders (#264)
Gate batphone dispatch on the subscriber currently holding the Raider role, checked live against Discord at push time. A subscriber who loses the role (goes inactive, leaves the guild) stops receiving alerts without needing to unregister; unresolvable members are treated as non-Raiders. The manual /eqnotify test path is intentionally unaffected. Claude-Session: https://claude.ai/code/session_01BWXRmPbtEz35wquwFd8Cu7 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 85a64e1 commit 3e4a281

3 files changed

Lines changed: 30 additions & 5 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Some features required secrets, such as to connect to CastleDKP.com or the Castl
5757

5858
#### 📣 EQNotify
5959

60-
`/eqnotify` lets raiders subscribe to phone notifications for the raid targets they care about. It watches the batphone channel and, for each subscriber whose keyword tags match the batphone (buff / last-hour RTE calls are filtered out), pushes an alert to their phone.
60+
`/eqnotify` lets raiders subscribe to phone notifications for the raid targets they care about. It watches the batphone channel and, for each subscriber whose keyword tags match the batphone (buff / last-hour RTE calls are filtered out), pushes an alert to their phone. Alerts are only delivered to subscribers who **currently hold the Raider role**, so anyone who goes inactive or leaves stops receiving them automatically.
6161

6262
- **Delivery channels**: **WirePusher** (free, Android-only) or **Telegram** (iOS/Android/desktop). Telegram delivery requires `TELEGRAM_BOT_TOKEN`; if unset, only WirePusher is offered.
6363
- **Getting your ID**: WirePusher users use their device ID from the app. Telegram users start a chat with the guild's EQNotify bot and get their numeric chat ID (e.g. from [@userinfobot](https://t.me/userinfobot)).

src/features/eqnotify/commands/register-subcommand.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class RegisterSubcommand extends Subcommand {
4646
? `Updated your EQNotify delivery to **${channel}**. Your notification tags are unchanged.`
4747
: `You're enrolled in EQNotify via **${channel}**! You'll be notified for: ${DEFAULT_TAGS.join(
4848
", "
49-
)}.\nUse \`/eqnotify add-tag\` / \`/eqnotify remove-tag\` to customize, and \`/eqnotify test\` to verify delivery.`
49+
)}.\nUse \`/eqnotify add-tag\` / \`/eqnotify remove-tag\` to customize, and \`/eqnotify test\` to verify delivery.\n_Note: alerts are only sent while you actively hold the Raider role._`
5050
);
5151
}
5252

src/features/eqnotify/eqnotify.service.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { eqnotify_subscriber, eqnotify_type } from "@prisma/client";
2-
import { prismaClient } from "../..";
2+
import { getMember, prismaClient } from "../..";
3+
import { raiderRoleId } from "../../config";
34
import { log } from "../../shared/logger";
45
import { notify } from "./notifiers";
56
import {
@@ -18,6 +19,24 @@ interface EnrollInput {
1819
type: eqnotify_type;
1920
}
2021

22+
/**
23+
* Whether a member currently holds the Raider role. Batphone alerts are only
24+
* delivered to active Raiders, so a subscriber who loses the role (goes
25+
* inactive, leaves the guild, etc.) stops receiving alerts without having to
26+
* unregister. Failures to resolve the member are treated as "not a Raider".
27+
*/
28+
const hasRaiderRole = async (discordId: string): Promise<boolean> => {
29+
try {
30+
const member = await getMember(discordId);
31+
return member.roles.cache.has(raiderRoleId);
32+
} catch (error) {
33+
log(
34+
`EQNotify could not resolve member ${discordId} for role check: ${error}`
35+
);
36+
return false;
37+
}
38+
};
39+
2140
const requireSubscriber = async (discordId: string) => {
2241
const subscriber = await prismaClient.eqnotify_subscriber.findUnique({
2342
where: { discordId },
@@ -95,7 +114,8 @@ export const eqnotifyService = {
95114

96115
/**
97116
* Matches a batphone against every subscriber's tags and delivers alerts.
98-
* Delivery failures are logged but never interrupt other subscribers.
117+
* Only subscribers who currently hold the Raider role are notified. Delivery
118+
* failures are logged but never interrupt other subscribers.
99119
*/
100120
dispatch: async (content: string) => {
101121
if (!content.trim() || isFiltered(content)) {
@@ -105,7 +125,12 @@ export const eqnotifyService = {
105125
await Promise.all(
106126
subscribers
107127
.filter((sub) => matchesTags(content, sub.tags))
108-
.map((sub) => eqnotifyService.notifySubscriber(sub, content))
128+
.map(async (sub) => {
129+
if (!(await hasRaiderRole(sub.discordId))) {
130+
return;
131+
}
132+
await eqnotifyService.notifySubscriber(sub, content);
133+
})
109134
);
110135
},
111136

0 commit comments

Comments
 (0)