Skip to content

@robojs/welcome - Welcome & Goodbye for Discord bots #450

Description

@Pkmmte

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/server is 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.
  • guildMemberAdd and guildMemberRemove events 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 preview and /goodbye preview display exactly what would be sent.
  • Per-guild settings persist reliably using Flashcore, isolated by guildId.
  • Optional HTTP API automatically mounts only if @robojs/server is 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-json accepts 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 → returns WelcomeConfig
  • PATCH → partial update of config
  • POST /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 guildMemberAdd and guildMemberRemove.
  • 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 _v in 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)

  1. Install: npx robo add @robojs/welcome
  2. Ensure Server Members Intent is enabled (Discord developer portal + client code)
  3. Run locally: npx robo dev
  4. Configure with /welcome … commands

Testing (encouraged, not required)

  • Unit tests for token expansion and config get/set
  • Basic event simulation for guildMemberAdd to assert the right post destination
  • Linting/formatting checks as in repo standards

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions