👾

【リアルタイム音声通話】OpenAI Realtime APIとTwilioで実装する:とりあえず動かすための簡単ガイド

2024/10/07に公開

1. はじめに

本記事では、OpenAI Realtime API(以下 Realtime API)とTwilioを使ったリアルタイム音声通話の実装手順を解説します。

「Twilioを通して相手に電話をかけて、Realtime APIがその相手と話してくれる」ということをゴールとしてローカルで構築します。

2. 必要な環境と準備

●ツール・言語・ライブラリ:
Node.js(18.4.0) / Express.js(4.20.0):APIサーバーの構築
WebSocket:リアルタイム通信
ngrok:ローカルサーバーを外部公開
Google Apps Script (GAS):Twilioのアウトバウンド通話発信

●Twilioのアカウント設定
Twilioにサインアップし、アカウントSIDとAuthトークンと電話番号を取得します。
※ 発信元用の電話番号の取得は書類準備が手間なので、お試し用の電話番号を発行しましょう。ログイン後のトップページから1クリックで取得できます。
※ 発信先の電話番号を別途追加してください。検証環境からの発信先電話番号として登録が必要です。

●OpenAI APIの準備
OpenAIのアカウントを作成し、APIキーを取得します。

3. アーキテクチャとワークフローの全体像

この図では、以下の流れを示しています:

  1. Google Apps ScriptからTwilioへアウトバウンドコールのリクエストが送信されます。
  2. Twilioはngrok経由でExpress.jsにWebSocket接続を確立します。
  3. Express.jsはOpenAI APIと通信してリアルタイムで音声データを処理し、応答を返します。

4. プロジェクトのセットアップ

Expressサーバーのセットアップ

  1. Node.jsプロジェクトを初期化:
mkdir openai-twilio-call
cd openai-twilio-call
npm init -y
  1. 必要なパッケージをインストール:
npm install express ws axios
  1. Expressサーバーの基本セットアップ:
import express from 'express'
import http from 'http'
const app = express()
const server = http.createServer(app)

ngrokの設定と起動

  1. ngrokをダウンロードしてインストールします。
  2. ngrokのトンネルを作成:
ngrok http 3000
# ngrokのURLが生成されるので後で使います。

GASでTwilioのアウトバウンドコール
GASプロジェクトを作成し、以下のようにTwilioにリクエストを送るコードを作成します。

function makeTwilioCall() {
  const accountSid = 'YOUR_ACCOUNT_SID'
  const authToken = 'YOUR_AUTH_TOKEN'
  const fromPhoneNumber = 'YOUR_TWILIO_NUMBER'
  const toPhoneNumber = 'TO_PHONE_NUMBER'
  const twilioUrl = `https://api.twilio.com/2010-04-01/Accounts/${accountSid}/Calls.json`

  const payload = {
    From: fromPhoneNumber,
    To: toPhoneNumber,
    Twiml: `
      <Response>
        <Connect>
          <Stream url="wss://YOUR_NGROK_URL"/>
        </Connect>
      </Response>`
  }

  const options = {
    method: 'post',
    headers: {
      'Authorization': 'Basic ' + Utilities.base64Encode(accountSid + ':' + authToken),
    },
    payload: Object.keys(payload)
      .map(key => encodeURIComponent(key) + '=' + encodeURIComponent(payload[key]))
      .join('&')
  }

  const response = UrlFetchApp.fetch(twilioUrl, options)
  Logger.log(response.getContentText())
}

5. WebSocketの接続実装

WebSocketサーバーの追加

Express.jsにWebSocketを追加し、Twilioからの接続を受け付けます。

  1. WebSocket設定:
yarn add ws
import WebSocket from 'ws'
const wss = new WebSocket.Server({ server })

wss.on('connection', (connection) => {
  console.log('WebSocket connection established')
})

server.listen(3000, '0.0.0.0', () => {
  console.log(`Server is running on port 3000`)
})

OpenAI APIとの連携

WebSocketでの通信:Twilioからの音声データを受信し、Realtime APIと連携します。
Realtime APIのレスポンス処理:OpenAIからの応答をTwilioに返します。

----実装の詳細はまた今度書きます----

参考リンク

Twilio公式によるRealtime APIの使い方動画
Twilio media stream
OpenAI Realtime API公式docs

使った感想

  • 雑音に弱い
  • プロンプト調整難しい
  • gpt-3くらいの応答イメージ(応答精度や話し声など総合的な評価)

実装自体はWebSocketの仕組みがある程度分かればそこまで難しくないかと思います。

Discussion