Package Information
Available Nodes
Documentation
n8n-nodes-zulip-hitl
🚀 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)
- Go to Settings > Community Nodes in your n8n instance
- Select Install
- Enter
n8n-nodes-zulip-hitl
- Click Install
- 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:
- Login to Zulip as an administrator
- Go to Settings > Your bots
- Click Add a new bot
- Fill in the details:
- Bot type: Generic bot
- Full name: n8n Workflow Bot
- Username: n8n-bot
- Avatar: Optional
- Copy the API key for later use
2. Zulip API Credentials in n8n
Configure Zulip credentials in n8n:
- Navigate to Credentials in n8n
- Click Create New
- Search for "Zulip API"
- 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 |
- 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)

| 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:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite:
npm test
- 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
- Request a Feature
- Include: Use case, expected behavior, examples
💬 Questions
📧 Contact
- Email: [email protected]
- Response time: Usually within 24-48 hours
Made with ❤️ for the n8n and Zulip communities