Vicuna Bot#
A Zulip bot for user registration and management. Vicuna helps users register their email addresses and Zulip IDs, creating a persistent directory for easy @mentions and user tracking.
Features#
- User Registration: Users can register themselves by sending a simple command
- Custom Email Support: Register with your actual email address (not just the auto-generated Zulip email)
- Persistent Storage: All registrations are stored on the server using Zulip's bot storage API
- Bidirectional Lookup: Look up users by email address or Zulip ID
- Message-based Configuration: All configuration happens via messages to the bot
- User Directory: List all registered users
OAuth/SSO Email Issue & Solution#
Problem: Many Zulip instances that use OAuth, SSO, or other authentication methods assign auto-generated emails to users like user123@zulipchat.com instead of their actual email addresses.
Smart Solution: Vicuna automatically tries to find your real email address!
When you type register, the bot uses this priority:
- Custom email you provide:
register alice@company.com(highest priority) - delivery_email from your Zulip profile (the real email associated with your account)
- user.email from your Zulip profile API (may differ from message sender email)
- Zulip message email as a last resort (the internal
user@zulipchat.comstyle)
This means most users can just type register and the bot will automatically use their real email address!
Manual Email Registration#
If needed, you can still manually specify your email:
register your-actual-email@example.com
The bot will:
- Store your actual email for lookups
- Still track your Zulip ID for @mentions
- Show you both your registered email and your Zulip-internal email
This way, colleagues can find you by your real email address while the bot maintains the proper Zulip ID mapping.
Installation#
# Build the bot
cd vicuna
dune build
# Install (optional)
dune install
Configuration#
Create a ~/.zuliprc file with your bot credentials:
[api]
email=vicuna-bot@your-domain.zulipchat.com
key=your-bot-api-key
site=https://your-domain.zulipchat.com
Usage#
Running the Bot#
# Run with default configuration
vicuna
# Run with verbose logging
vicuna -v
# Run with debug logging
vicuna -vv
# Run with custom config file
vicuna -c /path/to/.zuliprc
Bot Commands#
Send these commands to the bot via direct message or by mentioning it in a channel:
register or register <your-email@example.com>#
Register your email and Zulip ID in the system.
Smart auto-detection (recommended - just type register):
> register
✅ Successfully registered!
• Email: `alice@mycompany.com`
• Zulip ID: `12345`
• Full Name: `Alice Smith`
💡 Your Zulip email is: `user123@zulipchat.com`
📧 Using your delivery email from your profile
You can now be @mentioned by your email or Zulip ID!
The bot automatically fetched alice@mycompany.com from your Zulip profile's delivery_email field!
Manual registration (if you want to override):
> register alice@different-email.com
✅ Successfully registered!
• Email: `alice@different-email.com`
• Zulip ID: `12345`
• Full Name: `Alice Smith`
💡 Your Zulip email is: `user123@zulipchat.com`
📝 Using the custom email you provided
You can now be @mentioned by your email or Zulip ID!
Note: The bot tries four sources in order:
- Custom email you provide (highest priority)
delivery_emailfrom your Zulip profile (auto-detected)user.emailfrom your Zulip profile API (may be real email depending on permissions)- Zulip message sender email (fallback)
whoami#
Check your registration status.
> whoami
📋 Your registration info:
• Email: `alice@example.com`
• Zulip ID: `12345`
• Full Name: `Alice Smith`
• Registered: 2025-01-15 10:30:45
whois <email|id>#
Look up a registered user by their email or Zulip ID.
> whois bob@example.com
👤 User found:
• Email: `bob@example.com`
• Zulip ID: `67890`
• Full Name: `Bob Jones`
• Registered: 2025-01-14 09:15:22
> whois 67890
👤 User found:
• Email: `bob@example.com`
• Zulip ID: `67890`
• Full Name: `Bob Jones`
• Registered: 2025-01-14 09:15:22
list#
List all registered users.
> list
📋 Registered users (3):
• **Alice Smith** (`alice@example.com`) - ID: 12345
• **Bob Jones** (`bob@example.com`) - ID: 67890
• **Carol White** (`carol@example.com`) - ID: 54321
help#
Show available commands and usage information.
> help
👋 Hi Alice! I'm **Vicuna**, your user registration assistant.
Available Commands:
• `register` - Register with your Zulip email
• `register <your-email@example.com>` - Register with a custom email
• `whoami` - Show your registration status
• `whois <email|id>` - Look up a registered user
• `list` - List all registered users
• `help` - Show this help message
Examples:
• `register` - Register with Zulip email (`user123@zulipchat.com`)
• `register alice@mycompany.com` - Register with your actual email
• `whois alice@example.com` - Look up Alice by email
• `whois 12345` - Look up user by Zulip ID
Note: Many Zulip instances use auto-generated emails like `user@zulipchat.com`.
You can provide your actual email address during registration!
Send me a direct message to get started!
Architecture#
Libraries Used#
- zulip: OCaml bindings for the Zulip REST API
- zulip_bot: Bot framework for building interactive Zulip bots
- eio: Effects-based I/O for async operations
- logs: Structured logging
- cmdliner: Command-line interface
Storage#
Vicuna uses Zulip's bot storage API to persist user registrations. The storage format is:
- User by email:
user:email:<email>→<email>|<zulip_id>|<full_name>|<timestamp> - User by ID:
user:id:<zulip_id>→<email>|<zulip_id>|<full_name>|<timestamp> - User list:
users:all→<email1>,<email2>,<email3>,...
This allows for efficient bidirectional lookups and maintains a master list of all registered users.
Development#
Project Structure#
vicuna/
├── dune-project # Project definition
├── README.md # This file
├── lib/ # Bot library
│ ├── dune # Library build config
│ ├── vicuna_bot.ml # Bot implementation
│ └── vicuna_bot.mli # Bot interface
└── bin/ # Executable
├── dune # Executable build config
└── main.ml # Main entry point
Building#
# Build the project
dune build
# Build with verbose output
dune build --verbose
# Clean build artifacts
dune clean
Testing#
You can test the bot by running it and sending messages to it in your Zulip instance:
- Create a bot account in your Zulip instance
- Download the bot's
.zuliprcfile - Run
vicuna -c path/to/.zuliprc -vv - Send a direct message to the bot with
help
License#
This project is part of the knot/slop/stack collection.
Dependencies#
- OCaml 4.08+
- Dune 3.0+
- eio
- zulip (from ../zulip)
- zulip_bot (from ../zulip)
- logs
- cmdliner
- mirage-crypto-rng-unix