Developing an OpenClaw Discord Emoji Skill - Implementing a User Approval Workflow
My experience developing a skill for an OpenClaw AI agent that detects Discord emoji reactions to capture user decisions, and uploading it to GitHub. I also share the problems I ran into during ClawdHub deployment and how I solved them.
This post was machine-translated from Korean by AI. Some expressions may differ from the original.
Read the original (Korean)Introduction
When you use AI agents, there comes a moment when you wonder, "Should I really let this run?" This is especially true for irreversible actions like posting tweets, sending emails, or deleting files.
So I built one: a skill that gets user approval through Discord emoji reactions.
๐ธ An example message in Discord with the 1๏ธโฃ 2๏ธโฃ 3๏ธโฃ ๐ฅ โ emojis attached
Defining the Problem
I was building an automated crypto-market Twitter bot called "AlphaHunter" with OpenClaw. The AI collecting news and generating candidate tweets was fine, but the problem was that it must not post directly without approval.
Limitations of the existing approach:
- Using โ /โ emojis, they got cut off and weren't visible in Discord
- Hard to choose among multiple candidates
- Cases occurred where posts went out without approval
Solution: A Number-Emoji Approval System
Design Principles

Implementation Code (approval_workflow.py)
class ApprovalManager:
"""์น์ธ ์ํฌํ๋ก์ฐ ๊ด๋ฆฌ์"""
EMOJI_MAP = {
'1๏ธโฃ': 0,
'2๏ธโฃ': 1,
'3๏ธโฃ': 2,
'๐ฅ': 'all',
'โ': 'reject'
}
def __init__(self):
self.pending = {} # message_id -> candidates
self.approved = [] # ์น์ธ๋ ํ๋ณด ํ
def submit_candidates(self, candidates: list, message_id: str):
"""ํ๋ณด ์ ์ถ ๋ฐ ์ด๋ชจ์ง ๋ฌ๊ธฐ"""
self.pending[message_id] = {
'candidates': candidates,
'submitted_at': datetime.now(),
'expires_at': datetime.now() + timedelta(hours=24)
}
return self.EMOJI_MAP.keys() # ๋ฌ์์ผ ํ ์ด๋ชจ์ง ๋ชฉ๋ก
def process_reaction(self, message_id: str, emoji: str):
"""์ด๋ชจ์ง ๋ฐ์ ์ฒ๋ฆฌ"""
if message_id not in self.pending:
return None
action = self.EMOJI_MAP.get(emoji)
candidates = self.pending[message_id]['candidates']
if action == 'all':
self.approved.extend(candidates)
elif action == 'reject':
del self.pending[message_id]
elif isinstance(action, int) and action < len(candidates):
self.approved.append(candidates[action])
return self.approvedDiscord Integration
Attach the emojis with OpenClaw's message tool:
# ํ๋ณด ์ ์ก ํ ์ด๋ชจ์ง ๋ฌ๊ธฐ
message_id = send_candidates_to_discord(candidates)
for emoji in ['1๏ธโฃ', '2๏ธโฃ', '3๏ธโฃ', '๐ฅ', 'โ']:
message(
action='react',
channel='discord',
messageId=message_id,
emoji=emoji
)Uploading to GitHub
Once skill development is complete, you need to upload it to GitHub. An OpenClaw skill follows this structure:
skills/
โโโ discord-emoji-approval/
โโโ SKILL.md # ์คํฌ ๋ฌธ์
โโโ scripts/
โ โโโ approval_workflow.py
โโโ config.json # ์ค์ Writing SKILL.md
# Discord Emoji Approval Skill
๋์ค์ฝ๋ ์ด๋ชจ์ง ๋ฐ์์ผ๋ก ์ฌ์ฉ์ ์น์ธ์ ๋ฐ๋ ์คํฌ.
## ์ฌ์ฉ๋ฒ
1. ํ๋ณด๋ฅผ ๋์ค์ฝ๋๋ก ์ ์ก
2. ์ด๋ชจ์ง 5๊ฐ ๋ฌ๊ธฐ (1๏ธโฃ 2๏ธโฃ 3๏ธโฃ ๐ฅ โ)
3. ์ฌ์ฉ์๊ฐ ์ด๋ชจ์ง ํด๋ฆญ
4. ์น์ธ๋ ํ๋ณด๋ง ์คํ
## ์์กด์ฑ
- OpenClaw message ๋๊ตฌ (react ์ก์
)Git Commit & Push
cd ~/.openclaw/workspace/skills/discord-emoji-approval
git add .
git commit -m "feat: ๋์ค์ฝ๋ ์ด๋ชจ์ง ์น์ธ ์คํฌ ์ถ๊ฐ"
git push origin mainAttempting ClawdHub Deployment (Failed)
ClawdHub is the OpenClaw skill marketplace. You can share the skills you've built.
The Deployment Attempt
clawdhub publish ./skills/discord-emoji-approvalThe Error That Occurred
Error: Unable to connect to clawdhub.com
Status: 503 Service UnavailableThe service was temporarily unstable. I decided to try again later.
Alternative: Installing Directly from GitHub
If ClawdHub doesn't work, you can install directly from a GitHub URL:
# ๋ค๋ฅธ ์ฌ๋์ด ์ค์นํ ๋
git clone https://github.com/arang/openclaw-skills.git
cp -r openclaw-skills/discord-emoji-approval ~/.openclaw/workspace/skills/Lessons Learned
1. User Approval Is Essential
No matter how smart the AI is, a human needs to confirm irreversible actions.
2. Emojis Are Intuitive
A 1๏ธโฃ emoji is much faster than the text "Choose option 1."
3. A Queuing System Is Needed
If you select several at once and run them simultaneously, you hit the rate limit. Sequential execution is safer.
4. Offline Fallback
In case an external service like ClawdHub is down, document the direct GitHub installation method too.
Wrapping Up
Thanks to this skill, the AlphaHunter bot went from being a "dangerous bot that tweets on its own" to a "safe bot that tweets only when a human approves."
Next time, I'll share my experience of actually using this approval system to build a self-improving AI agent.
Related Links:
Comments