Noesis / Integrations
Plivo
Stream a Plivo call to Noesis with the Stream XML element and a stream token, and receive the answers through a relay.
Plivo's <Stream> element sends a call's audio to a WebSocket. Noesis reads Plivo's media messages as they are. Plivo cannot send an Authorization header to Noesis, so put a stream token in the URL.
1. Stream the call to Noesis
Ask Plivo for μ-law at 8 kHz and set the same format on the URL. In XML, write each & in the URL as &:
<Response>
<Stream bidirectional="false" audioTrack="inbound" contentType="audio/x-mulaw;rate=8000">wss://api.noesis.detectif.ai/v1/detect/stream?token=ntk_...&encoding=mulaw&sample_rate=8000</Stream>
<!-- your existing call flow continues here -->
</Response>Create the token in your answer webhook, right before you return the XML, as in the Twilio guide. To not record the call, add &record=false to the URL.
2. Receive the answers during the call
Plivo does not pass messages from the stream back to you. To act on the answers, point the stream at a relay on your server, which forwards Plivo's messages to Noesis unchanged and receives the answers:
<Response>
<Stream bidirectional="false" audioTrack="inbound" contentType="audio/x-mulaw;rate=8000">wss://relay.example.com/plivo</Stream>
<!-- your existing call flow continues here -->
</Response>The relay uses noesis_relay.py from the relay helper:
# plivo_relay.py: Plivo Stream -> your server -> Noesis
import asyncio
import websockets
from noesis_relay import NoesisCall
async def on_answer(event):
if event["type"] == "classification":
print(event["call_id"], event["label"]) # your own logic; call_id is Plivo's call ID
async def handle(plivo):
call = NoesisCall(on_answer, encoding="mulaw", sample_rate=8000)
await call.open()
try:
async for message in plivo: # Plivo's JSON messages, unchanged
await call.send(message)
except websockets.ConnectionClosed:
pass
await call.close()
async def main():
async with websockets.serve(handle, "0.0.0.0", 8080):
await asyncio.Future() # run until stopped
asyncio.run(main())If you choose 16-bit PCM in contentType (audio/x-l16;rate=8000 or audio/x-l16;rate=16000), set encoding="pcm_s16le" and the same sample_rate.