A feature-rich Discord bot built with TypeScript, Discord.js v14, and Bun runtime. Designed for translation, role management, and server moderation.
| Feature | Description |
|---|---|
| ๐ Translation | Translate text via slash commands or context menu |
| ๐ญ Self-Roles | Interactive role selection panel for members |
| ๐ฃ๏ธ Language Roles | Set target translation language via role buttons |
| ๐ URL Moderation | Automatic URL detection and removal |
| ๐ผ๏ธ Avatar Fetcher | Retrieve any user's profile picture by ID |
Parrot-bot/
โโโ src/
โ โโโ commands/
โ โ โโโ context/ # Context menu commands
โ โ โ โโโ translate.ts
โ โ โโโ slash/ # Slash commands
โ โ โโโ langpanel.ts
โ โ โโโ ping.ts
โ โ โโโ selfroles.ts
โ โ โโโ translate.ts
โ โ โโโ userpfp.ts
โ โโโ config/
โ โ โโโ env.ts # Environment configuration
โ โโโ constants/
โ โ โโโ languages.ts # Language codes & mappings
โ โ โโโ roles.ts # Role configuration
โ โโโ embeds/
โ โ โโโ translateEmbed.ts # Translation result embed
โ โโโ events/
โ โ โโโ interactionCreate.ts
โ โ โโโ messageCreate.ts
โ โโโ handlers/
โ โ โโโ langButtonHandler.ts
โ โ โโโ selfRolesHandler.ts
โ โโโ services/
โ โ โโโ translateService.ts
โ โโโ types/
โ โ โโโ discord.d.ts # Discord.js type extensions
โ โ โโโ index.ts # Shared type definitions
โ โโโ utils/
โ โ โโโ arrays.ts
โ โ โโโ strings.ts
โ โโโ main.ts # Bot entry point
โ โโโ register.ts # Command registration
โโโ .env # Environment variables (not committed)
โโโ .gitignore
โโโ package.json
โโโ tsconfig.json
โโโ README.md
- Bun v1.0 or higher
- Discord Bot Token (Create one here)
- Node.js 18+ (for Discord.js compatibility)
1. Clone the repository
git clone https://github.com/your-username/parrot-bot.git
cd parrot-bot2. Install dependencies
bun install3. Configure environment variables
Create a .env file in the project root:
TOKEN=your_discord_bot_token
CLIENT_ID=your_application_client_id
GUILD_ID=your_development_server_id # Optional: for guild-specific commands4. Register commands
bun run register5. Start the bot
bun run startRun with hot reload:
bun run dev| Command | Description | Permission |
|---|---|---|
/ping |
Check bot latency | Everyone |
/translate |
Translate text to a specified language | Everyone |
/stealpfp |
Get a user's profile picture by ID | Everyone |
/langpanel |
Post language role selection panel | Administrator |
/selfroles |
Post self-role selection panel | Administrator |
| Command | Type | Description |
|---|---|---|
Translate (Target Role) |
Message | Translate selected message based on your language role |
Slash Command:
/translate msg:Hello, how are you? langcode:ja
Context Menu:
- Right-click any message
- Navigate to Apps โ Translate (Target Role)
- Translation uses your assigned language role (defaults to English)
Administrators can create a language selection panel:
/langpanel
Users click buttons to set their target translation language. Only one language role is active at a time.
Supported Languages:
- ๐ฌ๐ง English (en)
- ๐น๐ญ Thai (th)
- ๐ฏ๐ต Japanese (ja)
- ๐ต๐ญ Filipino (fil)
- ๐ฎ๐ฉ Indonesian (id)
- ๐ช๐ฌ Arabic - Egyptian (ar-eg)
- ๐ฌ๐ญ Akan (ak)
- ๐ฌ๐ญ Ewe (ee)
- ๐ฌ๐ญ Ga (gaa)
- ๐ฌ๐ญ Dagbani (dag)
Administrators can create a role selection panel:
/selfroles
- Users select roles from the dropdown menu
- Press Submit to apply selected roles
- Press Reset to clear selection
- Developer role is auto-assigned when submitting
Create a new file in src/commands/slash/:
import { SlashCommandBuilder } from "discord.js";
import type { Command } from "../../types";
export const command: Command = {
data: new SlashCommandBuilder()
.setName("example")
.setDescription("An example command"),
async execute(interaction) {
await interaction.reply("Hello from example command!");
},
};Create a new file in src/commands/context/:
import {
ApplicationCommandType,
ContextMenuCommandBuilder,
MessageFlags,
} from "discord.js";
import type { MessageContextMenuCommandInteraction } from "discord.js";
import type { Command } from "../../types";
export const command: Command<MessageContextMenuCommandInteraction> = {
data: new ContextMenuCommandBuilder()
.setName("Example Action")
.setType(ApplicationCommandType.Message),
async execute(interaction) {
const message = interaction.targetMessage;
await interaction.reply({
content: `Message content: ${message.content}`,
flags: MessageFlags.Ephemeral,
});
},
};Register the new commands with Discord:
bun run registerThen restart the bot:
bun run start| Script | Description |
|---|---|
bun run start |
Start the bot |
bun run dev |
Start with hot reload |
bun run register |
Register commands to Discord |
bun run test |
Run tests with Vitest |
bun run lint |
Type-check with TypeScript |
| Variable | Required | Description |
|---|---|---|
TOKEN |
โ | Discord bot token |
CLIENT_ID |
โ | Discord application ID |
GUILD_ID |
โ | Guild ID for dev commands (instant updates) |
Edit src/constants/roles.ts to customize:
EXCLUDED_ROLE_NAMES- Roles excluded from self-role selectionDEVELOPER_ROLE_NAME- Auto-assigned developer role name
Edit src/constants/languages.ts to:
- Add/remove supported languages in
LANG_CODES - Map language codes to Google Translate codes in
TRANSLATE_TARGET
- Ensure
bun run registercompleted successfully - Check bot has
applications.commandsscope - Wait up to 1 hour for global commands (instant for guild commands)
Ensure the bot role has:
Manage Roles- For role assignment featuresSend Messages- For responding to commandsManage Messages- For URL moderation
- Google Translate API may rate-limit frequent requests
- Check network connectivity
- Verify the language code is valid
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m "Add: amazing feature") - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Discord.js - Discord API wrapper
- Bun - JavaScript runtime
- Google Translate - Translation service

