Zulip HITL

Human-in-the-loop integration with Zulip

Overview

The "Request Approval" operation in this node enables sending a message to a specified Zulip stream requesting human approval for a workflow step. It posts a formatted query message and then waits, polling the Zulip API for user responses that match configured approval or rejection keywords. This allows workflows to pause and resume based on explicit human decisions communicated via Zulip.

Common scenarios include:

  • Workflow steps requiring manual sign-off before proceeding.
  • Compliance or quality checks where human validation is mandatory.
  • Collaborative decision-making processes integrated into automated workflows.

Practical example:
A deployment pipeline sends an approval request message to a Zulip stream named approval-requests with details about the release. Team members reply with "approve" or "reject" keywords. The workflow waits up to 30 minutes, checking every 30 seconds, and continues based on the received response or times out if no response arrives.


Properties

Name Meaning
Stream Name Name of the Zulip stream to send the approval request message to. Must be lowercase, max 60 characters, and follow Zulip naming rules.
Topic Topic under which the approval message will be posted in the stream. Helps organize conversations. If left empty, a default topic "Approval Request" is used, optionally appended with a timestamp for uniqueness.
Generate Unique Topic Boolean flag to append a timestamp suffix (format: YYYY-MM-DD-HH-mm-ss) to the topic name to ensure uniqueness and avoid conflicts in approval workflows.
Query Content The content of the approval request message sent to Zulip. Supports Markdown formatting for rich text (bold, italic, code, links). Should clearly describe what requires approval.
Approval Keywords Comma-separated list of case-insensitive keywords indicating approval (e.g., "approve", "yes", "confirm"). Users replying with any of these words are considered to have approved.
Rejection Keywords Comma-separated list of case-insensitive keywords indicating rejection (e.g., "reject", "no", "deny"). Leave empty to only allow approvals without rejections.
Timeout (Minutes) Duration in minutes to wait for an approval or rejection response before timing out. After timeout, the workflow proceeds as if no response was received. Range: 1 to 1440 minutes.
Polling Interval (Seconds) Frequency in seconds to poll Zulip for new messages containing approval or rejection responses. Minimum 10 seconds; recommended 30-60 seconds to balance responsiveness and API usage.
Enable Debug Mode Enables detailed debug logging for troubleshooting, including API calls and internal processing. May impact performance.
Debug Level Level of detail for debug logs (Debug, Error Only, Info, Trace, Verbose, Warnings). Higher levels provide more information but may reduce performance.
Debug Categories Specific categories of debug information to enable (e.g., API calls, Authentication, Network). Allows focusing logs on relevant areas.
Debug Output Format Format of debug output logs: JSON (machine-readable) or Pretty (human-readable).
Performance Tracking Tracks operation timing and memory usage to help identify bottlenecks. Adds slight overhead.
Include Stack Traces Includes stack traces in error and debug logs for deeper debugging at the cost of increased log size.
Formatting Options Collection of options to configure message formatting, including allowed/forbidden HTML tags, enabling/disabling emoji, markdown, math blocks, mentions, spoilers, tables, message style (plain, basic markdown, rich markdown, Zulip enhanced), and XSS protection.

Output

The node outputs a JSON object with the following structure after the approval request completes:

  • approved (boolean): Whether the request was approved by a user.
  • rejected (boolean): Whether the request was rejected by a user.
  • timedOut (boolean): True if no response was received within the timeout period.
  • streamName (string): The Zulip stream name where the request was posted.
  • topic (string): The topic under which the approval message was posted.
  • messageId (number): The Zulip message ID of the approval request.
  • elapsedMinutes (number): Minutes elapsed waiting for the response.
  • timeoutMinutes (number): Configured timeout duration.
  • response (object|null): Details of the user response if received, including:
    • id: Response message ID.
    • content: Text content of the response.
    • sender: Full name of the user who responded.
    • timestamp: Timestamp of the response.
  • timestamp (ISO string): Timestamp when the node finished processing.
  • userFeedback (object): A structured message summarizing success or timeout status for user feedback and logging.

No binary data output is produced by this operation.


Dependencies

  • Requires valid credentials for Zulip API access, including server URL, bot email, and API key.
  • Uses the Zulip API client to send messages and poll for responses.
  • Relies on n8n environment to provide these credentials securely.
  • Optional debug logging depends on internal logger and debug configuration modules.
  • Markdown processing uses configurable options for safe and rich text formatting.

Troubleshooting

Common Issues

  • Missing or invalid credentials: The node throws an error if no Zulip API credentials are provided or connection test fails.
  • Invalid stream or topic names: Validation errors occur if stream names or topics do not meet Zulip naming conventions or length limits.
  • Empty or invalid message content: The query content must not be empty after markdown processing.
  • Timeouts: If no approval or rejection response is received within the configured timeout, the node returns a timeout result.
  • API errors: Failures to send messages or check responses result in errors with descriptive messages.

Error Messages and Resolutions

  • "No credentials provided": Ensure you have configured and selected valid Zulip API credentials.
  • "Connection failed": Verify network connectivity and correctness of API credentials.
  • "Stream name required" or "Invalid stream name": Provide a valid stream name following Zulip rules.
  • "Content required" or "Query content cannot be empty": Enter meaningful message content for approval requests.
  • "Timeout must be between 1 and 1440 minutes": Adjust the timeout value within allowed range.
  • "Polling Interval must be between 10 and 3600 seconds": Set polling interval within allowed range.
  • "Failed to send message: <error>": Check Zulip API permissions and stream existence.
  • "Approval timeout": No user response received in time; consider increasing timeout or notifying users.

Enabling debug mode can provide detailed logs to diagnose issues.


Links and References


This summary covers the static analysis of the "Request Approval" operation of the custom Zulip HITL node implementation, describing its inputs, outputs, dependencies, and common troubleshooting points.

Discussion