Skip to content

Commands

Every slash command, message menu item, picker, prompt and DM the bot has, with options, defaults, limits and replies. Entries follow registration order, with the message menu and the tag flow next to /follow, then the ticket prompt and the meeting action items. Commands for asking, summaries, Linear and voice notes exist only while their feature is on; see When commands exist.

Terms used below:

  • Message menu: the Apps entry you get by right-clicking (or long-pressing) a message.
  • Picker: a private message with a drop-down of times and a Pick a time button.
  • Tag: mentioning the bot in a message.
  • Prompt: a direct message the bot starts on its own, such as the ticket prompt.
  • Private: only the person who used the command can see the reply.
  • Linear: the issue tracker the bot files tickets in.
  • Gemini: the AI model the bot calls. GEMINI_API_KEY is the key it needs.
  • Settings in capitals, such as REMINDER_ALLOWLIST, are bot settings listed in Configuration.
  • The bot works in one server only. Anything from another server is ignored without a reply.
  • Replies to commands, menus and buttons are private. The exceptions are the reply to a tag (a follow-up confirmation or an answer), a public /ask, replies to an upload in the meetings channel, and the voice-note posts: a notice and a result line in the voice channel’s text chat, and the summary in the meetings channel or in that chat. The ticket prompt and the meeting action items are DMs.
  • The bot saves your server display name when you use /whoami, /hours, /reminders, the message menu, the follow-up picker, /ask, or tag it with a follow-up request or a question.
  • /follow saves it once the message link is accepted, /summary now once its checks pass, and every /interests subcommand once its input checks pass. /linear-admin link saves it for the member you pick, if the bot has no record of them yet.
  • /reminder-rules, /summary-admin, /notes and /notes-admin do not save it.
  • An unexpected error shows as Something went wrong. After a button, drop-down or form on a message, the apology is a new private message and the original stays as it was.
  • An unknown command or button shows Unknown command. or Unknown action.
CommandWho can use itWhere
/whoami, /hours, /follow, /remindersAnyone in the serverServer
Message menu “Remind me to follow up”Anyone in the serverServer
Tag the bot in a replyAnyone in the serverServer channels
/ask and the answer to a tagAnyone in the server. The feedback buttons only for the askerServer, and a public answer in a server channel
Ticket prompt (buttons and form)Only the author of the message that triggered itDirect message
Meeting action items (drop-down and buttons)Only the owner of the items. Items with no owner belong to whoever uploaded the transcriptDirect message
/reminder-rulesMembers with Manage ServerServer only, not in DMs
/notesAnyone in the serverServer only, not in DMs
/notes-adminMembers with Manage ServerServer only, not in DMs
/summary nowRecipients of that summary, and members with Manage ServerServer
/interestsAnyone in the serverServer
/summary-adminMembers with Manage ServerServer only, not in DMs
/linear-adminMembers with Manage ServerServer only, not in DMs

A command whose switch is off is removed from the server at the next start. Each switch is a setting; see Configuration.

CommandsExist while
/summary, /interests, /summary-adminSUMMARIES_ENABLED is true
/notesVOICE_NOTES_ENABLED and MEETING_TRANSCRIPTS_ENABLED are true and GEMINI_API_KEY is set
/notes-adminMEETING_TRANSCRIPTS_ENABLED is true and GEMINI_API_KEY is set, so an upload-only install can still name the summary channel
/linear-adminLINEAR_API_KEY is set, whatever TICKET_PROMPTS_ENABLED says, because prompts already sent still use the member mapping
/askASK_ENABLED is true and GEMINI_API_KEY is set. With either missing, a tag about a question gets no answer

Message search and embeddings have no command of their own. Summaries and /ask use them behind the scenes.

/hours, /reminders time, /interests digest, the time option of /summary-admin create and the clock-time forms of follow-up times all read the same clock formats. Input is trimmed and case does not matter.

FormRuleParsesDoes not parse
12-hour1 or 2 digits, optional : and 2 minute digits, optional space, then am or pm. Hour 1 to 12.9am, 9 am, 9AM, 5:30 pm, 12am (00:00), 12pm (12:00), 12:30am13pm, 0am, 13am
24-hour with colon1 or 2 hour digits, :, exactly 2 minute digits. Hour up to 23, minute up to 59.09:00, 9:00, 23:59, 17:3024:00, 25:00, 9:5, 9:75, 9:00:00
Compact digits1 or 2 hour digits, then exactly 2 minute digits0900, 900, 173099999

A bare 9 does not parse. noon, abc, an empty value and seconds do not parse either. A bare four digit number such as 2026 reads as the time 20:26.

Shows your saved profile. No options. Private reply.

Example of the bot in Discord

You type

/whoami

Doge Bot replies

Name: Sam
Discord ID: 123456789012345678
Timezone: America/New_York
Working hours: 09:00 to 17:00

Only you can see this

Unset values show not set. Working hours show only when both start and end are saved.

Saves your working hours and your timezone. Two subcommands. Both replies are private.

start text required

Start of your work day, for example 9am or 09:00. Accepts the formats above.

end text required

End of your work day, for example 5pm or 17:00. Accepts the formats above.

zone text required

Your timezone as its full name, for example Africa/Nairobi or America/New_York. Type a city, such as nairobi, and pick the suggestion that appears. Required on every run, because the command saves it with your hours. The match is exact and case sensitive, so america/new_york is rejected. UTC is accepted.

Autocomplete on start and end offers up to 25 half-hour slots from 00:00 to 23:30, so 09 offers 09:00 and 09:30. 5pm shows no suggestion but is still accepted. Autocomplete on zone trims what you type, lower-cases it, turns spaces into underscores and offers up to 25 zone names that contain it, so new york finds America/New_York. It only suggests; an unknown zone gets the error below.

Start and end must differ after parsing, so 9am and 09:00 count as equal. If both are bad, only the start is named. Times are checked before the zone. When the end is earlier than the start, the reply adds (ends the next day). Hours are stored as HH:MM:00 and shown as HH:MM. To change only your timezone, run the command again with your current start and end and the new zone.

Example of the bot in Discord

You type

/hours set start: 9am end: 5pm zone: America/New_York

Doge Bot replies

Working hours saved: 09:00 to 17:00 (America/New_York)

Only you can see this

Example of the bot in Discord

You type

/hours set start: 22:00 end: 06:00 zone: UTC

Doge Bot replies

Working hours saved: 22:00 to 06:00 (ends the next day) (UTC)

Only you can see this

After saving, the bot checks your start-of-day channel reminders at once. If it sends you one, the reply gains a second line listing each channel as a mention:

Example of the bot in Discord

You type

/hours set start: 9am end: 5pm zone: America/New_York

Doge Bot replies

Working hours saved: 09:00 to 17:00 (America/New_York)
You have not posted in <#123456789012345678> yet today, so I sent you a reminder.

Only you can see this

With two channels the channels are joined by , . With no reminder sent, the reply is the first line only, and a failed check never changes the reply. The check ignores the rule’s grace (its wait after the start of your day) and the late limit (REMINDER_LATE_LIMIT_MINUTES). It skips end-of-day rules, rules whose time for you (see /reminders time) is later than now, rules you turned off, disabled rules, members not on REMINDER_ALLOWLIST and reminders switched off (REMINDERS_ENABLED). It counts as that work day’s reminder, so repeating /hours set sends nothing more. See The reminder engine.

Errors:

CauseReply
zone sent blank (Discord normally blocks this)I also need your timezone. Run /hours set again and fill in `zone`. Nothing was saved.
zone is not a known timezone"Mars/Olympus" is not a valid timezone. Pick one from the suggestions. (the value you typed is quoted)
A value does not parse"noon" is not a time I understand. Try 9am, 9:30 or 17:00. (the offending value is quoted)
Start and end are the same timeStart and end must be different times.

Removes your working hours and keeps your timezone. No options. Works whether or not hours were set. It does not trigger the reminder check.

Example of the bot in Discord

You type

/hours clear

Doge Bot replies

Working hours cleared.

Only you can see this

Reminds you about a message at a time you choose. Private reply. The bot does not open the message, so it does not check that the message exists or that you can see it.

message text required

Link to the message (Copy Message Link). It must be an https link to a message in this server, from discord.com, discordapp.com or their ptb. and canary. forms. Links to other servers, DM links and non-Discord links are rejected.

when text required

When to remind you, for example in 30s, in 2h, tomorrow 9am or 9am. See the formats below. No autocomplete.

note text optional

An optional note to include in the reminder. Only /follow takes a note; the menu and the tag flow do not.

Allowed: up to 200 characters

Example of the bot in Discord

You type

/follow message: https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002 when: in 2h note: Check the build

Doge Bot replies

Sure, I'll help you follow up on <https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002> in 2 hours.

Only you can see this

The confirmation is fixed words, with no countdown. A relative when such as in 2h is repeated as in 2 hours. A clock time such as tomorrow 9am ends with at <t:1790000000:f>, which Discord shows as a date and time in your own timezone. The link has no preview.

Input is trimmed and case does not matter.

FormMeaningExample
in <number> <unit>That long from now. Units: s, sec, secs, second, seconds; m, min, mins, minute, minutes; h, hr, hrs, hour, hours; d, day, days. A day is 24 hours. Needs no timezone.in 45s, in 30m, in 2 hours, in 3d
Clock timeThe next time the clock reads that value in your timezone. If today’s time has passed, it means tomorrow. Needs a timezone.9am, 17:00, 1730
tomorrow <clock time>That clock time on tomorrow’s date in your timezone. Needs a timezone.tomorrow 9:30am

Limits: at least 10 seconds ahead, at most 365 days ahead. A bare clock time does not skip weekends. in 1.5h, in 1 week, today 5pm, next monday and tomorrow on its own do not parse.

Time errors, shared by /follow, the picker form and the tag flow:

CauseReply
Text not understoodI did not understand that time. Try "in 2h", "tomorrow 9am" or "9am".
Clock time but no timezone savedSet your timezone with /hours set first, or use a relative time like "in 2h".
Less than 10 seconds ahead or in the pastThat time is in the past. Pick a time at least 10 seconds from now.
More than 365 days aheadThat is more than a year away. Pick something sooner.

Other errors:

CauseReply
Link is not a message link from this serverThat is not a message link from this server. Use "Copy Message Link" on a message here.
The follow-up rule is disabledFollow-ups are switched off.

The same follow-up twice (same message, same instant) keeps one reminder and shows the same confirmation. Different messages at the same instant are both kept.

Right-click or long-press a message, choose Apps, then Remind me to follow up. Private reply with a picker.

Example of the bot in Discord

You right-click a message and choose Apps >

Remind me to follow up

Doge Bot replies

When should I remind you to follow up on this message?

Only you can see this

Pick a time

The picker also holds a drop-down titled “When should I remind you?” with the presets below. The menu takes no note.

PresetShown whenTime
In 1 hourAlwaysNow plus 1 hour
In 3 hoursAlwaysNow plus 3 hours
Tomorrow HH:MMA timezone is savedTomorrow’s date at your work start
Next working day HH:MMA timezone is savedTomorrow, moved forward past Saturday and Sunday, at your work start

HH:MM is your saved work start, or 09:00 when no hours are saved. The last preset reads, for example, Next working day 09:00.

  • On a Friday, Tomorrow is Saturday and Next working day is Monday.
  • In 1 hour and In 3 hours are counted from the moment you click.
  • Tomorrow and Next working day use the time fixed when the picker was posted. If that time has passed when you click, you get the time error That time is in the past. Pick a time at least 10 seconds from now. and the picker is removed.
  • Choosing a preset replaces the picker with the /follow confirmation: in 3 hours for In 3 hours, at <t:...:f> for Tomorrow and Next working day.
  • Pick a time opens a form titled “Remind me to follow up” with one required field, “When”, hinting in 30s, in 2h, tomorrow 9am, 9am. It takes the /follow formats and replies with the confirmation or a time error.
  • Only the person the picker was made for can use it.
CauseReply
Someone else clicksThis picker is not for you.
The picker’s message reference cannot be readThat reminder picker is no longer valid.
The chosen option cannot be readThat option is no longer available.
You have left the server (picker click or form)You are no longer in the server, so I cannot set a reminder for you.
The fixed time of the chosen preset has passedThat time is in the past. Pick a time at least 10 seconds from now.
The follow-up rule is disabledFollow-ups are switched off.
Unknown button or menu actionUnknown action.

Type the bot’s mention in a message. Gemini reads the message to decide whether it is a follow-up request, a question or neither, and for a follow-up whether you gave a time. A tag on a reply follows up on the message you replied to; a tag on a plain message follows up on that message. The reply to a follow-up request is public in the channel, pings nobody, and never repeats your message.

Your messageThe bot answers in the channelAnd by direct message
A follow-up with a time the bot understandsSure, I'll help you follow up on this in 2 hours. for a length of time, or Sure, I'll help you follow up on this at <t:1790000000:f>. for a clock time. The follow-up is saved at once.Nothing
A follow-up with no time, or a time the bot could not readSure, I'll help you follow up on this. Check your DMs to pick a time.The picker below
A follow-up with no usable time, and your DMs are closedI could not DM you. Use /follow to pick a time.Nothing
A follow-up with a clock time and no timezone savedThe matching time error below. Nothing is saved.Nothing
A follow-up with a time in the past or over a year awayThe matching time error below. Nothing is saved.Nothing
A follow-up while the follow-up rule is disabledFollow-ups are switched off.Nothing
A question, while asking is switched onA public reply to your message with the answer and the feedback buttons, see /ask. No follow-up is saved.Nothing
A question over 500 characters, while asking is switched onKeep questions under 500 characters, or use /ask. Once per member per hour; after that the bot only reacts with ⏳.Nothing
A question while your last question is still being answeredA ⏳ reaction on your message.Nothing
Anything elseNothingNothing

For a length of time the reply repeats the number and unit the model returned: in 1 second, in 30 seconds, in 1 hour. The unit is singular only for 1. For a clock time, Discord turns <t:...:f> into a date and time in your own timezone, such as “3 October 2026 at 09:00”. The picker is the one the message menu sends, and its link points to the message you replied to, or to your own message when it is not a reply.

Example of the bot in Discord

You reply and tag the bot

@Doge Bot

Doge Bot sends you a DM

When should I remind you to follow up on <https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002>?

Pick a time

The model returns the time as in N seconds, in N minutes, in N hours, in N days, tomorrow HH:MM or HH:MM, and the bot reads it with the /follow rules.

Fallbacks. The bot does not read the message when the AI is not set up, you have used 20 readings in the last hour, the server has used MENTION_MAX_CHECKS_PER_DAY readings in the last 24 hours, the call fails, or nothing is left of your message once the mention is removed. A tag on a reply then counts as a follow-up with no time, and any other tag is ignored. These fallbacks never produce a question answer.

The bot ignores your message when:

  • it is in another server or a DM to the bot, or the author is a bot;
  • it mentions @everyone or @here, or does not contain the literal mention text (the bot’s own role counts as a tag, because Discord offers it under the same name as the bot; any other role does not);
  • neither feature applies: a follow-up needs reminders switched on (REMINDERS_ENABLED) and, when REMINDER_ALLOWLIST is set, you on it; a question needs asking switched on (ASK_ENABLED) and ignores the allowlist.

If the bot cannot send messages in the channel, the follow-up is still saved and no confirmation appears. A question is answered only when the bot can view the channel, send messages there (in threads, send messages in threads), embed links and read the message history; otherwise it stays silent. The text of your message, without the mention, goes to Gemini. See What the bot stores.

Not a slash command. When a post looks like a new feature idea and Linear has no matching ticket, the bot DMs the author a draft ticket. Only a submitted form creates a ticket. How the bot decides, and how it picks the team, assignee and labels: Ticket prompts. How members use it: Ticket prompts.

The prompt is sent only while TICKET_PROMPTS_ENABLED is true and both GEMINI_API_KEY and LINEAR_API_KEY are set. The buttons and the form keep working for prompts already sent while LINEAR_API_KEY is set. See Configuration.

Example of the bot in Discord

Doge Bot sends you a DM

Hi Sam, this sounds like a feature idea: https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002
> Draft ticket: Add dark mode
Want a Linear ticket for it? You can edit it before anything is created.
Only you got this. I ask when a post looks like a new feature and Linear has no matching ticket, at most 3 times a day.

Create ticket No thanks
  • The greeting is Hi and your first name from your server display name. A blank name gives Hi.
  • The link points to your message. The draft title is bold. The number in the last line is TICKET_PROMPT_DAILY_CAP.
  • When Linear has related tickets, These existing tickets look similar, check them first: and one line per ticket, - [IDENTIFIER](<url>) <title>, appear before the Want a Linear ticket line. Titles are cut to 80 characters and at most 3 are listed. If the message would pass 2000 characters, whole ticket lines are dropped from the end.
  • Mentions are off and link previews are suppressed.
  • When the AI judges the idea a clear duplicate and names the existing ticket, no message is sent. If it says duplicate but names no ticket the search found, the prompt is sent with the first 3 tickets found listed as similar.
ControlKindWhat it does
Create ticketPrimary buttonOpens the form
No thanksSecondary buttonCloses the prompt

Only the author can use the controls. Anyone else gets This prompt is not for you. There is no time limit on the buttons or the form.

Opens a form. Discord allows 3 seconds for this. The bot gives Linear 2.5 seconds, minus the time already used, to return the team list, and waits at most 0.7 seconds for the cycle dates, which are only decoration.

CauseReply
The prompt is openThe form opens
Linear has no team list in timeLinear is slow right now. Press Create ticket again in a moment.
Linear shows no public teamNo Linear team is available.
A form was sent less than 2 minutes ago and is still being filedStill creating that ticket. Give it a few seconds. The buttons stay.
The draft is gone: the message or its channel was deleted, or the bot started more than 30 days after the promptThe prompt becomes Your original message was deleted, so I closed this prompt. with no buttons. The same text is shown in all three cases
The prompt is not open any moreThe buttons are removed, then the status text below
A form was sent more than 2 minutes ago and never finishedThe form opens again

Status texts:

Prompt stateText
Ticket createdAlready created: [IDENTIFIER](<url>).
Dismissed with No thanksYou dismissed this one.
Closed without a ticketThis prompt is closed. Nothing was created.
Still openThis prompt is still open. Press Create ticket to try again.
Being filedStill creating that ticket. Give it a few seconds.
Team select required

Placeholder Choose a team. Present only when the bot offers more than one team; with exactly one, the field is left out and that team is used. One option per team, sorted by name, names cut to 100 characters, first 25 only, with the suggested team first. A suggested team is preselected and the field note reads Suggested from your message. Change it if it is wrong. With more than 25 teams only the note Showing 25 of N teams. Ask an admin if yours is missing. shows, in place of the suggestion note, and the suggested team is still first and preselected. The offered teams are the Linear teams you belong to (private ones included) when your Discord account is linked to a Linear user, and all public teams when you are not linked or belong to no team.

Title text required

Short single-line text, prefilled with the draft title.

Allowed: up to 200 characters

Description text optional

Paragraph text, prefilled with the draft description. Hint: Optional. A link to your Discord message is added automatically.

Allowed: up to 4000 characters

Cycle select optional

Optional. A cycle is Linear’s name for a sprint. Shown only when at least one offered team has cycles switched on. The options are No cycle, Current cycle and Next cycle. When exactly one team is offered and the bot read its cycles in time, the last two also carry the cycle name and dates, for example Current cycle · Cycle 5 (Oct 5–18). Dates are in your saved timezone, or UTC.

Default: No cycle

The form is titled New Linear ticket. Fields in order: Team, Title, Description, Cycle.

Checks on submit, in order. The first one that fails ends it.

CauseReply
The draft is gone: the message or its channel was deleted, or the bot started more than 30 days after the promptThe prompt becomes Your original message was deleted, so I closed this prompt.
The title is blankThe ticket needs a title. Press Create ticket and add one.
Linear cannot return the team listLinear is slow right now. Press Create ticket again in a moment.
The chosen team is not one of the teams offered to you nowThat team is not available. Press Create ticket and choose another.
You have left the serverYou are no longer in the server, so I cannot create this ticket.
A form is already being filedStill creating that ticket. Give it a few seconds.
The prompt is already created, dismissed or closedThe matching status text above
The message was deleted while the form was being sentThe claim is released, nothing is filed, and the prompt becomes Your original message was deleted, so I closed this prompt.

The prompt is marked as being filed (claimed) only after the first five checks pass, so a second press cannot start a second ticket.

What the bot creates in Linear:

  • Team: the one you chose, or the only one offered. Title: your title.
  • Assignee: your linked Linear user. When an admin never linked or unlinked you, the bot first tries to match your name exactly. Otherwise none.
  • Labels: up to 3 that the model picks from the labels the team can already use, only when the AI is configured. The bot never creates a label. If the model fails, the ticket is created with no labels.
  • Cycle: the current or next cycle of the team, when you chose one and the team has it. Otherwise the ticket is filed with no cycle and a line under it says why, for example Engineering has no current cycle, so the ticket was filed without one.
  • Nothing else is set: no project, priority or state. Linear gives the team’s default state.
  • If Linear refuses the assignee, labels or cycle as invalid, the bot tries once more without them. The ticket then reads Filed in and gains a line such as Linear rejected some details, so it was filed without its assignee or labels. that names what had been sent.
  • Description: your description, a blank line, --- and Proposed by <your display name> (Discord id <your id>) in Discord: <link to your message>.
  • The creator shown in Linear is the owner of LINEAR_API_KEY, not you.
  • Linear gets 20 seconds per step. The ticket id is fixed before filing, so pressing Create ticket again after a failure never makes a second ticket.

On success the prompt is edited to show a link button and no other buttons. While filing, the prompt gains the line *Creating the ticket…* at its end and returns to its old text if filing fails.

Example of the bot in Discord

Doge Bot sends you a DM

Ticket created: [ABC-9](<https://tracker.example/issue/ABC-9>) Add dark mode
From your message: https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002
Assigned to you in Engineering · Cycle 5 (Oct 5–18).

Open ABC-9

The small-text line under the link is -# Assigned to you in <team name>. when the ticket was assigned to you, and -# Filed in <team name>. when it was not. When a cycle was set, · <cycle name> (<dates>) follows the team name. Team and cycle names are cut to 64 characters. Each note is added below as its own small-text line. When Linear did not confirm the details of a ticket that already existed from an earlier try, the line reads Linear did not confirm this ticket's details, so check them in Linear. and no notes follow.

The cycle notes are <team> does not use cycles, so the ticket was filed without one., <team> has no current cycle, so the ticket was filed without one., <team> has no next cycle, so the ticket was filed without one. and Could not read <team>'s cycles, so the ticket was filed without one.

On a failure, the bot answers privately and keeps your edited text.

CauseReply
Linear did not answer in timeLinear did not answer in time, so I cannot tell yet whether the ticket was filed. Press Create ticket to check: it will not create a second one.
Linear rejected the ticket (key, permission or input)Linear rejected the ticket, so nothing was filed. Tell an admin: the bot may lack permission for that team.
Any other failure, including a rate limitCould not create the ticket in Linear, so nothing was filed. Your text is saved: press Create ticket to try again.

Closes the prompt and clears the draft. The prompt is edited and loses its buttons.

Example of the bot in Discord

Doge Bot sends you a DM

No ticket created for Add dark mode
Your message: https://discord.com/channels/123456789012345678/200000000000000001/300000000000000002
I will not ask about that message again.

With no draft left the first line is No ticket created. A dismissed prompt still counts toward your daily limit. On a prompt that is no longer open, No thanks answers Still creating that ticket. Give it a few seconds. while a ticket is being filed, and otherwise removes the buttons and shows the matching status text above.

CauseReply
LINEAR_API_KEY is not set (every control, including No thanks)Ticket prompts are turned off.
No prompt matches the button, for example an old or edited buttonThis prompt has expired. Nothing was created.
Someone other than the authorThis prompt is not for you.
Unknown actionUnknown action.

A prompt starts only from a new message in a channel the bot stores: text and announcement channels, public threads and forum posts. An edit, backfilled history, a DM, a private thread and the chat of a voice channel never start one.

RuleValue
AuthorsNot bots. Everyone when REMINDER_ALLOWLIST is empty, otherwise only listed ids
Message typesNormal messages and replies
LengthAt least 8 words. Code, links, emoji, mentions and tokens without a letter do not count
Per author, per rolling hour20 checks. Fixed (not a setting)
Checks waiting or runningAt most 10 per author and 200 in total, 4 running at once. Fixed. A message over a limit is dropped and does not use up the author’s hourly allowance
Per author, per rolling 24 hoursTICKET_PROMPT_DAILY_CAP prompts, default 3, 1 to 50. Duplicates do not count
All members, per rolling 24 hoursTICKET_PROMPT_MAX_CHECKS_PER_DAY checks that reach the AI, default 2000, 1 to 100000
AI unavailableNew checks pause for 60 seconds. Messages in that time are dropped
No public Linear teamNo prompt is sent
Team suggestionOnly for a message judged a proposal: one more model call that sees the teams offered to the author (two or more, looked up within 1.5 seconds, skipped when slow) with their one-line descriptions. It answers with a team name, and only a name that matches exactly one listed team (accents and letter case ignored) counts. The suggestion only preselects the Team field and never files anything. A failure means no suggestion
One prompt per messageYes. A message is never prompted twice, even after No thanks or a failed DM
Deleted message or channelThe draft is cleared and nothing is filed
Draft keptUntil the ticket is created, the prompt is dismissed or fails, the message or channel is deleted, or the bot next starts more than 30 days after the prompt

If the bot cannot DM you, for example because your DMs are closed, you see nothing, and the prompt still counts toward your daily limit.

Not a slash command. When a transcript upload or a voice meeting produces an action item that names you as owner, the bot DMs you your items. Only a press of Create selected (or Apply selected) creates or changes anything in Linear. How the bot decides: Meeting transcripts. How members use it: Meeting transcripts.

The message is sent only while MEETING_TRANSCRIPTS_ENABLED is true and GEMINI_API_KEY is set. The controls keep working for messages already sent; Create selected and the team drop-down need LINEAR_API_KEY. See Configuration.

When an owner’s DMs are closed, the upload reply or the /notes stop result says <names> could not get a DM (their DMs are closed), so their action items are only listed above.

Example of the bot in Discord

Doge Bot sends you a DM

Hi Alex, here are your action items from Weekly sync (see the summary).

  1. Draft the build checklist - this might already be ENG-12: Host menu mute. Check it before creating.
  2. Book the QA session
  3. Move ENG-9: Add blue crossbow to In Progress
    Choose items, then press Create selected. Nothing is filed until you do.
Create selected (3) Dismiss all
  • The greeting is Hi and your first name from your server display name. see the summary links to the bot’s summary in the channel.
  • When an item had no clear owner, Some of these had no clear owner, so they came to you. follows the first line.
  • Every item starts selected, so Create selected (N) is enabled at once.
  • An item line is its number and title, cut to 100 characters. - this might already be <ticket>. Check it before creating. follows when a ticket may cover it, and - already tracked as <ticket> when one surely does; that item cannot be selected. After you act, an item reads - created: <ticket>, - creating..., - dismissed or, for an item left unticked in a press that filed the rest, - not filed.
  • While a press works, the controls are disabled, the primary button reads ⏳ Creating… (⏳ Applying… for updates only) and the footer reads Working on it, this takes a few seconds. Afterwards the buttons are removed and the last line is It is created., It is updated. or It is created and updated.
  • An update item reads Move <ticket> to <Status> or Add a note to <ticket>, and after you act - applied: <ticket>, - noted: <ticket>, - applying... or - dismissed. An update with no matching ticket reads Note: <title> (no matching issue found, nothing to update) and is not selectable.
  • A ticket link reads ID: title, with the whole link text cut to 70 characters.
  • When every open item is an update, the buttons are Apply update or Apply selected (N), the drop-down placeholder is Choose the items to apply and the footer says Nothing is changed until you press ....
  • A Cycle drop-down sits under the item drop-down while a new item is open. It is not in the example.
  • Mentions are off and link previews are suppressed. If the message would pass 2000 characters, whole item lines are dropped from the end and -# N more not shown is added.
ControlKindWhat it does
Choose the items to create (Choose the items to apply for updates only)Drop-down, up to 25 open items, all chosen at first. Update items are prefixed Update:Selects which items to act on. Saves and refreshes the message
CycleDrop-down with No cycle, Current cycle and Next cycle, one choice, No cycle at firstSets the cycle for every open new item in the message, not for updates. Saved at once. Shown while a new item is open or being created
Create selected (N) or Apply selected (N), Create ticket or Apply update for one itemPrimary buttonFiles each selected new item as a Linear ticket and applies each selected update
Dismiss all or DismissSecondary buttonMarks every open item dismissed

The item drop-down shows only while two or more items are open. The buttons show while an item is open or being created. Only the owner can use the controls; anyone else gets These action items are not for you. There is no time limit.

The bot first acknowledges the press, because Discord allows 3 seconds for that, then works.

CauseReply
There is no LINEAR_API_KEY (Create selected and the team drop-down; the other controls keep working)Meeting tickets are turned off.
The meeting is not posted, has no row, or the button holds a broken idThis meeting is no longer available. Nothing was created.
The items are not yoursThese action items are not for you.
Nothing is selectedSelect at least one action item first.
You have left the serverYou are no longer in the server, so I cannot create these tickets.
Linear cannot return the team listLinear is slow right now. Try again in a moment.
Linear shows no teamNo Linear team is available.
An item is already being filedStill creating that ticket. Give it a few seconds.
The team needs a choiceA private message Which Linear team should these tickets go in? with a drop-down Choose a team. A team the bot suggested from the meeting is listed first with the description Suggested from the meeting
The team you chose is not offered to youThat team is not available. Pick another team.
Linear rejected the ticket (auth or invalid)Linear rejected the ticket, so nothing was filed. Tell an admin: the bot may lack permission for that team.
Linear did not answer in timeLinear did not answer in time, so I cannot tell yet whether the ticket was filed. Try again in a moment: it will not create a second one.
Another Linear errorCould not create the ticket in Linear, so nothing was filed. Try again in a moment.
A failure left items unfiled1 more item is still selected. or N more items are still selected.
An update and you have no admin-made Linear linkI could not update <ticket> because your Discord account is not linked to Linear yet. Ask an admin to run /linear-admin link for you.
An update and you are not on the ticket’s teamI could not update <ticket> because you are not on its Linear team.
The ticket for an update cannot be found or is in a private teamCould not find <ticket> in Linear, so nothing was changed.
The access check failedCould not check your access in Linear, so nothing was changed. Try again in a moment.
Linear did not answer an update in timeLinear did not answer in time, so the update may or may not have been applied. Check the issue in Linear before trying again.
Linear rejected an update (auth or invalid)Linear rejected the update, so nothing was changed. Tell an admin: the bot may lack permission for that team.
Another Linear error on an updateCould not update the issue in Linear, so nothing was changed. Try again in a moment.

Updates are applied first, before the team is looked at. Then the team is chosen in this order: the team the meeting named, when you are offered it; the only team offered to you; the team you pick in the drop-down, which is remembered for the meeting when it named none. The offered teams are your Linear teams when your Discord account is linked to a Linear user, and all public teams otherwise. When an admin never linked or unlinked you, your account is first matched to a Linear user by exact name.

What the bot creates in Linear, for each selected item:

  • Team: as above. Title: the item title.
  • Assignee: your linked Linear user, only for an item assigned to you. An item with no owner is unassigned.
  • Labels: up to 3 that the model picks from the labels the team can already use. The bot never creates a label. If the model fails, the ticket is created with no labels.
  • Project: the project the meeting named, only while it is still one of the chosen team’s projects.
  • Cycle: the current or next cycle of the team, as set in the Cycle drop-down. The choice stored on the item when the bot claims it wins, so a pick made while a press is working cannot be lost.
  • Nothing else is set: no priority or state.
  • If Linear refuses the assignee, labels, project or cycle as invalid, the bot tries once more without them.
  • Up to three tickets are filed at once. Any error stops new ones from starting.
  • Description: the item description, a blank line, --- and a footer: From the meeting "<title>" in [Discord](<link to the summary>), Approved by [<your display name>](<link to your profile>) and, for an item with no assignee whose owner the meeting named, Owner in the meeting: <name>. The summary link has no angle brackets.
  • The creator shown in Linear is the owner of LINEAR_API_KEY, not you.
  • The ticket id is fixed before filing, so pressing Create selected again after a failure never makes a second ticket.

An update item is applied before any new ticket in the same press. The person pressing needs an admin-made link (/linear-admin link; a name-matched link does not count) to a Linear user who is a member of the ticket’s team. Membership is read fresh each time. Refused or unverifiable updates take no claim and change nothing.

A successful update needs no message of its own: the item line reads - applied: <ticket> when the state was set or already there, and - noted: <ticket> when a comment was added. When the team has no matching state, the bot adds a comment instead and sends a private message: <ticket> noted (no "<Status>" state, so I added a note instead), with the ticket as a link.

The status is one of Backlog, Todo, In Progress or In Review, picked from the team’s own states. The bot never sets Done or Canceled. A comment reads Meeting note: <title>. <description>, or for a missing state The meeting suggested the status "<Status>", which this team has no matching state for., followed by the same --- footer as a ticket.

When the team is known, pressing Create selected edits the message to show - created: <ticket>. When you answered the team drop-down, that private message becomes Created <ticket> lines instead, and the original message is refreshed too when the bot can still find it.

After a press that filed something, the message ends with small-text lines for what happened. Each cycle line covers every ticket that press filed with that choice.

LineWhen
Filed in <team> · <cycle name> (<dates>).Tickets went into the cycle. Ends , except <tickets>. when some were filed without details Linear rejected, or Linear did not confirm them
<team> does not use cycles, so the ticket was filed without one.The team has cycles switched off. With several tickets: the 3 tickets were filed without one.
<team> has no current cycle, so the ticket was filed without one.The choice was Current cycle and there is none
<team> has no next cycle, so the ticket was filed without one.The choice was Next cycle and there is none
Could not read <team>'s cycles, so the ticket was filed without one.Linear did not return the cycles
Linear rejected some details, so it was filed without its assignee or labels.The retry without those details ran. With several tickets it names them, or counts them, such as so 2 of 3 tickets were filed without their labels.
Linear did not confirm the details of <tickets>, so check it in Linear.A ticket was recovered by its id after an unknown outcome. check them for several

See and control your own reminders. A reminder here is a rule: a channel reminder that checks whether you posted, or the built-in follow-up rule behind /follow. Admins manage rules with /reminder-rules. Three subcommands. Everyone can use them and all replies are private.

The rule option autocompletes with enabled channel reminders only, sorted by name, up to 25. The follow-up rule is never offered.

For toggle and time, a rule that does not exist, is disabled or is the follow-up rule gets this reply:

Example of the bot in Discord

You type

/reminders toggle rule: nope state: off

Doge Bot replies

There is no reminder called “nope”. Pick one from the suggestions.

Only you can see this

Shows the enabled reminders that can message you. No options. Disabled rules are hidden. Sorted by name, cut at 2000 characters.

A channel line reads **name** (status): channel, timing, wait, attachment, where:

  • status is on or off, with , HH:MM added when you set your own time
  • channel is a channel link, or not set
  • timing is at the start of your work day, at the end of your work day or on request
  • the rule’s grace (minutes to wait after that time) shows as N min after only when it is more than 0
  • needs an attachment appears only when the rule requires one

The follow-up rule shows as **follow-up**: on request with /follow.

Example of the bot in Discord

You type

/reminders list

Doge Bot replies

follow-up: on request with /follow
standup (on): <#123456789012345678>, at the start of your work day, 120 min after

Only you can see this

With no enabled rules the reply is There are no reminders set up.

Turns a reminder on or off for you only.

rule text required
Reminder name. Autocompletes.
state choice required
Turn the reminder on or off for yourself.

Allowed: on, off

Example of the bot in Discord

You type

/reminders toggle rule: standup state: off

Doge Bot replies

Reminder standup is now off for you.

Only you can see this

Sets your own time for a reminder, or clears it.

rule text required
Reminder name. Autocompletes.
time text required

A clock time in the formats above, or clear to follow your work hours again. Your time is the exact time the reminder fires; the rule’s wait is not added. It is saved whether or not a timezone is saved. Autocomplete offers half-hour slots, with clear first while the field is empty or holds part of the word, then up to 24 slots.

Example of the bot in Discord

You type

/reminders time rule: standup time: 9:30

Doge Bot replies

Reminder standup will now fire at 09:30 (your timezone).

Only you can see this

Example of the bot in Discord

You type

/reminders time rule: standup time: clear

Doge Bot replies

Custom time for standup cleared. It follows your work hours again.

Only you can see this

A value that does not parse gets "noon" is not a time I understand. Try 9am, 9:30 or 17:00.

Manage reminder rules: the channel watches that DM members who have not posted, and the built-in follow-up rule. Needs Manage Server and works only in a server. Discord hides it from members without the permission, and the bot checks again; without it the reply is You need Manage Server.

Five subcommands, all with private replies. The name option of edit, enable and disable autocompletes with all rules, enabled and disabled, including follow-up, sorted by name, up to 25. create has no autocomplete. There is no delete: rules are only disabled.

Shows every rule, including disabled ones. No options. Sorted by name, cut at 2000 characters.

  • A channel watch rule checks a channel for the member’s post. Channel watch line: **name** (enabled|disabled) - channel watch - channel - anchor, with - +Nm added when the wait is more than 0.
  • Follow-up line: **name** (enabled|disabled) - follow-up.
  • Anchor is the point in the member’s work day the check counts from. It reads start of work day, end of work day or on request. A missing channel shows not set.
Example of the bot in Discord

You type

/reminder-rules list

Doge Bot replies

art-eod (disabled) - channel watch - not set - end of work day
follow-up (enabled) - follow-up
standup (enabled) - channel watch - <#123456789012345678> - start of work day - +120m

Only you can see this

With no rules the reply is There are no reminder rules.

Creates a channel reminder rule. New rules are enabled.

name text required

Lowercase letters, digits and dashes. Names are compared exactly, and a disabled rule still holds its name.

Allowed: 1 to 50 characters: a-z, 0-9 and dash

channel channel required

Channel to watch.

Allowed: text or announcement channels

anchor choice required

When to check.

Allowed: Start of work day, End of work day

grace number optional

Minutes after the anchor before the bot checks (the grace).

Default: 120 for start of day, 0 for end of day Allowed: 0 to 1440

attachment true or false optional

Require an attachment in the post.

Default: false

message text optional

Reminder text. The command lists it as Reminder text. Filled in: {greeting} {name} {channel} {previous}. {greeting} becomes Good morning from 05:00 to 11:59, Good afternoon from 12:00 to 16:59 or Good evening from 17:00 to 04:59 in the member’s timezone, or Hello with no timezone. {name} is the first word of the member’s name. {channel} is a link to the channel. {previous} is Your previous post: and a link to the member’s latest post in that channel or its threads from before the posting window began (normally 00:00 on the work day in their timezone), or nothing if there is none or the lookup fails. See The reminder engine. Placeholders are not checked.

Default: {greeting} {name}, looks like you haven't posted in {channel} yet. This is a friendly reminder to do so whenever you get the chance. {previous} Allowed: up to 1000 characters

Example of the bot in Discord

You type

/reminder-rules create name: art-end-of-day channel: #art-updates anchor: End of work day grace: 30 attachment: True message: Time to post in {channel}. {previous}

Doge Bot replies

Rule created.


art-end-of-day (enabled)
Kind: channel watch
Channel: <#123456789012345678>
When: end of work day
Grace: 30 minutes
Needs an attachment: yes
Message: Time to post in {channel}. {previous}

Only you can see this

Errors:

CauseReply
Name is not 1 to 50 of a-z, 0-9, -Rule names use lowercase letters, digits and dashes only, up to 50 characters.
A rule with that name existsA rule named "art-end-of-day" already exists.

Changes a rule. Only the options you pass change. 0 for grace and false for attachment are real values and are applied.

name text required
Rule name. Autocompletes.
channel channel optional
Channel to watch.

Allowed: text or announcement channels

anchor choice optional
When to check.

Allowed: Start of work day, End of work day

grace number optional
Minutes after the anchor.

Allowed: 0 to 1440

attachment true or false optional
Require an attachment in the post.
message text optional

Reminder text. The command lists it as Reminder text. {greeting} {name} work everywhere; follow-up rule: {link} {note}. {greeting} and {name} work on every rule, and the follow-up rule also takes {link} and {note}.

Allowed: up to 1000 characters

The success reply is Rule updated., a blank line, then the same seven-line summary shown under create. The message line is cut at 300 characters.

Errors:

CauseReply
Only name passedNothing to change. Pass at least one option to edit. (checked before the rule is looked up)
No rule with that nameThere is no rule named "nope".
Anything but message on the follow-up ruleFollow-up rules only support editing the message.
Follow-up message without {link}The follow-up message must include {link}, or the reminder has nothing to open.

One option each.

name text required
Rule name. Autocompletes.
Example of the bot in Discord

You type

/reminder-rules disable name: art-eod

Doge Bot replies

Rule art-eod is now disabled.

Only you can see this

Enabling an enabled rule, or disabling a disabled one, repeats the success reply. An unknown name gets There is no rule named "nope". The follow-up rule cannot be enabled or disabled here and answers Follow-up rules only support editing the message.

Ask a question about what was said in the server. The reply is private unless you set public. The answer comes from messages and meetings you can see, with links to each source; Linear is not a source. How it works: Asking the bot questions. The member’s view: Asking the bot questions.

question text required

Your question.

Allowed: 1 to 500 characters

public true or false optional

false shows the reply only to you. true posts the answer in the channel and limits it to what every reader of that channel can see. A refusal or an error text is still sent only to you.

Default: false

The reply is an embed (a boxed message) with the answer and linked sources, plus two buttons, 👍 Helpful and 👎 Not helpful, which only the asker can press. A tag question is answered like a public /ask: a reply to the tagging message, with typing shown meanwhile, nothing to press first and no expiry. With public: true, a text that is not an answer is removed from the channel and sent to you privately. In a tag it is a plain reply in the channel, once per member per hour; later refusals only get a ⏳ reaction. A tag is skipped, with no reply, when the bot cannot view the channel, send messages there, embed links or read the message history. The first four checks run before the bot starts on the answer, so their replies are private even for a public /ask. Checks run in this order:

CauseReply
GEMINI_API_KEY is not setAsking is not set up yet. Ask an admin.
The question is only spacesAsk a question.
You already have a question runningI am still answering your last question.
4 questions already runningBusy right now, try again shortly.
You asked your limit in the last 24 hoursYou have asked 50 questions in the last 24 hours. Try again later. The number is ASK_MAX_PER_MEMBER_PER_DAY
The server reached its limitThe daily question limit is reached. Try again later.
Used outside the serverThis only works in the server.
Discord could not say which channels you (or, for a public answer, everyone) can viewI could not check which channels you can see right now. Try again in a minute.
You can search no channel or meeting, or a public answer has none open to its readersI could not find anything you have access to search.
The model found nothingThe answer reads I could not find that in what I can search., or the model’s own short words saying what it could not find. An answer with no valid source counts as no answer
The search ran too longThat took too long to search. Try a shorter period or a more specific question.
The model failedI could not answer that right now. Try again in a minute.

From a tag, the texts for a failed answer, a search that ran too long, a channel list that could not be read and use outside the server end with Use /ask to try again.

Feedback button ids are ask:fb:<id>:<userId>:up or :down, and the bot checks who presses. Buttons with the old ask:answer: id are retired.

CauseReply
Someone other than the asker pressesThis button is not for you.
The id cannot be readThat button is no longer valid.
An old Answer privately buttonThis button is no longer used. Ask with /ask or tag me.
Feedback savedThe answer’s buttons are removed and you get a private Thanks for the feedback. The answer text is not changed.
Feedback could not be savedI could not record that.
Unknown actionUnknown action.

The vote is stored with the question for as long as the record lasts.

Takes notes of a voice call. How a meeting is written up: How voice notes work. How members use it: Voice notes.

Three subcommands, none with options. Every reply is private.

SubcommandWhat it does
startThe bot joins the voice channel you are in, muted, and starts taking notes
stopStops, and writes and posts the notes
statusShows whether notes are being taken
Example of the bot in Discord

You type

/notes start

Doge Bot replies

I joined #team-sync and started taking notes. Run /notes stop when you are done and the summary will be posted.

Only you can see this

The channel is shown as a link. The bot also posts the consent notice in that voice channel’s text chat. The refusals are checked in this order:

CauseReply
The bot’s voice part is not running (the reply is the same for any reason)Voice notes are not enabled on this server.
You are not in a voice channelJoin a voice channel first, then run /notes start.
Notes are being taken, starting or wrapping upI am already taking notes in #team-sync. Only one meeting at a time. The channel is another channel when you cannot see it
The bot lacks Connect, View Channel or Send Messages in that channelAsk an admin to give me Connect, View Channel and Send Messages in that channel.
The bot could not look up the blocked channels (see /notes-admin)I could not check this channel right now. Try again in a moment.
The channel is blocked and you do not have Manage ServerAn admin has turned off notes in this channel.
The bot could not connectI could not join that voice channel. Try again in a moment.
The notice could not be postedI could not post the notice in the voice channel chat, so I did not start taking notes. Check my Send Messages permission there.
The connection dropped while joiningI lost the voice connection while joining. Try again in a moment.

The consent notice is posted in the voice channel’s text chat before anything is transcribed. Its first line is **Taking notes**, started by <name>. The summary goes to <where>, visible to <who>. where <where> is the summary channel and <who> is everyone who can read that channel, or, when the voice channel is not open to everyone, this channel's chat and the people who can access this voice channel. It adds I created <channel> for the summaries. when the bot just created the summary channel, or I could not find or create the summary channel, so this meeting's summary stays in this chat. when it could not. The second line is small text: Everyone who speaks here is transcribed. Audio is not kept; the text is kept for N days and processed by the PlaySafe transcription service and AI. Leave the call to opt out; anyone in it can run /notes stop. N is MEETING_TRANSCRIPT_RETENTION_DAYS.

Discord’s “Invite to voice” sends the bot a direct message with an invite link, and that also starts notes. The bot reacts with 👀, then ✅ or ❌, and replies to the message. Only a member who is in that voice channel and may use bot commands there can start notes this way, at most 5 times a minute per member. The refusals of /notes start apply, with these extra replies:

CauseReply
The invite is not for a voice or stage channel of this serverThat invite is not for a voice channel in this server.
You are not in that channelJoin that voice channel first, then send the invite again.
You may not use bot commands in that channelYou do not have permission to use bot commands in that channel.
It workedI joined #team-sync and started taking notes. Run /notes stop in the server when you are done.

Messages that carry no invite, or that are not direct messages, are ignored.

Anyone in the call, the person who started the notes, or a member with Manage Server from anywhere. The reply is the result line, which is also posted in the voice chat.

CauseReply
No notes are runningI am not taking notes right now.
The bot is still joiningNotes are still starting. Try again in a moment.
It is already finishingThe notes are already being wrapped up.
You are not in the call, did not start it and lack Manage ServerOnly people in the call, the person who started the notes or someone with Manage Server can stop them.
It workedMeeting notes posted in #ai-meeting-transcripts., with Some speech could not be transcribed. when part was missed, and the closed-DM line from the action items when an owner could not get a DM
Under 200 characters of textThere was too little speech (the transcript was too short), so no notes were posted.
Nothing could be transcribedThe transcription service was unavailable, so no notes were written.
The same meeting was already writtenThese notes were already posted.
The AI is unavailableThe AI service was unavailable, so the notes are not written yet. I kept what was said and will write them up automatically in a few minutes.
The server’s daily total is used upThe daily limit for meeting notes has been reached. Try again tomorrow.
The starter’s own daily limit is used upYou have reached your daily limit for meeting notes. Try again tomorrow.
The summary channel is not availableThe meeting notes channel is not available.
Meeting notes are offMeeting notes are turned off.
The write-up was interruptedThe notes were interrupted. or, at shutdown, What was said is saved and the notes will be finished when the bot is back.
Anything elseSomething went wrong while writing the notes.

Notes also stop on their own. The bot then posts the result line in the voice chat with a lead-in and DMs the same text to the person who started the notes, because nobody may be left to read the chat.

CauseLead-in
Every person left the callEveryone left, so I stopped taking notes.
The call reached VOICE_NOTES_MAX_MINUTESThe maximum meeting length was reached, so I stopped taking notes.
The bot lost its voice connection or was moved outI was disconnected from the voice channel, so I stopped taking notes.
The bot is shutting downThe bot is restarting, so I stopped taking notes.

Once per session, when the transcription service keeps failing, the bot posts The transcription service is having trouble, so parts of this meeting may be missing from the notes. in the voice chat.

StateReply
Nothing runningI am not taking notes right now.
Running in a channel you can seeTaking notes in #team-sync, started by @Sam since 12 minutes ago., with (joining) or (wrapping up) after the channel while it is starting or finishing
Running in a channel you cannot seeI am taking notes in a channel you cannot see.

The mention shows the person’s name, and the time is Discord’s relative time. The mention does not ping.

Manage where voice notes are allowed and where summaries go. Needs Manage Server and works only in a server. Discord hides it from members without the permission, and the bot checks again; without it the reply is You need Manage Server. Every reply is private. How it is used: Voice notes for admins.

SubcommandWhat it does
excludeBlocks notes in a voice or stage channel
includeAllows notes there again
listShows the blocked channels
summary-channel setSets the name of the channel summaries and uploads use
summary-channel showShows that name
channel channel required
Voice or stage channel.
CommandReply
excludeNotes are now blocked in #hr-room. or #hr-room is already excluded. Followed by The notes running there were stopped: <result line> when notes were running in that channel
includeNotes are allowed again in #hr-room. or #hr-room was not excluded.

Blocking is only checked when notes start. Blocked channels refuse members, and a member with Manage Server may still start notes there.

No options. The reply is Notes are blocked in: and one channel link per line, oldest first. Whole lines are kept up to about 1900 characters, then ...and N more. With none it is No channels are excluded.

name text required

The channel name. It is trimmed, lowercased, spaces become hyphens and repeated hyphens collapse. Only a-z, 0-9, - and _ may remain. The channel need not exist.

Allowed: 1 to 100 characters

CauseReply
The name is not valid after that clean-upThat is not a valid channel name. Use letters, numbers, hyphens and underscores, up to 100 characters.
It could not be savedI could not save the summary channel name. Try again in a moment.
A text channel with that name existsThe summary channel is now #team-meetings. A channel with that name already exists and will be used. The old channel is not moved or deleted.
None existsThe summary channel is now #team-meetings. A channel with that name does not exist yet; it will be created the first time someone starts voice notes. Transcript uploads are only read once it exists. The old channel is not moved or deleted.

No options. The reply is The summary channel is #team-meetings (set by an admin). or (the default), followed by The channel exists. or A channel with that name does not exist yet; it is created the first time someone starts voice notes.

Gets a project summary. A summary is a named setup (called a config in the options) that says which Linear team to cover, how often, and who receives it. Everyone can see the command, but a given summary works only for its recipients and for members with Manage Server. How summaries are built and sent: Summaries.

Writes a summary right now, for you only. Private reply. The bot reads only channels you can see yourself, so Manage Server does not widen what it uses.

config text required

Which summary. Autocomplete offers enabled summaries you may use, filtered by what you type, up to 25.

period choice optional

How far back to look. The period always ends now.

Default: 24h for a daily summary, 7d for weekly and on_demand Allowed: 24h, 7d, 14d, 30d

Checks run in this order. The first one that fails ends the command.

CauseReply
No summary with that name, it is disabled (also for Manage Server), or it is a personal digestThere is no summary called "nope". Pick one from the list that appears as you type.
You are not a recipient and do not have Manage ServerYou are not a recipient of this summary. Ask an admin to add you with /summary-admin recipients add.
GEMINI_API_KEY is not setSummaries are not available: AI is not configured.
Used outside the serverThis command only works in the server.
You asked less than 60 seconds agoPlease wait 42 seconds before asking for another summary. /summary now and /interests now share this limit. (the seconds left, rounded up)
3 summaries are already being writtenBusy right now, try again shortly.
The daily limit is used upDaily summary limit reached, try again later.
None of the channels mapped to the team is visible to youNo channel mapped to this team is visible to you. Ask an admin to check /summary-admin list.
The model or Discord failed and nothing was sentI could not write that summary right now. Nothing was sent; try again in a minute.
Example of the bot in Discord

You type

/summary now config: weekly-launch period: 7d

Doge Bot replies

weekly-launch - <t:1789900000:d> to <t:1790504800:d>
Launch build is stable and one review is waiting


Progress
- Release build passed on all targets


Blockers & risks
- Trailer approval is waiting on legal

Only you can see this

The first line is the summary name and the period. The headline and the items are written by the model, so your text will differ. When the model returns nothing usable, the headline reads No summary this time. The layout is fixed:

  • Sections appear in this order, and empty ones are left out: Progress, Blockers & risks, Decisions, Next.
  • The model writes at most 8 items per section. Blockers & risks can be longer, because the in-review tickets below are added after the model’s items. An item can end with links the bot built itself, in brackets: discord for a message, or the Linear id for a ticket, for example (discord, PLAY-12).
  • With nothing to report, No activity in this period. replaces the sections.
  • When Linear is connected, tickets that have been in review for 7 days or more are added at the end of Blockers & risks. Each reads like PLAY-7 Fix shader is in review for 9 days, followed by its Linear link. The bot checks at most 30 tickets in review. If there are more, it adds the line More issues in review than could be checked. If Linear is not connected or the lookup fails, none are added.
  • The text is cut into pieces of at most 2000 characters. The first piece is the reply and the rest are private follow-up messages. Mentions are switched off.

Rules:

  • The 60 second wait is per person and resets on restart. If nothing was sent, it is cleared.
  • A summary can take up to 180 seconds to write.
  • The daily limit is SUMMARY_MAX_GENERATIONS_PER_DAY, counted per recipient over the last 24 hours across scheduled and on-demand summaries. Sent and failed summaries count, and so does a personal digest that matched nothing. /interests now uses the same limit.
  • REMINDER_ALLOWLIST does not apply to /summary now. For summaries it limits only the scheduled DMs.
  • A summary is never posted in a channel.

Follow people, topics and channels and get a personal digest. Every reply is private, and it only ever works on your own interests. How digests are built: Summaries. The member’s view: Interests.

An interest needs at least one of person, topic or a channel. You can have 10.

person user optional
A person to follow.
topic text optional
A topic in free text.

Allowed: up to 200 characters

channel, channel_2, channel_3 channel optional
Channels to focus on.

Allowed: up to 3 text, announcement or forum channels

prompt text optional
Extra guidance for the digest.

Allowed: up to 500 characters

CauseReply
SuccessSaved: <@person>, "topic", <#channel> (note: ...). Your digest is on: every weekday at 09:00 (Europe/London). Change it with /interests digest, or try /interests now. The digest part reads is paused when you paused it, and weekly on Friday for a weekly digest
Success, no timezone savedSaved: .... Your digest is on: every weekday at 09:00, once you set a timezone. Change it with /interests digest. and a second line I need your timezone first. Run /hours set and fill in `zone`.
Topic or note is only spacesThe topic cannot be empty. Nothing was saved. or The note cannot be empty. Nothing was saved.
Same person, topic (any letter case), channels and note already savedYou already follow that.
None of person, topic or channel givenPick at least one person, topic or channel. Nothing was saved.
You already have 10You can follow at most 10 interests. Remove one first.

Shows your interests, numbered. With none: You are not following anything yet. Add one with /interests add.

Takes interest (required, autocomplete over your own interests, labelled by number) and the same options as add. Only the options you give change, and giving channels replaces the channel list. A person, topic or note cannot be cleared this way, only replaced. Replies Updated: <description>. With none given: Nothing to change. Provide at least one option. An interest that is not yours gets That interest was not found. A change that makes it the same as another interest of yours gets You already follow that.

Takes interest (required, autocomplete). Deletes it. Replies Removed. or That interest was not found.

Needs a timezone. Without one: I need your timezone first. Run /hours set and fill in `zone`. Creates your digest on first use (every weekday, 09:00, on). An option you leave out keeps its current value.

cadence choice optional
How often. A new digest is every weekday, which skips Saturday and Sunday.

Allowed: every weekday, weekly

time text optional
Send time in your timezone, such as 9am or 09:00. A new digest is 09:00. Autocomplete offers half-hour slots.
weekday choice optional
Needed with weekly: Weekly digests need a weekday. Run it again and fill in `weekday`. Giving every weekday clears a saved weekday.

Allowed: Monday to Sunday

state choice optional
Pausing keeps your interests. A new digest is active.

Allowed: active, paused

Replies Your digest is on: every weekday at 09:00 (Europe/London). (weekly on Friday at 09:00 (Europe/London) for a weekly digest) or Your digest is paused. It was set for every weekday at 09:00 (Europe/London). The checks run in this order: timezone, then the time (I could not read that time. Try 9am or 09:00.), then a weekly cadence with no weekday. A schedule the bot refuses, such as a weekday given for an every-weekday digest, answers with the reason and Your digest schedule was not changed., for example Weekday only applies to weekly summaries. Your digest schedule was not changed.

Writes a digest of the last 24 hours for you only. Needs a timezone. Checks run in this order:

CauseReply
No timezone savedI need your timezone first. Run /hours set and fill in `zone`.
GEMINI_API_KEY is not setSummaries are not available: AI is not configured.
Used outside the serverThis command only works in the server.
Asked less than 60 seconds agoPlease wait 42 seconds before asking for another summary. /summary now and /interests now share this limit.
3 summaries already being writtenBusy right now, try again shortly.
You have no interestsAdd an interest first with /interests add.
You already ran /interests now 5 times in the last 24 hours (/summary now does not count)You can ask for 5 on-demand digests per day. Try again later or wait for your digest.
The daily limit is used upDaily summary limit reached, try again later.
You can see none of the channels the bot storesI could not find any channels you can view right now.
Nothing matchedNothing matched your interests in the last 24 hours.
The model failed and nothing was sentI could not write that summary right now. Nothing was sent; try again in a minute.

The reply is cut into pieces of at most 2000 characters, like /summary now. A request that matched nothing still counts toward the daily limit. Once a request passes the checks above, the 60 second wait stays even when the request fails. If the digest ends with nothing sent and no reason, the reply is Something went wrong, try again in a minute.

Manage project summaries (the named setups called configs). Needs Manage Server and works only in a server. Discord hides it from members without the permission, and the bot checks again; without it the reply is You need Manage Server.

Nine subcommands. Every reply is private. Autocomplete answers with an empty list for anyone without Manage Server.

SubcommandWhat it does
listShows every summary
createCreates a summary
promptSets what the summary should emphasise
recipients addAdds a person or role as a recipient
recipients removeRemoves a person or role
map-channelMaps a channel to a Linear team
unmap-channelRemoves a channel mapping
enable, disableTurns a summary on or off

The config option of prompt, recipients and enable and disable autocompletes with all summaries, enabled and disabled, filtered by what you type, up to 25. The team option autocompletes with Linear teams as Name (KEY), up to 25, and the project option with the projects of the team already chosen in the same command. Both are empty when no Linear key is set.

There is no delete subcommand, and no way to change cadence, weekday, time, description, team or project after creating a summary. The review status (In Review) and the 7 day review flag have no command. To change one of the fixed settings, create a new summary and disable the old one.

Error shared by the subcommands that take a config (prompt, recipients add, recipients remove, enable, disable):

CauseReply
No summary with that nameThere is no summary called "nope".
The name is a personal digest (interests- and an id)Personal digests are managed with /interests. (for prompt, this arrives after the form is sent)

Shows every summary, including disabled ones. No options. Sorted by name. Whole lines are kept up to about 1950 characters, then ...and N more closes the list.

A line reads **name** (enabled|disabled) - cadence [Weekday] HH:MM in each recipient's timezone - team label - N recipients - N channels. The cadence is shown as stored: daily, weekly or on_demand. The weekday shows only when one is set. The team label is Name (KEY), or a Linear team when Linear cannot name it. 1 recipient and 1 channel are singular. The recipient count is the people and roles added, so a role counts once. The channel count includes the threads and forum posts under each mapped channel. A team with no mapped channel reads 0 channels (unmapped).

Example of the bot in Discord

You type

/summary-admin list

Doge Bot replies

art-daily (disabled) - daily 09:00 in each recipient’s timezone - team Art (ART) - 1 recipient - 0 channels (unmapped)
weekly-launch (enabled) - weekly Friday 09:00 in each recipient’s timezone - team Launch (LCH) - 2 recipients - 3 channels

Only you can see this

With none the reply is There are no summaries.

Creates a summary. New summaries are enabled, have no prompt, and look at tickets in the state In Review.

name text required

Lowercase letters, digits and dashes. Names are unique, and a disabled summary still holds its name.

Allowed: 1 to 50 characters: a-z, 0-9 and dash

team text required

Linear team. Pick from the autocomplete. With a Linear key, an id that is not a team is rejected.

cadence choice required

How often it is sent. daily skips Saturday and Sunday in each recipient’s timezone. on_demand is never scheduled and works only with /summary now.

Allowed: daily, weekly, on_demand

weekday choice optional

Day for weekly summaries. Required for weekly, not allowed for the others.

Allowed: Monday 1 to Sunday 7

time text optional

Send time, read in each recipient’s own timezone. Autocomplete offers half-hour slots from 00:00 to 23:30, up to 25. Any format from the time table above is accepted, such as 9:30am or 1730. It is stored as HH:MM:00.

Default: 09:00

description text optional

What this summary covers. Given to the model as context.

Allowed: up to 200 characters

project text optional

Limit tickets to one Linear project. Pick from the autocomplete after choosing the team. A typed value must be 1 to 64 letters, digits, dashes or underscores. The bot does not check that it exists.

Example of the bot in Discord

You type

/summary-admin create name: weekly-launch team: Launch (LCH) cadence: weekly weekday: Friday time: 9am

Doge Bot replies

Created summary weekly-launch (weekly Friday 09:00 in each recipient’s timezone, team Launch (LCH)). Set its prompt with /summary-admin prompt and add recipients with /summary-admin recipients add.

Only you can see this

Errors:

CauseReply
Name is not 1 to 50 of a-z, 0-9, -Config names use lowercase letters, digits and dashes only, up to 50 characters.
time does not parseI could not read that time. Try 09:00, 9:30am or 1730.
The team is not one of the Linear teamsPick a team from the list.
No Linear key is setLinear is not connected, so I cannot validate the team. Ask an admin to set LINEAR_API_KEY.
weekly without weekdayPick a weekday for weekly summaries.
weekday with daily or on_demandWeekday only applies to weekly summaries.
project is not a valid idLinear project id is invalid.
Team id is not a valid idLinear team id is invalid.
The name starts with interests-Config names starting with interests- are reserved for personal digests.
A summary with that name existsThere is already a summary called "weekly-launch".

If Linear fails for any other reason, the team is not checked against Linear. The value must still be 1 to 64 letters, digits, dashes or underscores, or the reply is Linear team id is invalid. This is the only case where that reply appears.

Opens a form to edit what the summary should emphasise.

config text required
Summary name. Autocompletes.

The form is titled Prompt for <name> (cut to 45 characters). It has one paragraph field, Summary prompt, optional, up to 2000 characters, with the placeholder Optional: what to emphasise, e.g. launch blockers and release risk. The field starts with the current prompt. Only the person who opened the form can send it.

CauseReply
Saved with textPrompt updated for weekly-launch.
Saved emptyPrompt cleared for weekly-launch.
Someone else sends the formThis form is not for you.
The sender lost Manage ServerYou need Manage Server.
No summary with that name (before the form opens)There is no summary called "nope".

A recipient gets the scheduled DM and may run /summary now for that summary. A role covers everyone who holds it when the summary is sent.

config text required
Summary name. Autocompletes.
user user optional
A person. Give this or role, not both.
role role optional
A role. Give this or user, not both.
Example of the bot in Discord

You type

/summary-admin recipients add config: weekly-launch user: @Sam

Doge Bot replies

Added <@123456789012345678> to weekly-launch.

Only you can see this

CauseReply
add, personAdded <@123456789012345678> to weekly-launch.
add, roleAdded <@&123456789012345678> to weekly-launch.
add, person with no saved timezoneThe reply above, then They have no timezone set, so they will not get scheduled summaries until they set one with /hours set.
add, already a recipient<@123456789012345678> is already a recipient of weekly-launch.
removeRemoved <@123456789012345678> from weekly-launch.
remove, not a recipient<@123456789012345678> was not a recipient of weekly-launch.
Neither or both of user and rolePick exactly one of user or role.

A summary can have the same person or role only once.

Maps a channel to a Linear team. Every summary on that team reads the channels mapped to it, plus the threads and forum posts under them. A channel maps to one team at most.

channel channel required
Channel to map.

Allowed: text, announcement or forum channels

team text required
Linear team. Autocompletes.
Example of the bot in Discord

You type

/summary-admin map-channel channel: #launch team: Launch (LCH)

Doge Bot replies

Mapped <#123456789012345678> to Launch (LCH).

Only you can see this

CauseReply
The bot has not stored the channel yetThat channel has not been indexed yet. Try again after the backfill has seen it. The backfill is the bot’s pass that reads and stores channel history.
Team problemsThe same replies as create: Pick a team from the list., the Linear-not-connected text, or Linear team id is invalid. when Linear fails for another reason and the value is not a valid id

Removes a channel mapping.

channel channel required
Channel to unmap.

Allowed: text, announcement or forum channels

Replies Unmapped <#123456789012345678>. or <#123456789012345678> was not mapped.

One option each: config (required, autocompletes).

Example of the bot in Discord

You type

/summary-admin disable config: art-daily

Doge Bot replies

art-daily is now disabled.

Only you can see this

The reply is <name> is now enabled. or <name> is now disabled. and repeats if nothing changed. A disabled summary is skipped by the scheduler, hidden from /summary now autocomplete and refused by /summary now, even for Manage Server.

Link Discord members to Linear users, which decides the team and the assignee of their tickets. Needs Manage Server and works only in a server. Discord hides it from members without the permission, and the bot checks again; without it the reply is You need Manage Server.

Four subcommands. Every reply is private, and no reply pings anyone. If Linear does not answer, link, list and sync reply Could not reach Linear. Try again in a moment. unlink never calls Linear. The bot also links members by exact name on its own: see Linking members to Linear.

SubcommandWhat it does
linkLinks one member to one Linear user and stops name matching for that member
unlinkRemoves the link and stops name matching for that member
listMatches by name, then shows who is linked, unsure or not matched
syncThe same as list, with a first line saying how many were matched
member user required
Discord member to link.
linear_user text required
Linear user. Autocompletes with active Linear users as Name (display name), or just the name when the display name is the same, matching what you type anywhere in that label, up to 25. The list is empty for anyone without Manage Server, and when Linear cannot be reached.
Example of the bot in Discord

You type

/linear-admin link member: @Sam linear_user: Sam Rivera

Doge Bot replies

Linked <@123456789012345678> to Linear user Sam Rivera. Their tickets go to: Engineering, Tools.

Only you can see this

CauseReply
The Linear user is on no teamLinked <@123456789012345678> to Linear user **Sam Rivera**. They are not on any Linear team, so they choose from all public teams.
The team lookup fails after the link was savedLinked <@123456789012345678> to Linear user **Sam Rivera**.
The value is not one of the Linear usersPick a Linear user from the list.
Another member already holds that Linear userThat Linear user is already linked to <@234567890123456789>. (That Linear user is already linked to another member. when that member is no longer listed)

The link is saved as a manual decision, so name matching never changes it. Linking a member who is already linked replaces their link. If the bot has no record of the member yet, it saves one first.

member user required
Discord member to unlink.
CauseReply
The member was linkedUnlinked <@123456789012345678>.
The member had no link, or the bot has no record of them<@123456789012345678> was not linked.

When the bot has a record of the member, unlinking marks them as decided by an admin, even if they had no link, so name matching skips them from then on. Use link to give them a link again.

No options. First the bot runs the name match, so the report is current. Then it shows four sections, in this order. A section with nothing in it still shows its heading with (0).

SectionWhat it holds
Linked (N)One line per linked member: <@123456789012345678> - Sam Rivera, with (matched by name) added when the bot made the link. Reads a Linear user when the Linear user is no longer in the active list
Unsure (N)<@123456789012345678> - could be: Sam Rivera, Sam Rivers. Up to 3 names. These need link
No match (N)The members with no candidate, as mentions. Up to 20, then and K more
Not matched on purpose (N)Members an admin unlinked, as mentions
Example of the bot in Discord

You type

/linear-admin list

Doge Bot replies

Linked (2)
<@123456789012345678> - Sam Rivera (matched by name)
<@234567890123456789> - Alex Doe
Unsure (1)
<@345678901234567890> - could be: Jo Lee, Jo Leigh
No match (1)
<@456789012345678901>
Not matched on purpose (0)

Only you can see this

Whole lines are kept up to about 1950 characters, then ...and N more lines closes the report.

No options. It runs the same name match and shows the same report as list, with one line first.

Example of the bot in Discord

You type

/linear-admin sync

Doge Bot replies

Matched 2 members by name.
Linked (2)
…

Only you can see this

The line reads Matched N members by name. with the number of members linked by this run. list runs the match too but does not show the line.