zulip-hitl

Package Information

Released: 6/4/2025
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0
Author: b_matlega

Documentation

n8n-nodes-zulip-hitl

n8n.io - Workflow Automation

🚀 Overview

The Zulip Human-in-the-Loop (HITL) node enables seamless integration of human decision-making processes within n8n workflows. This node allows workflows to pause execution, send queries to users via Zulip, wait for responses, and continue processing with the received input.

Perfect for approval workflows, content review processes, quality control checkpoints, and any scenario where human judgment is required within automated processes.

✨ Features

  • 🔄 Request Approval: Send approval requests and wait for human responses
  • 📨 Send Messages: Post messages to Zulip streams with rich formatting
  • 🏗️ Stream Management: Create and configure Zulip streams automatically
  • 📡 Response Monitoring: Real-time monitoring of user responses with configurable polling
  • 🎨 Rich Formatting: Full Markdown support for rich text messaging
  • ⚡ Validation System: Comprehensive response validation and sanitization
  • 📊 Advanced Analytics: Built-in metrics collection and error tracking
  • 🛡️ Security: XSS protection, content sanitization, and secure API handling
  • 🔧 Debug Tools: Comprehensive logging and debugging capabilities
  • ⏱️ Timeout Handling: Configurable timeouts with automatic recovery
  • 👥 User Management: Flexible user subscription and notification management

📦 Installation

Prerequisites

  • n8n instance (version 1.0.0 or higher)
  • Self-hosted Zulip instance with API access
  • Zulip bot account with appropriate permissions
  • Node.js 18.x or higher (for development)

Option 1: Community Nodes (Recommended)

  1. Go to Settings > Community Nodes in your n8n instance
  2. Select Install
  3. Enter n8n-nodes-zulip-hitl
  4. Click Install
  5. Restart your n8n instance

Option 2: Manual Installation

# Navigate to your n8n custom nodes directory
cd ~/.n8n/custom

# Initialize npm if not already done
npm init -y

# Install the package
npm install n8n-nodes-zulip-hitl

# Restart n8n

Option 3: Development Installation

# Clone the repository
git clone https://github.com/bartlomiejmatlega/n8n-nodes-zulip-hitl.git
cd n8n-nodes-zulip-hitl

# Install dependencies
npm install

# Build the project
npm run build

# Link for local development
npm link
cd ~/.n8n/custom
npm link n8n-nodes-zulip-hitl

# Restart n8n

⚙️ Configuration

1. Zulip Bot Setup

First, create a bot account in your Zulip instance:

  1. Login to Zulip as an administrator
  2. Go to Settings > Your bots
  3. Click Add a new bot
  4. Fill in the details:
    • Bot type: Generic bot
    • Full name: n8n Workflow Bot
    • Username: n8n-bot
    • Avatar: Optional
  5. Copy the API key for later use

2. Zulip API Credentials in n8n

Configure Zulip credentials in n8n:

  1. Navigate to Credentials in n8n
  2. Click Create New
  3. Search for "Zulip API"
  4. Configure the following:
Field Description Example
Zulip Server URL Your Zulip instance URL https://yourcompany.zulipchat.com
Bot Email Email address of your Zulip bot [email protected]
Bot API Key API key from bot configuration aBcDeFgH123456789
  1. Test the connection and save

3. Stream Permissions

Ensure your bot has appropriate permissions:

  • Create streams (if using createStream operation)
  • Send messages to target streams
  • Subscribe users to streams
  • Read messages from monitoring streams

🎯 Operations

The Zulip HITL node supports four main operations:

1. Request Approval

Send approval requests and wait for human responses.

Key Parameters:

  • Stream Name: Target stream for approval requests
  • Topic: Conversation topic (auto-generated if enabled)
  • Query Content: Message content with Markdown support
  • Approval Keywords: Words indicating approval (e.g., "approve,yes,ok")
  • Rejection Keywords: Words indicating rejection (e.g., "reject,no,deny")
  • Timeout: Maximum wait time (1-1440 minutes)
  • Polling Interval: Check frequency (10-3600 seconds)

Example Use Case:

Expense Report → Request Approval → Process Decision

2. Send Message

Post messages to Zulip streams with rich formatting.

Key Parameters:

  • Stream Name: Target stream
  • Topic: Message topic
  • Query Content: Message content with Markdown

Example Use Case:

Data Processing → Send Status Update → Continue Workflow

3. Create Stream

Create new Zulip streams with automatic user subscription.

Key Parameters:

  • Stream Name: New stream name
  • Stream Description: Purpose description
  • Private Stream: Visibility setting
  • Subscribe Users: Comma-separated email list

Example Use Case:

New Project → Create Approval Stream → Configure Notifications

4. Handle User Response

Monitor streams for user responses and process them.

Key Parameters:

  • Stream Name: Stream to monitor
  • Monitor Topic: Specific topic (optional)
  • Response Type: Expected response format
  • Timeout: Monitoring duration
  • Polling Interval: Check frequency

Example Use Case:

Send Query → Handle Response → Process User Input

📝 Usage Examples

Basic Approval Workflow

{
  "nodes": [
    {
      "name": "Expense Approval",
      "type": "n8n-nodes-zulip-hitl.zulipHitl",
      "parameters": {
        "operation": "approval",
        "streamName": "expense-approvals",
        "topic": "Monthly Expense Review",
        "queryContent": "**Expense Report Review Required**\n\nEmployee: {{ $json.employeeName }}\nAmount: ${{ $json.amount }}\nCategory: {{ $json.category }}\n\nPlease review and approve or reject this expense.",
        "approvalKeywords": "approve,approved,yes,accept",
        "rejectionKeywords": "reject,denied,no,decline",
        "timeoutMinutes": 60,
        "pollingInterval": 30
      }
    }
  ]
}

Multi-Step Stream Creation

{
  "nodes": [
    {
      "name": "Create Project Stream",
      "type": "n8n-nodes-zulip-hitl.zulipHitl",
      "parameters": {
        "operation": "createStream",
        "streamName": "project-{{ $json.projectId }}",
        "streamDescription": "Discussion stream for project {{ $json.projectName }}",
        "privateStream": false,
        "subscribeUsers": "{{ $json.teamMembers.join(',') }}"
      }
    },
    {
      "name": "Send Welcome Message",
      "type": "n8n-nodes-zulip-hitl.zulipHitl",
      "parameters": {
        "operation": "sendMessage",
        "streamName": "project-{{ $json.projectId }}",
        "topic": "Welcome",
        "queryContent": "# Welcome to Project {{ $json.projectName }}!\n\n**Project Manager:** {{ $json.projectManager }}\n**Start Date:** {{ $json.startDate }}\n**Deadline:** {{ $json.deadline }}\n\nLet's get started! 🚀"
      }
    }
  ]
}

Advanced Response Handling

{
  "nodes": [
    {
      "name": "Monitor Feedback",
      "type": "n8n-nodes-zulip-hitl.zulipHitl",
      "parameters": {
        "operation": "handleResponse",
        "streamName": "product-feedback",
        "monitorTopic": "Feature Requests",
        "responseType": "text-input",
        "timeoutMinutes": 120,
        "pollingInterval": 45,
        "extractUserInfo": true
      }
    }
  ]
}

🎨 Markdown Formatting

The node supports full Zulip Markdown syntax:

Text Formatting

**Bold text**
*Italic text*
***Bold and italic***
~~Strikethrough~~
`inline code`

Lists and Structure

# Heading 1
## Heading 2
### Heading 3

- Bullet list item
- Another item
  - Nested item

1. Numbered list
2. Second item
   1. Nested numbered

> Quote block
> Multiple lines

Advanced Features

[Link text](https://example.com)
![Image alt](https://example.com/image.png)

| Column 1 | Column 2 |
|----------|----------|
| Data 1   | Data 2   |

:emoji_name:
:+1: :tada: :rocket:

- [x] Completed task
- [ ] Pending task

~~deleted text~~

Code Blocks

```javascript
function example() {
    return "syntax highlighted code";
}
```

```python
def hello_world():
    print("Hello, World!")
```

🔧 Advanced Configuration

Environment Variables

Configure these in your n8n environment:

# Logging
N8N_LOG_LEVEL=info
ZULIP_HITL_DEBUG=false

# Timeouts
ZULIP_HITL_DEFAULT_TIMEOUT=1800
ZULIP_HITL_MAX_RETRIES=3

# Performance
ZULIP_HITL_CACHE_SIZE=100
ZULIP_HITL_BATCH_SIZE=50

Debug Mode

Enable detailed logging for troubleshooting:

{
  "debugConfig": {
    "enabled": true,
    "level": "debug",
    "categories": ["api", "validation", "workflow"],
    "logToFile": true,
    "includeStackTrace": true
  }
}

Custom Validation Rules

Configure response validation:

{
  "validationConfig": {
    "enableSanitization": true,
    "preventXSS": true,
    "preventSQLInjection": true,
    "customRules": [
      {
        "field": "streamName",
        "pattern": "^[a-z0-9-]+$",
        "maxLength": 60
      }
    ]
  }
}

🛡️ Security Considerations

Bot Permissions

Configure minimal required permissions:

Bot Permissions:
  - Send messages to streams
  - Create streams (if needed)
  - Subscribe users to streams
  - Read messages from subscribed streams

Data Sanitization

All inputs are automatically sanitized:

  • XSS Protection: Script tags and dangerous HTML removed
  • SQL Injection Prevention: Dangerous SQL patterns detected
  • Content Validation: Input length and format validation
  • Markdown Safety: Safe Markdown rendering only

Sensitive Data

Best practices for handling sensitive information:

  • Never log API keys or credentials
  • Mask sensitive data in debug output
  • Use private streams for confidential workflows
  • Implement timeout policies for security-critical approvals

📊 Monitoring and Analytics

Built-in Metrics

The node automatically collects:

  • Response times for API calls
  • Success/failure rates for operations
  • User response patterns and timing
  • Error frequency and categorization
  • Performance benchmarks over time

Health Checks

Monitor node health with:

// Check node status
const healthCheck = {
  apiConnectivity: "green",
  responseTime: "< 500ms",
  errorRate: "< 1%",
  lastSuccessfulPoll: "2024-01-15T10:30:00Z"
};

Alerting

Set up alerts for:

  • API connection failures
  • High response times (> 5 seconds)
  • Approval timeouts exceeding threshold
  • Validation errors spike
  • Stream creation failures

🐛 Troubleshooting

Common Issues

1. Authentication Errors

Error: 401 Unauthorized

Solution:

  • Verify bot API key is correct
  • Check bot has required permissions
  • Ensure Zulip server URL is accessible

2. Stream Not Found

Error: Stream 'approval-requests' does not exist

Solution:

  • Use createStream operation first
  • Check stream name spelling
  • Verify bot is subscribed to stream

3. Timeout Issues

Error: Timeout waiting for approval

Solution:

  • Increase timeout duration
  • Check polling interval setting
  • Verify users are notified properly

4. Formatting Problems

Warning: Markdown not rendering correctly

Solution:

  • Check Markdown syntax
  • Verify no forbidden HTML
  • Test with simple formatting first

Debug Mode

Enable debug logging:

{
  "operation": "approval",
  "debugConfig": {
    "enabled": true,
    "level": "debug",
    "categories": ["api", "response", "validation"]
  }
}

Validation Errors

Common validation issues:

# Stream name validation
Error: Stream name must be lowercase alphanumeric with hyphens only

# Topic length validation  
Error: Topic name exceeds 60 character limit

# Timeout validation
Error: Timeout must be between 1 and 1440 minutes

🔗 API Reference

Node Input Format

{
  "operation": "approval",
  "streamName": "approval-stream",
  "topic": "Workflow Approval",
  "queryContent": "Please approve this action",
  "timeoutMinutes": 30,
  "approvalKeywords": "approve,yes",
  "rejectionKeywords": "reject,no"
}

Node Output Format

{
  "approved": true,
  "response": "approve",
  "user": {
    "id": 123,
    "email": "[email protected]",
    "full_name": "John Doe"
  },
  "timestamp": "2024-01-15T10:30:00Z",
  "responseTime": 1500,
  "streamInfo": {
    "streamName": "approval-stream",
    "streamId": 15,
    "topic": "Workflow Approval",
    "messageId": 456
  },
  "validationResults": {
    "isValid": true,
    "sanitizedContent": "approve",
    "securityChecks": "passed"
  }
}

🚀 Best Practices

1. Stream Naming

# Good stream names
project-alpha-approval
expense-review-2024
hr-onboarding-requests

# Avoid
Project Alpha Approval  # Contains spaces
project_alpha_approval  # Contains underscores

2. Timeout Configuration

// Short-term approvals (urgent)
timeoutMinutes: 15

// Standard business approvals
timeoutMinutes: 60

// Complex review processes
timeoutMinutes: 240

// Long-term feedback collection
timeoutMinutes: 1440  // 24 hours

3. Polling Intervals

// Real-time critical (higher API usage)
pollingInterval: 10

// Standard workflows
pollingInterval: 30

// Background processes
pollingInterval: 300  // 5 minutes

4. Error Handling

// Implement proper error handling
try {
  const result = await zulipHitlNode.execute();
  return result;
} catch (error) {
  if (error.type === 'timeout') {
    // Handle timeout scenario
    return handleTimeout();
  } else if (error.type === 'validation') {
    // Handle validation errors
    return handleValidationError(error);
  } else {
    // Handle other errors
    return handleGenericError(error);
  }
}

📚 Additional Resources

Documentation Links

Community

Examples Repository

Find more examples and templates:

🤝 Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for new functionality
  5. Run the test suite: npm test
  6. Submit a pull request

Development Setup

# Clone and setup
git clone https://github.com/bartlomiejmatlega/n8n-nodes-zulip-hitl.git
cd n8n-nodes-zulip-hitl
npm install

# Development commands
npm run dev          # Watch mode
npm run build        # Production build
npm run lint         # Code linting
npm run format       # Code formatting
npm run test         # Run tests

📄 License

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

🙏 Acknowledgments

  • n8n.io - Workflow automation platform
  • Zulip - Open-source team chat
  • Contributors - Thank you to all contributors!

📞 Support

Need help? Here's how to get support:

🐛 Bug Reports

  • Create an Issue
  • Include: n8n version, node version, error logs, workflow JSON

✨ Feature Requests

💬 Questions

📧 Contact


Made with ❤️ for the n8n and Zulip communities

Discussion