Dela via


Använda GPT Realtime-API:et via SIP

Azure OpenAI GPT Realtime API för tal och ljud är en del av GPT-4o-modellfamiljen som stöder konversationsinteraktioner med låg svarstid, "tal in, tal ut".

Du kan använda Realtids-API:et via WebRTC, SIP eller WebSocket för att skicka ljudindata till modellen och ta emot ljudsvar i realtid. Följ anvisningarna i den här artikeln för att komma igång med REALTIDS-API:et via SIP.

SIP är ett protokoll som används för att ringa telefonsamtal via Internet. Med SIP och Realtids-API:et kan du dirigera inkommande telefonsamtal till API:et.

Modeller som stöds

GPT-realtidsmodellerna är tillgängliga för globala distributioner i regionerna USA, östra 2 och Sverige, centrala.

  • gpt-4o-mini-realtime-preview (2024-12-17)
  • gpt-4o-realtime-preview (2024-12-17)
  • gpt-realtime (version 2025-08-28)
  • gpt-realtime-mini (version 2025-10-06)

Förutsättningar

Innan du kan använda GPT-realtidsljud behöver du:

Ansluta till SIP

Om du vill ansluta ett telefonnummer till API:et för realtid använder du en SIP-trunkeringsprovider (till exempel Twilio). En trunkeringsprovider är en tjänst som konverterar ditt telefonsamtal till IP-trafik. När du har köpt ett telefonnummer från din SIP-trunkeringsleverantör följer du anvisningarna som visas här.

Börja med att skapa en webhook för inkommande samtal med Azure OpenAI Webhook Service. Vi har ett REST-API som gör att du kan skapa, uppdatera, visa och ta bort webhook-slutpunkter.

Peka sedan din SIP-trunk mot Azure OpenAI SIP-slutpunkt genom att använda det interna ID för din Azure-resurs. Exempel:

  • Hämta internt ID för din Azure Open AI-resurs. Du hittar det interna ID:t genom att klicka på resursens JSON View .
  • Ditt projekt-ID = "proj_<internalId>" Det kan se ut så här "proj_88c4a88817034471a0ba0fcae24ceb1b"

Dina sip-inbjudningar använder det här projekt-ID:t som användare: till exempel sip:proj_88c4a88817034471a0ba0fcae24ceb1b@<region>.sip.ai.azure.com;transport=tls.

De regioner som för närvarande stöds är swedencentral och eastus2.

Hantera inkommande samtal

När Azure OpenAI tar emot SIP-trafik som är associerad med projektet tar webhookens slutpunkt emot ett inkommande händelsemeddelande. Händelsen som utlöstes för sip-anrop har typen = realtime.call.incoming, precis som i exemplet som visas här.

POST https://my_website.com/webhook_endpoint
user-agent: OpenAI/1.0 (+https://platform.openai.com/docs/webhooks)
content-type: application/json
webhook-id: wh_685342e6c53c8190a1be43f081506c52 # unique ID for idempotency
webhook-timestamp: 1750287078 # timestamp of delivery attempt
webhook-signature: v1,Signature # signature to verify authenticity from OpenAI

{
  "object": "event",
  "id": "evt_685343a1381c819085d44c354e1b330e",
  "type": "realtime.call.incoming",
  "created_at": 1750287018, // Unix timestamp
  "data": {
    "call_id": "some_unique_id",
    "sip_headers": [
      { "name": "From", "value": "sip:+142555512112@sip.example.com" },
      { "name": "To", "value": "sip:+18005551212@sip.example.com" },
      { "name": "Call-ID", "value": "rtc_xyz"}
    ]
  }
}

Från webhooksslutpunkten kan du acceptera, avvisa eller referera till det här anropet med hjälp av värdet call_id från webhook-händelsen. När du godkänner samtalet anger du den konfiguration som behövs (instruktioner, röst osv.) för API-sessionen i realtid. När du har upprättat kan du konfigurera en WebSocket och övervaka sessionen som vanligt. API:erna för att acceptera, avvisa, övervaka, referera till och lägga på samtalet dokumenteras i följande avsnitt.

Acceptera samtalet

Använd slutpunkten Acceptera samtal för att godkänna det inkommande anropet och konfigurera den realtidssession som besvarar det. Skicka samma parametrar som du skulle använda för att skapa en klienthemlighet. Du kan inkludera alla värden som du skulle använda i ett session.update-meddelande, men typ, modell och instruktioner är obligatoriska.

Anmärkning

För auktorisering kan du antingen använda api-nyckelrubriken eller ägartoken som visas här. Kom ihåg att modellnamnet faktiskt är namnet på distributionen.

curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/accept" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "type": "realtime",
        "model": "gpt-realtime",
        "instructions": "You are Alex, a friendly concierge for Example Corp."
      }'

Sökvägen för begäran måste innehålla

  • Call_id från webhook-händelsen realtime.call.incoming
  • Auktoriseringsrubrik (eller api-nyckel)

Slutpunkten returnerar 200 OK när SIP-benet ringer och realtidssessionen upprättas.

Avvisa anropet

Använd slutpunkten Avvisa anrop för att avvisa en inbjudan när du inte vill hantera det inkommande samtalet (till exempel från en landskod som inte stöds.) Om du vill kontrollera svaret som skickas tillbaka till transportföretaget anger du en valfri SIP-statuskod tillsammans med den nödvändiga call_id sökvägsparametern. Exemplet här visar en begäran som skickar 486, vilket indikerar att systemet är för upptaget för att ta samtalet.

curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/reject" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"status_code": 486}'

Om ingen statuskod anges skickar sip-servern statuskoden 603 till kunden som en del av avvisa-meddelandet. En lyckad begäran svarar med 200 OK när OpenAI har levererat SIP-svaret.

Omdirigera anropet

Överför ett aktivt anrop med hjälp av referensanropets slutpunkt. Ange call_id och target_uri som ska placeras i SIP-Refer-To-huvudet (till exempel +14155550123 eller sip:agent@example.com).

curl -X POST "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/refer" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"target_uri": "tel:+14155550123"}'

OpenAI returnerar 200 OK när REFER vidarebefordras till SIP-providern. Det underordnade systemet hanterar resten av samtalsflödet för anroparen.

Övervaka samtalshändelser och utfärda sessionskommandon och uppdateringar

När du har accepterat ett anrop öppnar du en WebSocket-anslutning till samma session för att strömma händelser och utfärda API-kommandon i realtid. Om du vill skapa en websocket till ett befintligt anrop måste du använda parametern call_id. Modellargumentet används inte eftersom det är konfigurerat som en del av json när anropet godkänns. Exemplet här visar ett vanligt scenario där meddelandet "response.create" utfärdas för att instruera REALTIDS-API-systemet att "svara i telefonen och säga hej".

Här är ett exempel på en WebSocket-begäran till ett specifikt SIP-anrop.

GET wss://<your azure resource name>.openai.azure.com/openai/v1/realtime?call_id={call_id}

Frågeparametrar

Parameter Typ Description
call_id snöre Identifikator från webhooken för realtime.call.incoming.

Headers

Auktorisering: Bearer $TOKEN (eller API-nyckel: ange din API-nyckel)

WebSocket fungerar exakt som alla andra realtids-API-anslutningar.

Du kan skicka meddelanden som "response.create" eller "session.update" för att styra anropet och lyssna efter serverhändelser som returneras för att spåra förloppet.

Följande kodfragment visar hur en websocket-anslutning görs.

import WebSocket from "ws";

const callId = "rtc_u1_9c6574da8b8a41a18da9308f4ad974ce";
const ws = new WebSocket(`wss://<your azure resource name>.openai.azure.com/openai/v1/realtime?call_id=${callId}`, {
    headers: {
        api-key: `${process.env.OPENAI_API_KEY}`,
    },
});

ws.on("open", () => {
    ws.send(
        JSON.stringify({
            type: "response.create",
        })
    );
});

Lägg på samtalet

Avsluta sessionen med slutpunkten Lägg på när programmet ska koppla från anroparen. Den här slutpunkten kan användas för att avsluta både SIP- och WebRTC-realtidssessioner.

curl -X POST "https://<your azure resoure name>.openai.azure.com/openai/v1/realtime/calls/$CALL_ID/hangup" \
  -H "Authorization: Bearer $TOKEN"
The API responds with 200 OK when it starts tearing down the call.

Exempel på webhook-slutpunkt

Följande kod är ett python-exempel på en realtime.call.incoming-hanterare. Det accepterar anropet och loggar sedan alla händelser från Api:et för realtid.

from flask import Flask, request, Response, jsonify, make_response
from openai import OpenAI, InvalidWebhookSignatureError
import asyncio
import json
import os
import requests
import time
import threading
import websockets

app = Flask(__name__)
client = OpenAI(
    webhook_secret=os.environ["OPENAI_WEBHOOK_SECRET"]
)

AUTH_HEADER = {
    "api-key": os.getenv("OPENAI_API_KEY")
}

call_accept = {
    "type": "realtime",
    "instructions": "You are a support agent.",
    "model": "gpt-realtime",
}

response_create = {
    "type": "response.create",
    "response": {
        "instructions": (
            "Say to the user 'Thank you for calling, how can I help you'"
        )
    },
}


async def websocket_task(call_id):
    try:
        async with websockets.connect(
            "wss://<your azure resource>.openai.azure.com/openai/v1/realtime?call_id=" + call_id,
            additional_headers=AUTH_HEADER,
        ) as websocket:
            await websocket.send(json.dumps(response_create))

            while True:
                response = await websocket.recv()
                print(f"Received from WebSocket: {response}")
    except Exception as e:
        print(f"WebSocket error: {e}")


@app.route("/", methods=["POST"])
def webhook():
    try:
        event = client.webhooks.unwrap(request.data, request.headers)

        if event.type == "realtime.call.incoming":
            requests.post(
                "https://<your azure resource name>.openai.azure.com/openai/v1/realtime/calls/"
                + event.data.call_id
                + "/accept",
                headers={**AUTH_HEADER, "Content-Type": "application/json"},
                json=call_accept,
            )
            threading.Thread(
                target=lambda: asyncio.run(
                    websocket_task(event.data.call_id)
                ),
                daemon=True,
            ).start()
            return Response(status=200)
    except InvalidWebhookSignatureError as e:
        print("Invalid signature", e)
        return Response("Invalid signature", status=400)


if __name__ == "__main__":
    app.run(port=8000)

Nästa steg

Nu vet du hur du får ett samtal anslutet via SIP. Nästa steg är att skapa dina programprompter i realtid för att servera dina kunder.