Skip to content

/event — Command Reference

Access

All /event subcommands require Chapter Organizer or higher.


Event Context — event_id Resolution

Most commands accept an optional event_id. When omitted, the bot matches the current channel ID against Events.organizer_thread and Events.Discord_event URLs in Grist. If no match is found, an error is returned with instructions to re-run with an explicit ID.

event_id is the UUID text field (Events.event_ID), not the Grist row number.


/event new

/event new [date] [region] [structured_event]

All three params are required. region and structured_event use Discord autocomplete from the configured ChoiceList values. date is a free-text string parsed flexibly: 6/14, June 14, 2025-06-14, TBD. Time defaults to 10:00 America/Los_Angeles when not specified.

Duplicate detection — before creating anything, the bot checks Events for rows in the same region within ±2 days. If a match is found, an ephemeral embed shows the existing event with three options:

  • Use existing / Link thread — behavior depends on what already exists:
  • Post + thread exist: confirms with no changes.
  • Post exists, no thread: creates an organizer thread and links it.
  • Neither exists: creates an organizer thread only. Run /event post separately to create the public post.
  • Create new event — proceeds with full creation despite the potential duplicate.
  • Cancel — aborts with no writes.

Creation flow:

  1. Ephemeral confirmation embed with parsed values (date, region, type, template, location, prereqs, counts-for-ToG). Edit details and Edit notes buttons open modals for corrections before confirming.
  2. Grist row created in Events.
  3. Organizer thread created in #firearms-instruction-workstream (public thread). Initial organizer post (roles + RSVP placeholder) posted and pinned. Events.organizer_thread and Events.organizer_post_message_id written to Grist.
  4. Ephemeral reply with Grist row ID and organizer thread link, with a reminder to run /event post.

Run /event post when ready to create the member-facing forum post in #range-days-and-events.

If the command is run from inside an existing thread in #firearms-instruction-workstream, that thread is used as the organizer thread instead of creating a new one.

Optional params: - location — location nickname or URL; autocompletes from Event_locations. Defaults to the region's configured location if omitted. - prereqs — override prereqs; autocompletes from configured values. Defaults to per-type defaults. Pass none to clear. - counts_for_tog — boolean override for whether this event counts toward Training of the Guards. Defaults to per-type setting.


/event post

/event post

Creates the member-facing forum post in #range-days-and-events. Run from inside the organizing thread — the event is inferred from the thread automatically. No parameters.

Errors if run outside an organizing thread (use /event info to find the thread link), or if the event already has a post.


/event info

/event info [event_id]

Shows the organizer thread and event post links for an event. Use this to find the organizing thread before running /event post, or to check what's been set up.

event_id autocompletes from events within the past 14 days and the next 25 upcoming, sorted by date. TBD/undated events appear at the end.


/event edit

/event edit [event_id]

Opens an ephemeral dropdown listing each block of the live event forum post with a short excerpt. Selecting a block opens a prepopulated modal with the full block text. Submitting the modal replaces only that block in the post.

Works regardless of which template was used or whether the post has been edited before. The live embeds in the Discord message are the source of truth — no template or section name knowledge required.

event_id is optional; inferred from the current organizing thread if omitted.


/event role add / /event role remove

/event role add [role] [member1] [...] [event_id]
/event role remove [role] [member1] [...] [event_id]

role autocompletes: instructor, TA, greeter, medic. Up to 5 members at once.

Each member is resolved to a People row via Discord snowflake. If any member cannot be resolved, the entire operation is aborted with an error listing which ones failed.

On success: - Updates the corresponding ReferenceList column in Grist (instructors, TAs, greeter, medic). - Edits the roles block in the live event forum post. - Refreshes the pinned organizer post. - Ephemeral confirmation with member mentions and post update status.

For competition events (structured_event contains Comp), the instructor role is labeled Match Director in posts.


/event attendance multi-add

/event attendance multi-add [event_id]

Multi-step interactive flow for logging post-event attendance.

Step 1 — Select from accepted RSVPs. Paginated in groups of 25 if there are more. Previous page and Next page buttons carry selections across pages. Continue advances to step 2 with accumulated selections.

Step 2 — UserSelect for members not on the RSVP list (extras). Up to 25.

Step 3 — Modal with an optional guests text field for non-member names (free text, comma-separated, appended to Events.guests_comma_sep_).

On submit: - Merges selected people IDs with existing Events.attendees (deduplicates). - Re-fetches the event to get the computed grass_touchers field. - Posts a summary to the organizer thread:

**Attendance logged**
**Touchers of grass (2):** @alice, @bob
**Everyone else (3):** @carol, @dave, @eve
Guests: "Alex Smith"

The grass touchers section only appears for events where counts_for_ToG is true; it always shows even if zero, so the absence of touchers is explicit.


/event attendance add

/event attendance add [member] [event_id]

Adds a single member to Events.attendees. Warns if already present. Posts a one-line log to the organizer thread.


/event attendance remove

/event attendance remove [member] [event_id]

Removes a single member from Events.attendees. Warns if not present. Posts a one-line log to the organizer thread.


Organizer Thread

Each event has a pinned post in its organizer thread (in #firearms-instruction-workstream) that is kept in sync automatically. The post shows:

  • Event post URL
  • Current role assignments (Greeter, Instructors/Match Director, TAs, Medic)
  • RSVPs grouped by status (Accepted / Waitlisted / Interest Noted / Pending) with gear/flag annotations
  • Legend and footnotes for annotated RSVPs

The post is refreshed on every RSVP status change, /rsvp list, and /rsvp identify completion. The message ID is stored in Events.organizer_post_message_id to avoid repeated pin scans.

Legend:

^ toucher of grass
º has taken [event type] before
~ joined <2mo ago
🔫 needs firearm
🪣 needs holster
🥽 needs eye protection
👂 needs ear protection
❓ needs other
[n mo] = months since vetted