Channels
Claw Onichan
OpenClaw plugin: detect emotion keywords in agent replies and attach mapped images via Discord API
Configuration Example
{
"plugins": {
"entries": {
"emotion-image": {
"enabled": true
}
}
}
}
README
# ๐ฆ claw-onichan
> Auto-attach emotion images to your OpenClaw agent's Discord messages.
Your agent sends a message โ the plugin detects the mood from keywords โ edits the message to attach a matching image. No core patches needed โ pure OpenClaw Plugin SDK.
```
Agent sends: "Task completed! All tests passed โ
"
โ Plugin detects: happy
โ Discord message gets: happy.png attached
```
## How It Works
1. Hooks into `message_sent` โ fires after every outbound Discord message
2. Scans the text for emotion keywords (regex pattern matching)
3. Calls Discord REST API (`PATCH`) to edit the message with an image attachment
The agent doesn't need to know about images at all. The plugin handles everything post-delivery.
---
## For AI Agents Setting This Up
> **If you're an AI agent installing this plugin for a user, here's what you need from them before proceeding.**
### What the user must provide
1. **Emotion images** โ This plugin ships with NO images. Ask the user to:
- Provide image files (PNG recommended, 256โ512px, under 512KB each)
- One image per emotion: `happy.png`, `neutral.png`, `sorry.png`, `confused.png`, `focused.png`, `loyalty.png`
- Or tell you what style/character they want, and generate the images for them using an image generation tool
2. **Discord bot token** โ The plugin calls the Discord REST API directly. The user must either:
- Give you a bot token to set as `EMOTION_IMAGE_DISCORD_TOKEN` env var
- Or confirm they already have a Discord account configured in `openclaw.json` (the plugin auto-detects the first available token)
3. **Which emotions to support** โ The built-in set is `happy`, `neutral`, `sorry`, `confused`, `focused`, `loyalty`. Ask if they want to:
- Add custom emotions (e.g., `sleepy`, `angry`, `excited`)
- Modify the trigger keywords for existing emotions
- Change the default/fallback emotion
### What you can do without asking
- Clone the repo to `extensions/emotion-image`
- Register the plugin in `openclaw.json` โ `plugins.entries.emotion-image`
- Set up the directory structure
- Configure `emotionMap` and `emotionRules` based on provided images/preferences
- Restart the gateway after setup
### Setup checklist
```
โก Plugin cloned to extensions/emotion-image
โก Registered in openclaw.json plugins.entries
โก Image files placed in assets/ directory (USER MUST PROVIDE)
โก Discord bot token configured (USER MUST CONFIRM)
โก Gateway restarted
โก Test: send a message and verify image attachment in logs
```
---
## Quick Start
### 1. Install
```bash
cd /path/to/openclaw
git clone https://github.com/IYENTeam/claw-onichan.git extensions/emotion-image
```
### 2. Register in config
Add to your `openclaw.json`:
```jsonc
{
"plugins": {
"entries": {
"emotion-image": {
"enabled": true
}
}
}
}
```
### 3. Prepare your images โ ๏ธ
**This plugin does NOT include any images.** You must create or source them yourself.
Place image files in the `assets/` directory:
```
extensions/emotion-image/assets/
โโโ happy.png
โโโ neutral.png
โโโ sorry.png
โโโ confused.png
โโโ focused.png
โโโ loyalty.png
```
#### Default emotion โ filename mapping
| Emotion | File | Triggers on |
|---------|------|-------------|
| `happy` | `happy.png` | ์๋ฃ, success, done, โ
, ๐ |
| `neutral` | `neutral.png` | *(fallback when nothing else matches)* |
| `sorry` | `sorry.png` | ์ฃ์ก, sorry, ์ค์, apolog |
| `confused` | `confused.png` | ๋ชจ๋ฅด, confused, ์ง๋ฌธ |
| `focused` | `focused.png` | ๋ถ์, ์์
, ๋๋ฒ๊ทธ, ์ฝ๋, ํ
์คํธ |
| `loyalty` | `loyalty.png` | ์๋
, ์๊ฒ , ์ถฉ์ฑ |
#### Creating images
**Option A โ AI image generation**
Use any image generator with prompts like:
| Emotion | Example prompt |
|---------|---------------|
| happy | *"Cute 2D character smiling warmly, simple flat style, transparent background, 512x512"* |
| sorry | *"Cute 2D character looking apologetic with sweat drop, soft pastel, transparent background, 512x512"* |
| confused | *"Cute 2D character with question mark above head, purple tones, transparent background, 512x512"* |
| focused | *"Cute 2D character with determined eyes and glasses, cool blue, transparent background, 512x512"* |
**Option B โ Open source icons**
- [OpenMoji](https://openmoji.org/) โ open source emoji
- [Twemoji](https://github.com/twitter/twemoji) โ Twitter's emoji set
- [Flaticon](https://www.flaticon.com/) โ free icons (check license)
**Recommended specs:**
- Format: PNG (transparent background supported)
- Size: 256ร256 to 512ร512 px
- Aspect ratio: 1:1
- File size: under 512KB
### 4. Set Discord bot token
The plugin needs a Discord bot token to call the edit API.
**Option A โ Environment variable (recommended)**
```bash
export EMOTION_IMAGE_DISCORD_TOKEN="your-bot-token"
```
**Option B โ Auto-detect from OpenClaw config**
If your `openclaw.json` has a Discord account configured, the plugin will automatically use the first available bot token:
```jsonc
{
"channels": {
"discord": {
"accounts": {
"my-bot": {
"token": "your-bot-token"
}
}
}
}
}
```
### 5. Restart OpenClaw
```bash
openclaw gateway restart
```
That's it. Your agent's messages will now get emotion images automatically.
---
## Configuration
All options go in `plugins.entries.emotion-image.config`:
```jsonc
{
"plugins": {
"entries": {
"emotion-image": {
"enabled": true,
"config": {
"imageDir": "./my-custom-images",
"defaultEmotion": "neutral",
"emotionMap": {
"happy": "my-happy.webp"
},
"emotionRules": {
"excited": ["awesome", "amazing", "incredible"]
}
}
}
}
}
}
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `enabled` | boolean | `true` | Kill switch |
| `imageDir` | string | `assets/` | Directory containing emotion images |
| `defaultEmotion` | string | `"neutral"` | Fallback when no keywords match |
| `emotionMap` | object | built-in | Emotion name โ image filename override |
| `emotionRules` | object | built-in | Emotion name โ keyword patterns to add |
### Adding custom emotions
1. Add keywords in `emotionRules`:
```jsonc
{ "emotionRules": { "sleepy": ["tired", "์กธ๋ ค", "zzz"] } }
```
2. Map to an image file in `emotionMap`:
```jsonc
{ "emotionMap": { "sleepy": "sleepy.png" } }
```
3. Place `sleepy.png` in your `imageDir`.
---
## Built-in Emotion Rules
| Emotion | Keywords |
|---------|----------|
| sorry | ์ฃ์ก, ๋ฏธ์, ์ค์, ์๋ชป, sorry, apolog |
| happy | ์๋ฃ, ์ฑ๊ณต, ๋์ต๋๋ค, ํด๊ฒฐ, pass, done, โ
, ๐, ์ถํ |
| confused | ๋ชจ๋ฅด, ์ด์ํ, ์์ธ๋ถ๋ช
, confused, unclear, ์ง๋ฌธ |
| focused | ์กฐ์ฌ, ๋ถ์, ๋๋ฒ๊ทธ, ์์
, ์์ , ์ฝ๋, ๋น๋, ๋ฐฐํฌ, ํ
์คํธ |
| loyalty | ํ์ฅ๋, ์ถฉ์ฑ, ์๊ฒ , ์๋
, ใ
ใ
|
Rules are evaluated top-to-bottom. First match wins.
---
## Troubleshooting
**Hook never fires**
- Make sure the plugin uses `api.on("message_sent", ...)` โ NOT `api.registerHook(...)`. These are different systems in OpenClaw. `registerHook` is for legacy/HTTP hooks and won't be called by the delivery pipeline.
**Discord edit fails (no image appears)**
- Check your bot token is valid
- The bot can only edit its own messages
- Look for `emotion-image: Discord edit failed` in gateway logs
- Check for Discord API rate limits (429 status)
**"Discord token not found" warning**
- Set `EMOTION_IMAGE_DISCORD_TOKEN` env var, or ensure your `openclaw.json` has a Discord account with a token
**Image not found**
- Verify image files exist in your `imageDir`
- Filenames must match `emotionMap` values exactly
---
## Development
```bash
# Run tests (from OpenClaw root)
npx vitest run extensions/emotion-image/index.test.ts
# 27 tests covering:
# - detectEmotion() keyword matching
# - MEDIA line cleanup
# - channel: prefix stripping
# - buildEmotionRules() config merging
# - editMessageWithImage() Discord API calls
# - Plugin entry shape validation
```
---
## License
MIT
channels
Comments
Sign in to leave a comment