{"id":34645578,"url":"https://github.com/r-webdev/moderation-tool","last_synced_at":"2026-05-25T18:03:52.595Z","repository":{"id":323177316,"uuid":"1065875809","full_name":"r-webdev/moderation-tool","owner":"r-webdev","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-12T12:19:58.000Z","size":116,"stargazers_count":0,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-12T14:16:17.805Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/r-webdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-28T15:52:25.000Z","updated_at":"2026-04-12T12:19:52.000Z","dependencies_parsed_at":"2025-12-12T16:02:22.878Z","dependency_job_id":null,"html_url":"https://github.com/r-webdev/moderation-tool","commit_stats":null,"previous_names":["r-webdev/moderation-tool"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/r-webdev/moderation-tool","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-webdev%2Fmoderation-tool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-webdev%2Fmoderation-tool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-webdev%2Fmoderation-tool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-webdev%2Fmoderation-tool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/r-webdev","download_url":"https://codeload.github.com/r-webdev/moderation-tool/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r-webdev%2Fmoderation-tool/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33486787,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-25T14:31:05.219Z","status":"ssl_error","status_checked_at":"2026-05-25T14:31:02.878Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-24T17:42:56.710Z","updated_at":"2026-05-25T18:03:52.583Z","avatar_url":"https://github.com/r-webdev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Discord Moderation Tool\n\nA TypeScript Discord bot built with Discord.js v14, designed for server moderation with a clean, type-safe architecture.\n\n## Features\n\n- **Slash Commands**: Traditional `/command` style interactions\n- **Context Menu Commands**: Right-click context menus for users and messages\n- **Event-Driven Architecture**: Modular event handling system\n- **Type-Safe**: Full TypeScript support with discriminated unions\n- **Environment Configuration**: Secure configuration management\n- **Command Helpers**: Easy-to-use helpers for creating different command types\n\n## Installation\n\n### Prerequisites\n\n- Node.js 22.20.0+\n- pnpm (recommended) or npm\n- A Discord bot token\n\n### Setup\n\n1. **Clone the repository**\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd moderation-tool\n   ```\n\n2. **Install dependencies**\n   ```bash\n   pnpm install\n   ```\n\n3. **Configure environment**\n   ```bash\n   cp .env.local.example .env.local\n   ```\n   Edit `.env.local` with your bot credentials:\n   ```env\n   DISCORD_TOKEN=your_bot_token_here\n   CLIENT_ID=your_client_id_here\n   SERVER_ID=your_guild_id_here\n   SPAM_DETECTION_CHANNEL_ID=your_spam_detection_channel_id_here\n   ROLE_REGULAR_ID=your_regular_role_id_here\n   ```\n\n4. **Build and run**\n   ```bash\n   # Development (with hot reload)\n   pnpm dev\n\n   # Production build\n   pnpm build:ci\n   pnpm start:ci\n   ```\n\n\n## Creating Commands\n\n### Slash Commands\n\nUse `createSlashCommand` helper for traditional `/command` interactions:\n\n```typescript\nimport { createSlashCommand } from \"../commands/helpers.js\";\n\nexport const ping = createSlashCommand({\n  data: {\n    name: \"ping\",  // Must be lowercase\n    description: \"Replies with Pong!\",\n    options: [     // Optional: command options\n      {\n        name: \"message\",\n        description: \"Optional message to include\",\n        type: ApplicationCommandOptionType.String,\n        required: false,\n      }\n    ]\n  },\n  execute: async (interaction) =\u003e {\n    await interaction.reply(\"Pong!\");\n  },\n});\n```\n\n### Context Menu Commands\n\n#### User Context Menu Commands\n\n```typescript\nimport { createUserContextMenuCommand } from \"../commands/helpers.js\";\n\nexport const userInfo = createUserContextMenuCommand({\n  data: {\n    name: \"Get User Info\",  // Can contain spaces and capitals\n  },\n  execute: async (interaction) =\u003e {\n    const targetUser = interaction.targetUser;\n    await interaction.reply(`User: ${targetUser.tag}`);\n  },\n});\n```\n\n#### Message Context Menu Commands\n\n```typescript\nimport { createMessageContextMenuCommand } from \"../commands/helpers.js\";\n\nexport const reportMessage = createMessageContextMenuCommand({\n  data: {\n    name: \"Report to Moderators\",\n  },\n  execute: async (interaction) =\u003e {\n    const targetMessage = interaction.targetMessage;\n    // Handle message reporting logic\n    await interaction.reply(\"Message reported!\");\n  },\n});\n```\n\n### Registering Commands\n\nAdd your commands to `src/commands/index.ts`:\n\n```typescript\nimport { ping } from \"./ping.js\";\nimport { reportMessage } from \"./reportMessage.js\";\nimport type { Command } from \"./types.js\";\n\nexport const commands = new Map\u003cstring, Command\u003e(\n  [ping, reportMessage].flat().map((command) =\u003e [command.data.name, command])\n);\n```\n\n## Creating Events\n\nEvents are handled automatically through the event system. Create new events using the `createEvent` helper:\n\n```typescript\nimport { Events } from \"discord.js\";\nimport { createEvent } from \"../events/helpers.js\";\n\nexport const messageCreateEvent = createEvent(\n  {\n    name: Events.MessageCreate,\n  },\n  async (message) =\u003e {\n    if (message.author.bot) return;\n\n    // Handle message logic\n    console.log(`Message from ${message.author.tag}: ${message.content}`);\n  }\n);\n```\n\n### Registering Events\n\nAdd your events to `src/events/index.ts`:\n\n```typescript\nimport { messageCreateEvent } from \"./message-create/index.js\";\nimport { readyEvent } from \"./ready/index.js\";\nimport type { DiscordEvent } from \"./types.js\";\n\nexport const events: DiscordEvent[] = [readyEvent, messageCreateEvent];\n```\n\n## Configuration\n\nThe bot uses a centralized configuration system in `src/env.ts`. Environment variables are validated and logged on startup.\n\n### Required Environment Variables\n\n- `DISCORD_TOKEN`: Your Discord bot token\n- `CLIENT_ID`: Your Discord application client ID\n- `SERVER_ID`: Guild ID (Server ID) for guild-specific command registration\n\n## Development\n\n### Scripts\n\n- `pnpm dev` - Start development server with hot reload\n- `pnpm build:ci` - Build for production\n- `pnpm start:ci` - Run production build\n- `pnpm typecheck` - Run TypeScript type checking\n- `pnpm lint` - Lint code with Biome\n- `pnpm format` - Format code with Biome\n\n### Code Quality\n\nThis project uses:\n- **Biome** for linting and formatting\n- **TypeScript** for type safety\n- **Husky** + **lint-staged** for pre-commit hooks\n\n### Adding New Features\n\n1. **Commands**: Create in `src/commands/` and register in `src/commands/index.ts`\n2. **Events**: Create in `src/events/` and register in `src/events/index.ts`\n3. **Utilities**: Add to `src/utils/`\n4. **Configuration**: Update `src/env.ts` for new environment variables\n\n## Deployment\n\nThis project includes automated deployment using GitHub Actions and Docker with direct SSH deployment to your VPS.\n\n### Prerequisites\n\n- A VPS with Docker and Docker Compose installed\n- SSH access to your VPS\n- GitHub repository with Actions enabled\n- Discord bot credentials\n\n### GitHub Actions Setup\n\n1. **Set up repository secrets**\n   - Go to Settings → Secrets and variables → Actions\n   - Add the following secrets:\n     - `VPS_HOST`: Your VPS IP address or hostname\n     - `VPS_USER`: SSH username for your VPS\n     - `VPS_SSH_KEY`: Private SSH key for authentication\n     - `DISCORD_TOKEN`: Your Discord bot token\n     - `CLIENT_ID`: Your Discord application client ID\n     - `SERVER_ID`: Your Discord server (guild) ID\n\n### VPS Setup\n\nThe CI/CD pipeline handles all the setup automatically. The first deployment will:\n- Create the `moderation-tool-bot` directory on your VPS\n- Clone the repository and set up the environment\n- Subsequent deployments will simply pull the latest changes\n\n### Automated Deployment\n\nThe GitHub Actions workflow will automatically:\n- Build and test on every push/PR to main branch\n- SSH directly to your VPS\n- Create project directory if it doesn't exist\n- Clone repository on first deployment\n- Pull latest code changes on subsequent deployments\n- Build Docker image on the VPS\n- Deploy using Docker Compose with production profile\n- Verify deployment success and show container status\n\n### Monitoring\n\n```bash\n# View logs\ndocker compose logs -f\n\n# Check container status\ndocker compose ps\n\n# Restart the bot\ndocker compose restart moderation-tool-bot\n\n# Stop the bot\ndocker compose down\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Run tests and linting\n5. Submit a pull request\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr-webdev%2Fmoderation-tool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fr-webdev%2Fmoderation-tool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr-webdev%2Fmoderation-tool/lists"}