Discord bot for sending 7TV emotes. Static emotes → PNG, animated emotes → GIF.
- Fetch emotes from 7TV with autocomplete
- Automatic format detection (PNG/GIF)
- User preferences (size, channels, emote sets)
- Sorts by popularity
- TypeScript
Commands:
/emote <name>- Send an emote (has autocomplete)/channel <channel>- Set default 7TV channel/emote-set <set>- Pick a specific emote set/image-size <size>- Choose size (1x, 2x, 3x, 4x)/reset- Reset all your preferences
Examples:
/emote xdd
/emote Clueless
/emote OMEGALUL
Just start typing and autocomplete will show suggestions.
- TypeScript
- Discord.js v14
- Supabase
- 7TV API v4
- Axios
Requirements:
- Node.js v18+
- Discord Developer account
- Supabase account (for storing user preferences)
git clone https://github.com/atmahana/7emotes
cd 7emotes
npm install- Discord Developer Portal → New Application
- Name it "7Emotes" (or whatever you prefer)
- Bot tab → Add Bot → Copy token and application ID
- OAuth2 → URL Generator → Select
bot+applications.commandsscopes - Permissions: Send Messages, Embed Links, Attach Files, Use Slash Commands
See SUPABASE_SETUP.md for detailed instructions on setting up the database.
The project uses two env files:
.env.local- for development (gitignored).env- for production
For development, create .env.local:
cp .env.example .env.localThen edit it with your dev bot credentials:
DISCORD_TOKEN=your_DEV_bot_token
CLIENT_ID=your_DEV_bot_client_id
GUILD_ID=your_test_server_id
SUPABASE_URL=your_supabase_url
SUPABASE_ANON_KEY=your_supabase_keyFor production, create .env with your production bot credentials. Same format, just different tokens.
Note: .env.local takes priority if both files exist.
Development:
npm run dev:deploy # Deploy commands to test server
npm run dev # Run the botProduction:
npm run build # Compile TypeScript
npm run deploy # Deploy commands
npm start # Run the botOther commands:
npm run watch- Auto-recompile on file changesnpm run start:prod- Run without rebuilding
Wrong bot starting (prod instead of dev):
- Use
npm run devnotnpm start - Make sure
.env.localexists with dev credentials - Check console - should say "Loaded environment from .env.local"
Environment not loading:
- Files must be named
.env.localor.envexactly (with the dot) - Must be in project root, not
src/ - Check for typos in variable names
Commands not showing up:
- Wait a few minutes (global commands can take up to an hour)
- Try restarting Discord
- Make sure bot has proper permissions
Emote not found:
- Use autocomplete suggestions
- Check if it exists on 7TV
7emotes/
├── src/
│ ├── commands/
│ │ ├── <command>/ # Each bot command follows this structure
│ │ │ ├── handler.ts # Discord command handler & autocomplete
│ │ │ ├── service.ts # 7TV API integration for this command (optional)
│ │ │ ├── query.ts # GraphQL queries specific to this command (optional)
│ ├── types/ # TypeScript types
│ ├── config/
│ │ └── env.ts # Environment loader (.env.local/.env)
│ ├── utils/
│ │ └── seventv.ts # 7TV API constants
│ ├── storage.ts # Supabase database client
│ ├── index.ts # Bot entry point
│ └── deploy-commands.ts # Command registration script
├── dist/ # Compiled JavaScript output
├── .env / .env.local # Environment variables (gitignored)
└── package.json
User Preferences:
- Supabase database stores per-user settings (channel, emote set, image size)
- Preferences persist across sessions
Emote Fetching:
- Bot searches 7TV's GraphQL API v4
- Results are sorted by popularity (TOP_ALL_TIME)
- User's selected channel/emote set filters results
- Caches recent searches for faster autocomplete
- Automatically detects format (PNG/GIF) based on animation
- Sends emote at user's preferred size (1x-4x)
Don't share your bot tokens or commit .env.local to git. It's already in .gitignore.
Priority: .env.local > .env
npm run dev→ loads.env.local→ dev botnpm start→ loads.env(or.env.localif no.env) → prod bot
PRs welcome. Just:
- Create
.env.localfor dev - Use
npm run dev - Test your changes
- Make sure it builds (
npm run build) - Submit PR
Emotes from 7TV • Built with Discord.js