Scenario: inbound call is coming. I want to dispat...
# ask-ai
f
Scenario: inbound call is coming. I want to dispatch an agent based on phone number with a context specific metadata. Can I use server APIs to add a participant agent based on some custom logic from webhook? https://docs.livekit.io/home/server/webhooks/ let's say something like this:
Copy code
import { FastifyPluginAsync } from 'fastify';
import { createDatabaseClient } from '@pf-workflo/core';
import { inboundMappings } from '@pf-workflo/core/src/services/db/schema/telephony';
import { eq } from 'drizzle-orm';
import { WorkflowType } from '@pf-workflo/core/dist/types/index';
import { createWorkflowEngine } from '../engine';

const webhookSecret = process.env.LIVEKIT_WEBHOOK_SECRET; // Set in env

export const livekitWebhookRoutes: FastifyPluginAsync = async (fastify) => {
  const workflowEngine = createWorkflowEngine({ signingKey: process.env.INNGEST_SIGNING_KEY || '', eventKey: process.env.INNGEST_EVENT_KEY || '' });

  <http://fastify.post|fastify.post>('/api/livekit-webhook', async (request, reply) => {
    const sig = request.headers['lk-signature'] as string;
    // Verify signature logic here

    const event = request.body as any;
    if (event.event === 'participant_joined' && event.participant.attributes?.sip) {
      const dialedNumber = event.participant.attributes.sip.dialedNumber;
      const caller = event.participant.attributes.sip.phoneNumber;
      const sipIdentity = event.participant.identity;

      const { db } = await createDatabaseClient();
      const mapping = await db.select().from(inboundMappings).where(eq(inboundMappings.phoneNumber, dialedNumber)).limit(1);

      if (mapping.length > 0) {
        const { tenantId, workflowId } = mapping[0];
        await workflowEngine.startWorkflow(tenantId, workflowId, {
          isInbound: true,
          roomName: event.room,
          sipIdentity,
          callerPhoneNumber: caller,
          dialedNumber
        }, WorkflowType.SERVER);
      }
    }

    reply.status(200).send({});
  });
};
and then inside
startWorkflow
Copy code
this.config.roomName = inputs.roomName as string;
        agentMetadata.participantIdentity = inputs.sipIdentity as string;
        agentMetadata.isInbound = true;
        await this.createExplicitDispatch(agentMetadata);
        return { status: ExecutionStatus.PENDING, output: {
          roomName: this.config.roomName,
          agentName: agentName ?? this.config.agentName,
          participantToken: await this.createTokenWithAgentDispatch(participantIdentity, agentMetadata),
          participantIdentity,
          phoneNumber,
          executionId: this.context.executionId
        }, resumeExecutionId: resumeExecutionId, triggeredOutputPorts: [], creditsUsed: 0 };
workers in my case don't have context and nuances of each specific workflow. Alternative solution I am considering is having an livekit worker, who will call my server to get the context before creating an agent, but this is not ideal , as I am losing control from server side.
t
Thanks for reaching out, Dmitry. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
You can use LiveKit server APIs to programmatically dispatch an agent to a room based on custom logic triggered from a webhook, such as routing by phone number and passing context-specific metadata. Key points for your scenario: • Explicit Agent Dispatch: Use the
AgentDispatchClient
(Node.js) or
AgentDispatchService
(Python) to create a dispatch for an agent, including custom metadata like phone number and workflow context. This can be triggered directly from your webhook handler. • Server-Side Token Generation: You can generate participant tokens server-side and include agent dispatch instructions and metadata in the token payload. • Custom Metadata: The
metadata
field accepts JSON, so you can pass structured data (e.g., phone number, workflow ID, tenant ID) to the agent. • Webhook Integration: Your webhook can analyze the incoming event, determine the correct agent and context, and then use the dispatch API to add the agent to the room with all necessary metadata. • Room Creation: If the room does not exist, it will be created automatically during dispatch. • Agent Requirements: The agent must be registered with an
agentName
in your worker configuration to be eligible for dispatch. This approach gives you full server-side control over agent selection and context, without requiring the worker to fetch context from your server. The agent can access the custom metadata via the
JobContext
when handling the dispatch. Example (Node.js):
Copy code
const agentDispatchClient = new AgentDispatchClient(process.env.LIVEKIT_URL);
await agentDispatchClient.createDispatch(roomName, agentName, {
  metadata: JSON.stringify({
    phoneNumber: dialedNumber,
    context: 'support',
    tenantId,
    workflowId
  })
});
This pattern matches your described workflow and is fully supported by LiveKit's APIs. Sources: packages/livekit-server-sdk/src/AgentDispatchClient.ts | examples/agent_dispatch.py | client/web/src/app/api/connection-details/route.ts | ivr-nagivator/flask_livekit/extension.py | Agent dispatch | LiveKit Docs