+32
stack/vicuna/.gitignore
+32
stack/vicuna/.gitignore
···
···
+14
stack/vicuna/.zuliprc.example
+14
stack/vicuna/.zuliprc.example
···
···
+265
stack/vicuna/README.md
+265
stack/vicuna/README.md
···
···+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.+- **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+**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.+This means **most users can just type `register`** and the bot will automatically use their real email address!+This way, colleagues can find you by your real email address while the bot maintains the proper Zulip ID mapping.+The bot automatically fetched `alice@mycompany.com` from your Zulip profile's `delivery_email` field!+This allows for efficient bidirectional lookups and maintains a master list of all registered users.
+170
stack/vicuna/USAGE.md
+170
stack/vicuna/USAGE.md
···
···+When you authenticate to Zulip using OAuth, SSO, or other third-party authentication methods, Zulip often assigns you an auto-generated email address like:+**Good news!** Vicuna now automatically detects your real email address from your Zulip profile!+2. Your `user.email` from Zulip profile API (may be your real email depending on server config)+1. **Just type `register`** - In most cases, the bot will automatically find your real email from your profile!+3. **Manual override if needed** - If the auto-detection didn't work, use `register your-email@example.com`+4. **Encourage your team to register** - The more people registered, the more useful the directory+6. **The bot stores both emails** - It knows your registered email AND your Zulip internal email+2. **delivery_email** (from Zulip profile API): Your real email address associated with the account+3. **user.email** (from Zulip profile API): Email from profile (if different from message sender)+- **delivery_email**: The most reliable source for real email, but may be `null` depending on permissions+- **user.email**: Another source from the API that may contain the real email depending on server configuration
+14
stack/vicuna/bin/dune
+14
stack/vicuna/bin/dune
+467
stack/vicuna/bin/main.ml
+467
stack/vicuna/bin/main.ml
···
···+| Some (user : Vicuna_bot.user_registration) when (not show_admins_only) || user.is_admin -> Some user+Cmd.v info Term.(const cli_add_user $ config_file $ user_id_arg $ email_arg $ full_name_arg $ admin_flag $ const eio_env)+Cmd.v info Term.(const cli_set_admin $ config_file $ user_id_arg $ const true $ const eio_env)+Cmd.v info Term.(const cli_set_admin $ config_file $ user_id_arg $ const false $ const eio_env)+let default_info = Cmd.info "vicuna" ~version:"1.0.0" ~doc:"Vicuna - User Registration and Management Bot for Zulip" in+let default_term = Term.(const run_vicuna_bot $ config_file $ verbosity_term $ const eio_env) in
+19
stack/vicuna/dune-project
+19
stack/vicuna/dune-project
···
···+(description "A Zulip bot that manages user registrations, mapping email addresses to Zulip IDs for easy @mentions and user tracking")
+4
stack/vicuna/lib/dune
+4
stack/vicuna/lib/dune
+502
stack/vicuna/lib/vicuna_bot.ml
+502
stack/vicuna/lib/vicuna_bot.ml
···
···+(* First, try to fetch the user's profile from the Zulip API to get delivery_email and email *)+Log.info (fun m -> m "Found user.email from API: %s (differs from message sender: %s)" user_email sender_email);+Log.warn (fun m -> m "Invalid email format provided: %s, trying API emails or falling back to sender email" email);
+84
stack/vicuna/lib/vicuna_bot.mli
+84
stack/vicuna/lib/vicuna_bot.mli
···
···