diff --git a/backend/src/voice/voice.controller.ts b/backend/src/voice/voice.controller.ts
index 17ed440..15178ed 100644
--- a/backend/src/voice/voice.controller.ts
+++ b/backend/src/voice/voice.controller.ts
@@ -164,25 +164,40 @@ export class VoiceController {
this.logger.log(`Full body: ${JSON.stringify(body)}`);
try {
- // Extract tenant domain from phone number mapping
- // For now, we'll need to determine which tenant owns this phone number
- // TODO: Add phone number to tenant mapping in database
+ // Extract tenant domain from Host header
+ const host = req.headers.host || '';
+ const tenantDomain = host.split('.')[0]; // e.g., "tenant1" from "tenant1.routebox.co"
- // For multi-tenant, we need to route to the correct user's browser Device
- // The Device identity is the userId we used when generating the access token
+ this.logger.log(`Extracted tenant domain: ${tenantDomain}`);
+
+ // Get all connected users for this tenant
+ const connectedUsers = this.voiceGateway.getConnectedUsers(tenantDomain);
- // For now, let's dial ALL connected clients (you can refine this later)
- // Using a simple approach: dial the most recently connected user
+ this.logger.log(`Connected users for tenant ${tenantDomain}: ${connectedUsers.length}`);
+
+ if (connectedUsers.length === 0) {
+ // No users online - send to voicemail or play message
+ const twiml = `
+
+ Sorry, no agents are currently available. Please try again later.
+
+`;
+ this.logger.log(`No users online - returning unavailable message`);
+ return res.type('text/xml').send(twiml);
+ }
+
+ // Build TwiML to dial all connected clients (first to answer gets the call)
+ const clientElements = connectedUsers.map(userId => ` ${userId}`).join('\n');
const twiml = `
Connecting your call
-
- e6d45fa3-a108-4085-81e5-a8e05e85e6fb
+
+${clientElements}
`;
- this.logger.log(`Returning inbound TwiML - dialing Client`);
+ this.logger.log(`Returning inbound TwiML - dialing ${connectedUsers.length} client(s)`);
res.type('text/xml').send(twiml);
} catch (error: any) {
this.logger.error(`Error generating inbound TwiML: ${error.message}`);
diff --git a/backend/src/voice/voice.gateway.ts b/backend/src/voice/voice.gateway.ts
index 231effc..cf7daba 100644
--- a/backend/src/voice/voice.gateway.ts
+++ b/backend/src/voice/voice.gateway.ts
@@ -290,4 +290,20 @@ export class VoiceGateway
socket.emit('ai:action', data);
}
}
+
+ /**
+ * Get connected users for a tenant
+ */
+ getConnectedUsers(tenantDomain?: string): string[] {
+ const userIds: string[] = [];
+
+ for (const [userId, socket] of this.connectedUsers.entries()) {
+ // If tenantDomain specified, filter by tenant
+ if (!tenantDomain || socket.tenantSlug === tenantDomain) {
+ userIds.push(userId);
+ }
+ }
+
+ return userIds;
+ }
}