back to tutorials

How to Use Channel-Based Function Calling with Stream

Learn how to implement channel-based function calling using the complete().stream() method for inline conversation execution. This tutorial covers real-time event handling and function execution in interactive chat scenarios.

This tutorial demonstrates how to implement channel-based function calling using the complete().stream() method in ChatBotKit. This approach is ideal for interactive conversations where you need real-time control over the conversation flow.

Learning Objectives

By the end of this tutorial, you will be able to:

  • Use the complete().stream() method for inline conversation processing
  • Handle streaming events directly in your code
  • Implement static and channel-based function results
  • Process the waitForChannelMessageBegin event for dynamic function execution
  • Display real-time tokens as they arrive

Prerequisites

  • Node.js 18+ installed
  • A ChatBotKit account with an API secret
  • Basic understanding of async iterators and streams

Estimated time: 20 minutes

Understanding Stream vs Dispatch

Aspectcomplete().stream()dispatch()
ExecutionInline, blockingBackground, async
Event sourceDirect from stream iteratorVia channel.subscribe()
Use caseInteractive chatBackground tasks
ControlDirect in your loopRequires separate subscription

The complete().stream() method processes a conversation inline, streaming events directly to your code as they occur.

Step 1: Set Up Your Project

Create a new Node.js project and install the ChatBotKit SDK:

Create a .env file with your API secret:

CHATBOTKIT_API_SECRET=your_api_secret_here

Step 2: Create the Basic Structure

Create a file called index.js:

Step 3: Define Your Functions

Define both static and channel-based functions:

Step 4: Start the Conversation Stream

Use complete().stream() to get a stream of events:

Step 5: Process Stream Events

Iterate over the stream and handle different event types:

Step 6: Handle Channel Function Calls

When you receive a waitForChannelMessageBegin event, execute the function and publish the result:

Complete Example

Here's the complete working example:

Key Differences from Dispatch

  1. Direct event access: Events come directly from the stream iterator, not wrapped in a message envelope
  2. Inline execution: Your code blocks while processing the stream
  3. Token streaming: You can display tokens in real-time with event.type === 'token'
  4. Simpler event handling: Event types are directly on event.type

Displaying Real-Time Tokens

To show tokens as they arrive (for chat-like interfaces):

Troubleshooting

Stream Closes Early

Ensure you handle all events before the result event. Don't break out of the loop prematurely.

Channel Timeout

If you don't publish to the channel quickly enough, the conversation may timeout. Execute functions efficiently.

Missing Results

Always check event.type carefully. The stream includes many event types - filter for what you need.

Next Steps