@robojs/welcome - Welcome & Goodbye for Discord bots
Motivation
MEE6/Dyno-style welcome features are universally loved: a warm channel greeting and optional DM onboarding. Robo.js already provides the primitives: file-based commands/events and a tiny KV store (Flashcore). This plugin will make onboarding new members delightful and easy to configure.
Goals
- Welcome & goodbye messages, configurable per guild
- Optional DM onboarding message to new members
- Simple message definitions (plain text and basic embed JSON)
- Per-guild persistence with Flashcore (clean namespacing)
- Helpful preview command(s) for fast iteration
- Optional HTTP API when
@robojs/serveris installed (not a hard dep) - Friendly docs and examples
User Stories
- As a server admin, I want to set a welcome channel and message quickly so new members feel greeted.
- As a server admin, I want to send a concise DM with helpful links to new members.
- As a moderator, I want to preview the messages without waiting for a real member to join.
Acceptance Criteria
- Slash commands to configure welcome and goodbye flows are available and auto-register in a Robo project.
guildMemberAddandguildMemberRemoveevents trigger appropriate messages.- Welcome and goodbye messages can include placeholder tokens and support text or minimal embed JSON.
- DM onboarding sends to new members when configured and gracefully handles closed DMs.
/welcome previewand/goodbye previewdisplay exactly what would be sent.- Per-guild settings persist reliably using Flashcore, isolated by
guildId. - Optional HTTP API automatically mounts only if
@robojs/serveris installed. - Clear documentation about required Discord intents and bot permissions.
Scope & Features
1) Welcome message (channel)
- Configure a target text channel.
- Message can be either plain text or a minimal embed JSON.
- Simple placeholder tokens (see Tokens).
2) Goodbye message (channel)
- Optional; same capabilities as Welcome.
3) DM Onboarding (optional)
- Plain text or minimal embed JSON sent to the new user.
- Graceful fallback if user DMs are closed (log + optional ephemeral notice to admin who ran preview).
4) Preview
- Command to render messages now (to channel or ephemeral) so admins can iterate fast.
5) Rate-safe delivery
- Queue + backoff to stay within Discord limits (burst-join scenarios).
Tokens (simple placeholders)
Supported in text and embed fields:
{user}— user mention{username}— username{tag}— username#discriminator (or username if discriminator-less){id}— user ID{guild}— guild name{memberCount}— current member count
Unresolved tokens remain literal. Keep this minimal for v1; more can be added later.
API Design
Slash Commands
/welcome set-channel <#channel>
/welcome message set <text-or-embed-json>
/welcome message clear
/welcome dm set <text-or-embed-json>
/welcome dm clear
/welcome toggle <on|off>
/welcome preview [here|channel]
/goodbye set-channel <#channel>
/goodbye message set <text-or-embed-json>
/goodbye message clear
/goodbye toggle <on|off>
/goodbye preview [here|channel]
Notes
text-or-embed-jsonaccepts either raw text or a minimal embed shape (see Examples)- Permission checks: bot must be able to Send Messages/Embed Links in the configured channel
Imperative API (for future dashboards)
export interface WelcomeConfig {
enabled?: boolean
channelId?: string
message?: TextOrEmbed
dm?: TextOrEmbed
goodbye?: {
enabled?: boolean
channelId?: string
message?: TextOrEmbed
}
}
export type TextOrEmbed =
| { type: 'text'; content: string }
| { type: 'embed'; data: MinimalEmbed }
export const Welcome = {
getGuildConfig(guildId: string): Promise<WelcomeConfig>,
setGuildConfig(guildId: string, patch: Partial<WelcomeConfig>): Promise<void>,
resetGuildConfig(guildId: string): Promise<void>,
preview(guildId: string, opts?: { channelId?: string; dm?: boolean }): Promise<void>
}
Optional HTTP API (mounted only if @robojs/server is installed)
- Base:
/api/welcome/:guildId GET→ returnsWelcomeConfigPATCH→ partial update of configPOST /preview→ triggers a preview- Auth: use a simple bearer token from env for MVP; document that this is intended for private dashboards
Behavior Details
Events & Intents
- Subscribe to
guildMemberAddandguildMemberRemove. - Document how to enable Server Members Intent in the bot settings and in code.
Rate Limits
- Use a small in-memory queue for outbound messages; respect 429s and retry-after headers.
- Coalesce duplicate joins when many happen at once (lightweight debounce).
Permissions & Safety
- Validation when setting channels.
- Helpful error messages if permissions are missing.
DM Fallback
- If DM send fails, log the failure; do not spam retries.
Data Model (Flashcore)
- Namespace:
guildId - Key:
welcome:config - Shape:
WelcomeConfig - Versioning: include
_vin the stored object (for upgrade functions in future changes later)
Architecture & File Layout
@robojs/welcome
├─ package.json
├─ src/
│ ├─ commands/
│ │ ├─ welcome/
│ │ │ ├─ set-channel.ts
│ │ │ ├─ message-set.ts
│ │ │ ├─ message-clear.ts
│ │ │ ├─ dm-set.ts
│ │ │ ├─ dm-clear.ts
│ │ │ ├─ toggle.ts
│ │ │ └─ preview.ts
│ │ └─ goodbye/
│ │ ├─ set-channel.ts
│ │ ├─ message-set.ts
│ │ ├─ message-clear.ts
│ │ ├─ toggle.ts
│ │ └─ preview.ts
│ ├─ events/
│ │ ├─ guildMemberAdd.ts
│ │ └─ guildMemberRemove.ts
│ ├─ lib/
│ │ ├─ config.ts # Flashcore get/set, schema, defaults, migrations
│ │ ├─ render.ts # token expansion + embed builder
│ │ ├─ post.ts # channel/DM posting with queue + backoff
│ │ └─ permissions.ts # capability checks & helpful errors
│ └─ api/ (optional; only if @robojs/server is installed)
│ ├─ welcome.get.ts
│ ├─ welcome.patch.ts
│ └─ preview.post.ts
└─ README.md
Examples
1) Minimal welcome text
Welcome {user}! You’re member #{memberCount}. Please read the rules in #rules.
2) Minimal embed JSON
{
"type": "embed",
"data": {
"title": "Welcome, {username}! 🎉",
"description": "Say hi to {user}! You’re member #{memberCount}.",
"image": "https://example.com/welcome-banner.png"
}
}
3) DM onboarding example
Welcome to {guild}! Quick links:
• Rules: #rules
• Roles: #get-roles
• Introductions: #introductions
Setup Notes (for users)
- Install:
npx robo add @robojs/welcome - Ensure Server Members Intent is enabled (Discord developer portal + client code)
- Run locally:
npx robo dev - Configure with
/welcome …commands
Testing (encouraged, not required)
- Unit tests for token expansion and config get/set
- Basic event simulation for
guildMemberAddto assert the right post destination - Linting/formatting checks as in repo standards
References
-
Robo.js docs: Overview, Commands, Events, Flashcore, Server plugin
-
Discord developer docs: Gateway Intents, Rate Limits
@Pkmmte I wan't to work on this. Can I get assigned?
@dthlss26 Sure, task has been assigned! Feel free to reach out either here or on our Discord if you have any questions.