Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions public/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ peerConnection.ontrack = (event) => {
document.body.appendChild(el);
};

const dataChannel = peerConnection.createDataChannel('response');
const dataChannel = peerConnection.createDataChannel('oai-events');

function configureData() {
console.log('Configuring data channel');
Expand Down Expand Up @@ -137,22 +137,30 @@ navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {

peerConnection.createOffer().then((offer) => {
peerConnection.setLocalDescription(offer);
fetch('/session')
.then((tokenResponse) => tokenResponse.json())
.then((data) => {
const EPHEMERAL_KEY = data.result.client_secret.value;
const baseUrl = 'https://api.openai.com/v1/realtime';
const model = 'gpt-4o-realtime-preview-2024-12-17';
fetch(`${baseUrl}?model=${model}`, {
method: 'POST',
body: offer.sdp,
headers: {
Authorization: `Bearer ${EPHEMERAL_KEY}`,
'Content-Type': 'application/sdp',
},
})
.then((r) => r.text())
.then((answer) => {
// Accept answer from Realtime WebRTC API
peerConnection.setRemoteDescription({
sdp: answer,
type: 'answer',
});
});
});

// Send WebRTC Offer to Workers Realtime WebRTC API Relay
fetch('/rtc-connect', {
method: 'POST',
body: offer.sdp,
headers: {
'Content-Type': 'application/sdp',
},
})
.then((r) => r.text())
.then((answer) => {
// Accept answer from Realtime WebRTC API
peerConnection.setRemoteDescription({
sdp: answer,
type: 'answer',
});
});
});
});
40 changes: 17 additions & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
import { Hono } from 'hono';
import { cors } from 'hono/cors';

const app = new Hono<{ Bindings: Env }>();
app.use(cors());

const DEFAULT_INSTRUCTIONS = `You are helpful and have some tools installed.

In the tools you have the ability to control a robot hand.
`;

app.post('/rtc-connect', async (c) => {
const body = await c.req.text();
const url = new URL('https://api.openai.com/v1/realtime');
url.searchParams.set('model', 'gpt-4o-realtime-preview-2024-12-17');
url.searchParams.set('instructions', DEFAULT_INSTRUCTIONS);
url.searchParams.set('voice', 'ash');

const response = await fetch(url.toString(), {
method: 'POST',
body,
// Learn more: https://platform.openai.com/docs/api-reference/realtime-sessions/create
app.get('/session', async (c) => {
const response = await fetch("https://api.openai.com/v1/realtime/sessions", {
method: "POST",
headers: {
Authorization: `Bearer ${c.env.OPENAI_API_KEY}`,
'Content-Type': 'application/sdp',
"Authorization": `Bearer ${c.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
});

if (!response.ok) {
throw new Error(`OpenAI API error: ${response.status}`);
}
const sdp = await response.text();
return c.body(sdp, {
headers: {
'Content-Type': 'application/sdp',
},
});
body: JSON.stringify({
model: "gpt-4o-realtime-preview-2024-12-17",
instructions: DEFAULT_INSTRUCTIONS,
voice: "ash",
}),
});
const result = await response.json();
return c.json({result});
});


export default app;