Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Resolves multi-channel user IDs to a single canonical ID, preventing fragmented state across Telegram, WhatsApp, Discord, web, and more.
Resolves multi-channel user IDs to a single canonical ID, preventing fragmented state across Telegram, WhatsApp, Discord, web, and more.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
Canonical user identity resolution across messaging channels
Resolves multi-channel user identities (Telegram, WhatsApp, Discord, web, etc.) to canonical user IDs, preventing state fragmentation when users interact via multiple channels. Problem it solves: Without identity resolution, a user messaging via Telegram and WhatsApp appears as two different users, causing fragmented memory, access control, and per-user state across skills. Solution: Maps all channel identities to one canonical user ID automatically.
Prerequisites: Install uv if not already installed: curl -LsSf https://astral.sh/uv/install.sh | sh Install the skill: cd /path/to/openclaw/workspace # Via ClawHub (recommended) clawhub install identity-resolver # Or via Git git clone https://github.com/clawinfra/identity-resolver skills/identity-resolver
# Initialize identity map (auto-detects owner from USER.md) cd /path/to/workspace uv run python skills/identity-resolver/scripts/identity_cli.py init # Verify your identity uv run python skills/identity-resolver/scripts/identity_cli.py resolve \ --channel telegram --user-id YOUR_TELEGRAM_ID # Output: your-canonical-id # List all registered identities uv run python skills/identity-resolver/scripts/identity_cli.py list
Add to your skill's Python code: import sys from pathlib import Path # Import identity resolver sys.path.insert(0, str(Path.cwd() / "skills" / "identity-resolver" / "scripts")) from identity import resolve_canonical_id # Get canonical user ID from session context import os channel = os.getenv("OPENCLAW_CHANNEL") # e.g., "telegram" user_id = os.getenv("OPENCLAW_USER_ID") # e.g., "123456789" canonical_id = resolve_canonical_id(channel, user_id) # Use canonical_id for all user-specific operations # Example: User-specific memory file memory_file = f"data/users/{canonical_id}/memory.json"
✅ Auto-registers owner from workspace USER.md ✅ Thread-safe identity map storage with fcntl locking ✅ CLI + Python API for both users and developers ✅ Path traversal protection — sanitizes all canonical IDs ✅ Zero dependencies — pure Python stdlib ✅ Multi-channel support — Telegram, WhatsApp, Discord, web, and future channels
# tiered-memory skill integration canonical_id = resolve_canonical_id(channel, user_id) memory_tree = f"memory/users/{canonical_id}/tree.json"
# agent-access-control skill integration canonical_id = resolve_canonical_id(channel, user_id) if is_owner(canonical_id): # Full access else: # Limited access
# Same user across Discord + Telegram discord_id = resolve_canonical_id("discord", "user#1234") telegram_id = resolve_canonical_id("telegram", "987654321") # Both resolve to same canonical ID if registered
resolve_canonical_id(channel, provider_user_id, workspace=None, owner_numbers=None) -> str Resolve channel identity to canonical user ID. Auto-registers owner numbers from USER.md Returns canonical ID (e.g., "alice") or "stranger:{channel}:{user_id}" for unmapped users add_channel(canonical_id, channel, provider_user_id, workspace=None, display_name=None) Add channel mapping to a canonical user (creates user if doesn't exist). remove_channel(canonical_id, channel, provider_user_id, workspace=None) Remove channel mapping from canonical user. list_identities(workspace=None) -> dict Return all identity mappings. get_channels(canonical_id, workspace=None) -> list Get all channels for a canonical user. is_owner(canonical_id, workspace=None) -> bool Check if canonical ID is the owner.
# Initialize identity init [--force] # Resolve (auto-detect from env or explicit params) identity resolve [--channel CH] [--user-id ID] # Add mapping identity add --canonical ID --channel CH --user-id ID [--display-name NAME] # Remove mapping identity remove --canonical ID --channel CH --user-id ID # List all identity list [--json] # Get channels identity channels --canonical ID [--json] # Check owner identity is-owner --canonical ID [--json]
Location: data/identity-map.json or memory/identity-map.json { "version": "1.0", "identities": { { "version": "1.0", "identities": { "alice": { "canonical_id": "alice", "is_owner": true, "display_name": "Alice Johnson", "channels": [ "telegram:123456789", "whatsapp:+1234567890", "whatsapp:+9876543210", "whatsapp:+5555555555" ], "created_at": "2026-01-15T10:00:00Z", "updated_at": "2026-01-15T10:05:00Z" }, "bob": { "canonical_id": "bob", "is_owner": false, "display_name": "Bob Smith", "channels": [ "discord:bob#1234", "telegram:987654321" ], "created_at": "2026-01-15T10:10:00Z", "updated_at": "2026-01-15T10:10:00Z" } } } } } }
Path traversal protection: Canonical IDs sanitized to [a-z0-9-_] only Thread-safe operations: fcntl file locking on all reads/writes Input validation: All user inputs validated and sanitized Owner auto-registration: Only numbers from USER.md auto-register as owner
See docs/TIERED_MEMORY_INTEGRATION_EXAMPLE.md for complete working example.
MIT - See LICENSE file
OpenClaw Agent agent@openclaw.local
GitHub: https://github.com/clawinfra/identity-resolver Issues: https://github.com/clawinfra/identity-resolver/issues ClawHub: https://clawhub.com/skills/identity-resolver
Messaging, meetings, inboxes, CRM, and teammate communication surfaces.
Largest current source with strong distribution and engagement signals.