Skip to content

A bot that automates daily team standups in Zulip. Features automated scheduling, AI-powered summaries, multi-timezone support, and robust database persistence.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE
MIT
LICENSE.md
Notifications You must be signed in to change notification settings

protomated/zulip-standup-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

76 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Zulip Standup Bot

License: MIT Python 3.8+ Docker

A production-ready bot that automates daily team standups in Zulip. Features automated scheduling, AI-powered summaries, multi-timezone support, and robust database persistence.

πŸ“‘ Table of Contents

✨ Features

  • πŸ• Automated Scheduling: Daily prompts, reminders, and summaries with precise timing
  • 🌍 Multi-timezone Support: Each team member can set their own timezone
  • πŸŽ‰ Holiday Detection: Built-in support for Nigeria and US holidays with smart skipping
  • πŸ—“οΈ Flexible Scheduling: Configure custom days and automatic holiday handling
  • 🧠 Smart Prompts: Context-aware questions that adapt to gaps and holidays
  • ❓ Customizable Questions: Tailor standup questions to your team's workflow (1-5 questions)
  • πŸ€– AI-Powered Summaries: Intelligent team summaries using OpenAI GPT or Groq
  • πŸ’Ύ PostgreSQL/SQLite Support: Reliable data storage with connection pooling
  • πŸ›‘οΈ Production Ready: Comprehensive error handling, logging, and monitoring
  • 🐳 Easy Deployment: Docker, Docker Compose, and CapRover support
  • πŸ”„ Interactive Workflow: Flexible questionnaire with dynamic completion logic
  • πŸ“Š Rich Analytics: Search history, view trends, and track participation

πŸš€ Quick Start

1. Prerequisites

  • Zulip Server: A running Zulip instance with admin access
  • Bot Account: Create a bot account in your Zulip organization
  • Python 3.8+ or Docker

2. Create Bot Account

  1. Go to your Zulip organization settings
  2. Navigate to "Bots" section
  3. Add a new bot:
    • Name: Standup Bot
    • Username: standup-bot
    • Bot type: Generic bot
  4. Download the bot's configuration file (.zuliprc)

3. Installation Options

Option A: Docker (Recommended)

# Clone repository
git clone https://github.com/protomated/zulip-standup-bot.git
cd zulip-standup-bot

# Copy environment configuration
cp .env.example .env

# Edit .env with your configuration
nano .env

# Run with Docker Compose
docker-compose up -d

Option B: Local Development

# Clone repository
git clone https://github.com/protomated/zulip-standup-bot.git
cd zulip-standup-bot

# Create virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies (includes holiday detection library)
pip install -r requirements.txt

# Install the bot
pip install -e .

# Set up environment variables
cp .env.example .env
# Edit .env with your configuration

# Run the bot
python run_standup_bot.py

4. Configuration

Edit your .env file with the following required settings:

# Zulip Configuration (Required)
ZULIP_EMAIL=standup-bot@your-zulip.com
ZULIP_API_KEY=your_api_key_here
ZULIP_SITE=https://your-zulip.com

# AI Configuration (Optional - for smart summaries)
OPENAI_API_KEY=sk-your_openai_key  # Or use Groq
GROQ_API_KEY=gsk_your_groq_key     # Alternative to OpenAI

# Database (Optional - defaults to SQLite)
DATABASE_URL=postgresql://user:pass@localhost/standup

# Bot Behavior (Optional - has sensible defaults)
DEFAULT_TIMEZONE=America/New_York
DEFAULT_PROMPT_TIME=09:30
DEFAULT_REMINDER_TIME=11:45
DEFAULT_CUTOFF_TIME=12:45
LOG_LEVEL=INFO

5. Setup in Zulip

  1. Add the bot to your team channel
  2. Send the setup command:
@standup-bot /standup setup

The bot will automatically:

  • Configure daily standups with default times
  • Add all human channel members as participants
  • Schedule the first standup for the next business day

πŸ“‹ Commands Reference

Setup & Configuration

Command Description
/standup setup Activate standup with default times (9:30 AM prompt, 11:45 AM reminder, 12:45 PM summary)
/standup setup HH:MM Set custom prompt time only
/standup setup HH:MM HH:MM HH:MM Set prompt, reminder, and cutoff times
/standup config prompt_time HH:MM Change when daily prompts are sent
/standup config reminder_time HH:MM Change when reminders are sent
/standup config cutoff_time HH:MM Change when summaries are posted
/standup config times HH:MM HH:MM HH:MM Set all times at once
/standup config days weekdays Set which days to run (weekdays/weekend/all/custom)
/standup config holidays Nigeria Set holiday country (Nigeria/US)
/standup config skip_holidays true Enable/disable holiday skipping
/standup config questions Q1, Q2, Q3 Set custom standup questions (comma-separated)
/standup config questions reset Reset questions to defaults
/standup config timezone <tz> Set channel timezone (e.g., America/New_York)

Personal Settings

Command Description
/standup timezone <tz> Set your personal timezone
/standup timezone View your current timezone

Management

Command Description
/standup status View configuration and next scheduled events
/standup pause Temporarily pause standups for this channel
/standup resume Resume paused standups
/standup participants View and manage team participants
/standup test-prompt Send a test prompt immediately

History & Analytics

Command Description
/standup history [days] View recent standup history (default: 7 days)
/standup search <term> Search past standup responses
/standup stats View participation statistics

Debug & Support

Command Description
/standup debug Show technical details and scheduler status
/standup help Show command help

πŸ”„ How It Works

Daily Workflow

  1. Morning Prompt (e.g., 9:30 AM)

    • Bot sends private messages to all participants
    • Asks the first configured question (default: "What did you work on yesterday?")
  2. Interactive Questionnaire

    • Bot asks follow-up questions based on your team's configuration
    • Default: 3 questions about yesterday's work, today's plans, and blockers
    • Custom: 1-5 questions tailored to your team's needs
    • Completion marked when all questions are answered
  3. Reminder (e.g., 11:45 AM)

    • Friendly reminder sent to non-responders
    • Includes quick action buttons for easy participation
  4. Summary (e.g., 12:45 PM)

    • AI-generated summary posted to channel
    • Adapts to your question structure automatically
    • Includes participation stats and key highlights
    • Falls back to manual summary if AI unavailable

Smart Features

  • Timezone Intelligence: Each user's prompts arrive at their local time
  • Weekend Detection: Automatically skips weekends and holidays
  • Participant Management: Automatically excludes bots and inactive users
  • Graceful Degradation: Works without AI, database, or network issues

πŸŽ‰ Holiday Detection & Smart Scheduling

Automatic Holiday Support

The bot includes built-in holiday detection for Nigeria and the United States, automatically skipping standups on official holidays and adapting prompts accordingly.

Supported Countries

Nigeria πŸ‡³πŸ‡¬

  • New Year's Day (January 1)
  • Independence Day (October 1)
  • Christmas Day (December 25)
  • Boxing Day (December 26)
  • All other official Nigerian holidays

United States πŸ‡ΊπŸ‡Έ

  • New Year's Day (January 1)
  • Independence Day (July 4)
  • Thanksgiving (4th Thursday in November)
  • Christmas Day (December 25)
  • All federal holidays including Memorial Day, Labor Day, etc.

How Holiday Detection Works

  1. Automatic Skipping: When a scheduled standup day falls on a holiday, the bot automatically skips prompts, reminders, and summaries
  2. Smart Prompts: After holidays, prompts ask about the last actual work day instead of "yesterday"
  3. Configurable: Each channel can enable/disable holiday detection and choose their country

Holiday Configuration

Basic Setup

# Nigerian holidays (default)
/standup setup

# US holidays  
/standup setup
/standup config holidays US

# Disable holiday skipping
/standup config skip_holidays false

Advanced Configuration

# Set holiday country
/standup config holidays Nigeria    # Nigerian holidays
/standup config holidays US         # United States holidays

# Control holiday skipping
/standup config skip_holidays true   # Skip holidays (default)
/standup config skip_holidays false  # Run on holidays too

# Combine with custom days
/standup config days weekdays        # Monday-Friday only
/standup config holidays US          # + skip US holidays

Smart Prompt Examples

The bot automatically adapts prompts based on holidays and configured days:

Regular Tuesday:

"What did you work on yesterday?"

Tuesday after Nigerian Independence Day (October 1):

"What did you work on last Thursday?" (skipped Friday holiday, weekend)

Wednesday after US Thanksgiving:

"What did you work on last Tuesday?" (before the long weekend)

Monday after Christmas weekend:

"What did you work on last Friday?" (before the holiday period)

Holiday Status Display

Use /standup status to see current holiday configuration:

🎯 Standup Status for #engineering

πŸ“Š Configuration:
β€’ Status: βœ… Active
β€’ Timezone: America/New_York
β€’ Days: Weekdays (Mon-Fri)
β€’ Holiday Country: United States
β€’ Skip Holidays: βœ… Enabled
β€’ Participants: 8 members

Use /standup debug to see if today is a holiday:

πŸ“ˆ Channels:
β€’ engineering: Prompt at 09:30 UTC, Holidays: United States πŸŽ‰

(The πŸŽ‰ emoji appears when today is a holiday)

Deployment Considerations

  • Default Behavior: New channels default to Nigerian holidays with skipping enabled
  • No Dependencies: Holiday detection gracefully degrades if the holidays library isn't available
  • Database Migration: Existing deployments automatically get holiday support with sensible defaults
  • Logging: Holiday detection is logged for debugging and monitoring

πŸ—οΈ Architecture

Components

  • Main Bot Handler (standup.py): Core bot logic and command routing
  • Database Layer (database.py): PostgreSQL/SQLite operations with pooling
  • Scheduler (APScheduler): Timezone-aware job scheduling
  • AI Integration (ai_summary.py): OpenAI/Groq integration for summaries
  • Configuration (config.py): Environment and default settings

Database Schema

The bot uses a PostgreSQL or SQLite database with the following tables:

  • users: User preferences and timezone settings
  • channels: Channel configuration and scheduling
  • channel_participants: Team membership tracking
  • standup_responses: Daily response storage with JSONB
  • standup_prompts: Prompt tracking and pending responses

Dual Storage Strategy

  • Primary: Database storage for persistence and reliability
  • Fallback: In-memory storage for temporary operation
  • Automatic: Switches based on database availability

🐳 Deployment

Docker Compose (Recommended)

version: '3.8'
services:
  standup-bot:
    build: .
    environment:
      - ZULIP_EMAIL=standup-bot@your-zulip.com
      - ZULIP_API_KEY=your_api_key
      - ZULIP_SITE=https://your-zulip.com
      - DATABASE_URL=postgresql://user:pass@db:5432/standup
    depends_on:
      - db
    restart: unless-stopped
    volumes:
      - ./data:/app/data

  db:
    image: postgres:15
    environment:
      - POSTGRES_DB=standup
      - POSTGRES_USER=standup_user
      - POSTGRES_PASSWORD=your_secure_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:

CapRover Deployment

  1. Fork this repository
  2. Create a new CapRover app
  3. Connect your Git repository
  4. Set environment variables in app settings
  5. Deploy using the included captain-definition

Manual Deployment

# Install system dependencies
sudo apt-get update
sudo apt-get install python3 python3-pip postgresql

# Clone and setup
git clone https://github.com/protomated/zulip-standup-bot.git
cd zulip-standup-bot
pip3 install -r requirements.txt

# Configure systemd service
sudo cp standup-bot.service /etc/systemd/system/
sudo systemctl enable standup-bot
sudo systemctl start standup-bot

βš™οΈ Configuration Reference

Environment Variables

Required Settings

Variable Description Example
ZULIP_EMAIL Bot's email address standup-bot@company.zulipchat.com
ZULIP_API_KEY Bot's API key from Zulip abcd1234...
ZULIP_SITE Zulip server URL https://company.zulipchat.com

Optional Settings

Variable Default Description
OPENAI_API_KEY None OpenAI API key for AI summaries
GROQ_API_KEY None Groq API key (alternative to OpenAI)
DATABASE_URL SQLite file PostgreSQL connection string
DEFAULT_TIMEZONE Africa/Lagos Default timezone for new channels
DEFAULT_PROMPT_TIME 09:30 Default time to send prompts
DEFAULT_REMINDER_TIME 11:45 Default time to send reminders
DEFAULT_CUTOFF_TIME 12:45 Default time to post summaries
DEFAULT_HOLIDAY_COUNTRY Nigeria Default holiday country (Nigeria/United States)
DEFAULT_SKIP_HOLIDAYS true Default holiday skipping setting
LOG_LEVEL INFO Logging level (DEBUG, INFO, WARNING, ERROR)

Advanced Configuration

Database Settings

# PostgreSQL (recommended for production)
DATABASE_URL=postgresql://user:password@localhost:5432/standup

# SQLite (good for development)
DATABASE_URL=sqlite:///./data/standup.db

AI Provider Settings

# OpenAI (more accurate, higher cost)
OPENAI_API_KEY=sk-your-key-here
OPENAI_MODEL=gpt-3.5-turbo

# Groq (faster, lower cost)
GROQ_API_KEY=gsk-your-key-here
GROQ_MODEL=llama-3.1-8b-instant

πŸ”§ Customization

Custom AI Providers

To add support for other AI providers, extend the ai_summary.py module:

class CustomAIProvider:
    def generate_summary(self, responses):
        # Your implementation here
        return summary_text

Custom Questions

Modify the questions in standup.py:

STANDUP_QUESTIONS = [
    "What did you accomplish yesterday?",
    "What are your goals for today?",
    "What challenges are you facing?"
]

Customizable Standup Questions

The bot allows you to customize the questions asked during standups to better fit your team's workflow and needs.

Default Questions

By default, the bot asks these 3 questions:

  1. "What did you work on {last_day}?"
  2. "What are you planning to work on today?"
  3. "Any blockers or issues you're facing?"

Setting Custom Questions

# Set custom questions (comma-separated)
/standup config questions What are your top 3 priorities today?, What help do you need from teammates?, What did you learn yesterday?

# Single question workflow
/standup config questions What's your main focus for today?

# Reset to default questions
/standup config questions reset

Question Features

  • Dynamic Day References: Use {last_day} placeholder to automatically reference the last working day
  • Flexible Workflow: Support 1-5 custom questions per standup
  • Team-Specific: Each channel can have different questions
  • Smart Adaptation: Bot adjusts prompts and completion logic based on question count

Example Configurations

Engineering Team:

/standup config questions What did you ship {last_day}?, What are you building today?, Any technical blockers?

Product Team:

/standup config questions What customer insights did you gather {last_day}?, What features are you prioritizing today?, What feedback needs addressing?

Sales Team:

/standup config questions How many prospects did you contact {last_day}?, What deals are you closing today?, What support do you need?

Coaching Cohort:

/standup config questions What progress did you make on your goals {last_day}?, What are you committed to achieving today?, What support or accountability do you need?

Single Question (Daily Focus):

/standup config questions What is your #1 priority today and how can the team help?

Viewing Current Questions

Check your current question configuration with /standup status:

❓ Questions (Custom):
  1. What are your top 3 priorities today?
  2. What help do you need from teammates?
  3. What did you learn yesterday?

Custom Time Zones

The bot supports all standard timezone names. Common examples:

  • America/New_York (Eastern Time)
  • America/Chicago (Central Time)
  • America/Denver (Mountain Time)
  • America/Los_Angeles (Pacific Time)
  • Europe/London (GMT/BST)
  • Europe/Berlin (CET/CEST)
  • Asia/Tokyo (JST)

πŸ“Š Monitoring & Maintenance

Health Checks

The bot includes built-in health monitoring:

# Check bot status
curl http://localhost:5002/health

# View metrics
curl http://localhost:5002/metrics

Logging

Logs are structured and include:

  • Timestamp and log level
  • Component and operation context
  • Performance metrics
  • Error details and stack traces

Database Maintenance

The bot automatically:

  • Cleans up old data (>90 days)
  • Optimizes database performance
  • Manages connection pooling
  • Handles schema migrations

Backup Strategy

For production deployments:

# PostgreSQL backup
pg_dump standup > backup_$(date +%Y%m%d).sql

# SQLite backup
cp data/standup.db backup_$(date +%Y%m%d).db

πŸ› Troubleshooting

Common Issues

Bot Not Responding

  1. Check Status: Use /standup debug to see scheduler status
  2. Verify Configuration: Ensure all environment variables are set
  3. Check Logs: Look for error messages in application logs
  4. Test Connection: Verify bot can connect to Zulip

Prompts Not Being Sent

  1. Verify Setup: Check /standup status shows active configuration
  2. Check Timezone: Ensure timezone settings are correct
  3. Verify Participants: Confirm users are added to channel
  4. Test Manually: Use /standup test-prompt to test immediately

AI Summaries Not Working

  1. Check API Key: Verify OPENAI_API_KEY or GROQ_API_KEY is set
  2. Check Credits: Ensure API account has sufficient credits
  3. Review Logs: Look for API error messages
  4. Fallback Mode: Bot continues with manual summaries

Database Connection Issues

  1. Check URL: Verify DATABASE_URL format is correct
  2. Check Permissions: Ensure database user has required permissions
  3. Test Connection: Use database client to verify connectivity
  4. Fallback Mode: Bot switches to in-memory storage automatically

Debug Commands

# Show detailed status
/standup debug

# Test immediate prompt
/standup test-prompt

# Check configuration
/standup status

# View recent activity
/standup history 1

Performance Tuning

For large teams (50+ members):

  1. Database Optimization:

    • Use PostgreSQL instead of SQLite
    • Enable connection pooling
    • Add database indexes
  2. Scheduler Tuning:

    • Increase APScheduler thread pool size
    • Optimize job execution intervals
  3. Monitoring:

    • Enable detailed logging
    • Set up metrics collection
    • Monitor database performance

🀝 Contributing

We welcome contributions! Please see our contributing guidelines:

Development Setup

# Fork and clone
git clone https://github.com/protomated/zulip-standup-bot.git
cd zulip-standup-bot

# Setup development environment
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install -e .

# Run tests
python -m pytest

# Code formatting
python -m black .
python -m isort .

Code Style

  • Black for code formatting
  • isort for import sorting
  • mypy for type checking
  • pytest for testing

Submitting Changes

  1. Create a feature branch
  2. Write tests for new functionality
  3. Ensure all tests pass
  4. Update documentation
  5. Submit a pull request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support


Made with ❀️ for distributed teams everywhere by Protomated

About

A bot that automates daily team standups in Zulip. Features automated scheduling, AI-powered summaries, multi-timezone support, and robust database persistence.

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE
MIT
LICENSE.md

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages