メインコンテンツへスキップ
Tech·AI
公開日: 2026/5/1

音声メモを自動で文字起こし&整形するDiscord Botを作った

音声メモを自動で文字起こし&整形するDiscord Botを作った
目次
  1. 思いついた瞬間に、外に出す
  2. 録音→アップロード、あとはBotが全部やる
  3. 話し言葉はそのままより、整形してから渡す
  4. 文字起こしにRunPodを使う理由
  5. ファイルで返すと、そのまま実装依頼になる
  6. 24時間動かすための設定
  7. ローカル開発中は .env ファイルで管理しますが、本番環境(RailwayやFly.io)ではダッシュボードの環境変数設定画面から入力します。
  8. 帰宅したら実装が始められる状態になっていた

散歩中に急にアイデアが浮かんで、でも手が塞がっていてメモできない——そういう経験、ありませんか。

スマホを取り出してメモアプリを開いて、歩きながらタイプして……というのが想像以上に面倒なんですよね。信号で止まるたびに少しずつ書いていって、気がついたら何を言いたかったのか忘れている。

「じゃあ音声メモを使えばいい」というのはその通りで、スマホの録音アプリでもワイヤレスイヤホンでも録音自体はできます。

ただそこで止まるんです。録音した音声が、そのまま作業に繋がらない。

帰宅してから音声を聞き直して、メモを打ち直して、それをClaude CodeやCodexに渡せる形に整えて——そこまでやって初めてアイデアが「使えるもの」になります。

今回紹介するのは、その整理を自動でやってしまう仕組みです。

Discordの指定チャンネルに音声ファイルを投げると、1〜2分後に整理済みMarkdownが返ってくる。そのファイルをそのままClaude Codeに貼り付けて「これを実装して」と言えば始められる——それだけのことですが、とても便利な自動化です。


記事全体の解説図

思いついた瞬間に、外に出す

少し前の記事で、Discordを使って作業ログを毎朝届ける仕組みを作りました。

この仕組みは「後から振り返る」ためのものでした。昨日のコミットログをAIが整理して、朝に届けてくれる。「昨日何をやったんだっけ」という感覚を解消するためのフローです。

今回の音声Botは、その逆向きです。「今ここで浮かんだことを、その場で外に出す」ための仕組み。

頭の中のアイデアをその場で言葉にして、整理された状態でシステムに渡す——という流れを、録音してアップロードするだけに絞り込む。それがこのBotの役割です。


録音→アップロード、あとはBotが全部やる

録音からClaude Codeへの4ステップフロー

4つのステップです。

  1. 録音: スマホで歩きながら5分でも1時間でも、考えていることを話す
  2. アップロード: 帰宅したら(あるいは移動中に)Discordの指定チャンネルに音声ファイルを投げる
  3. 変換: BotがRunPod(GPUサーバー)で音声を文字起こし → Claudeが構造化されたMarkdownに整形する
  4. 利用: Discordに返ってきた .md ファイルを、そのままClaude CodeやCodexに渡して実装を依頼する

音声を投げたら、あとはBotが全部やってくれます。自分がやることは「録音して、アップロードして、返ってきたファイルを使う」だけ。


この「投げたらすぐ返ってくる」という体験を実現しているのが、Botの常駐構造です。

Botはバックグラウンドで起動し続けながら、WebSocket(常時接続の通信経路)でDiscordのイベントを受け取り続けています。音声ファイルがアップロードされた瞬間にイベントが届いて、その場で処理を起動できる。

定期実行型が「決まった時間に動く」のに対して、都度実行型が「何かあった瞬間に動く」理由はここにあります。

話し言葉はそのままより、整形してから渡す

Whisper→Claudeの2段階整形フロー

一番シンプルな実装は「音声ファイルをOpenAI Whisper APIに送って、返ってきたテキストをそのままDiscordに貼る」です。それでも一応は動きます。

ただ、せっかくなら整形したいですね。

Whisperが返すのは、音声の内容をそのままテキストにしたものです。「えーと」「あのー」「ちょっとそこはどうしようかな」——口語のまま、言い淀みも全部残った状態になっています。

別にそのままClaude Codeに渡しても動きます。でも読みにくいし、指示としての精度も落ちる。

だからこのBotは2段階の処理をしています。

第1段階: Whisperで文字起こし(RunPod) 音声をそのまま文字起こしする。

第2段階: Claudeで整形(Claude API) 口語テキストをMarkdownに整理する。タイトル・概要・タスクリスト・注意事項に分けて、Claude CodeやCodexに渡せる「指示書」の形にする。

const SYSTEM_PROMPT = `あなたは音声で話された開発者の指示を、AIコーディングアシスタントが利用しやすい構造化されたMarkdown指示書に変換するアシスタントです。

ルール:
- 内容を端的に表すタイトル(# 見出し)を冒頭につける
- 概要・タスク・注意事項などのセクションに適切に分割する
- 実行すべきタスクはチェックボックス(- [ ])で記述する
- ファイル名・関数名・コマンドはバッククォートで囲む
- コード片はコードブロックで囲む
- Markdownのみを出力する`;

話し言葉で録った内容が、AIに渡せる実装の仕様書に変わって返ってくる——そのギャップを埋めるのがこのプロンプトの役割です。


文字起こしにRunPodを使う理由

正直に言うと、個人の音声メモを処理するだけなら、OpenAI Whisper APIで十分です。

公式の料金は $0.006/分で、5分の音声を毎日処理しても月$0.90(約135円)。節約のためにわざわざ別のサービスを使う必要はありません。

それでもRunPodを選んだのは、2つの理由があります。

ひとつは、将来の用途を見越してのことです。今は個人の散歩中のメモですが、これが週に何度かの打ち合わせや、数時間のログ処理に広がっていく可能性があります。

そういう規模になってくると、コストの差が効いてきます。RunPodはGPUを動かした時間だけの課金なので、同じ量を処理してもOpenAI APIより大幅に安く抑えられます。Faster-Whisperを使った場合は3〜4倍程度のコスト削減になるとRunPodは述べています。

具体的には、RTX 4000クラスのGPUで$0.00016/秒程度。5分の音声の処理時間は20〜30秒程度なので、1回あたり$0.003〜0.005。OpenAI APIの同じ音声(5分×$0.006=$0.03)と比べると6〜10倍の差になります(GPU種別と処理時間による)。

もうひとつは、RunPodの使い方を覚えておきたかったから。GPUをオンデマンドで使う仕組みは、Whisperに限らず他の処理にも応用できます。今のうちにフローを理解しておくという意味合いが大きいです。

RunPodは「ジョブを投げて、完了したら取りに行く」という非同期の仕組みで動きます。OpenAI APIのように「送ったらすぐ返ってくる」ではなく、処理番号(ジョブID)をもらって、定期的に「もう終わった?」と確認する形です。

// 音声を送ってジョブIDをもらう
const { id: jobId } = await submitToRunPod(audioBuffer);

// 完了するまで5秒おきに確認する(最大300秒待つ)
for (let i = 0; i < 60; i++) {
  await sleep(5_000);
  const result = await checkJobStatus(jobId);
  if (result.status === "COMPLETED") return result.transcription;
  if (result.status === "FAILED") throw new Error("RunPod job failed");
}

10分の音声でも大抵1分以内に返ってきます。


ファイルで返すと、そのまま実装依頼になる

処理が終わったら、結果をDiscordのメッセージとして返すのが自然な流れです。ただ、このBotはMarkdownを .md ファイルとして添付して返します。

理由はDiscordのテキスト制限です。メッセージ1件あたり2,000文字の上限があって、10分の音声を文字起こし・整形した内容は軽く超えます。ファイルなら制限がありません。

実際のコードはこんな形です。MarkdownのテキストをUTF-8のバイナリに変換して、Discordのファイル添付として送っています。

function buildReplyPayload(markdown: string, filename: string): MessageReplyOptions {
  const attachment = new AttachmentBuilder(Buffer.from(markdown, "utf-8"), {
    name: filename,
  });
  return {
    content: "📝 文字起こしが完了しました",
    files: [attachment],
  };
}

24時間動かすための設定

このBotはDiscordのイベントを常時監視している必要があるので、どこかのサーバーで24時間起動し続ける必要があります。

RailwayかFly.ioあたりがよくある選択肢です。どちらもDockerfileをプロジェクトルートに置けば、あとはリポジトリを接続してボタンを押すだけで動き始めます。月$5〜10(700〜1,500円程度)の費用感です。

RailwayとFly.ioの違い

Railway: GitHubリポジトリを接続すればDockerfileなしでも自動検出してデプロイできる。設定がシンプルで、従量課金制(月$5〜)。

Fly.io: 世界35拠点以上にデプロイでき、リージョン選択やスケーリングを細かく制御できる。VM設定が必要で、VMは$2〜/月の従量課金で、実用最小構成では月$7〜10程度。

どちらも無料枠はないので、ずっと起動し続けるBotは実費がかかります。

設定が必要なのは大きく4種類です。Discord BotのトークンとチャンネルID、RunPodのAPIキーとエンドポイントID、Claude APIのキー、それだけです。

ローカル開発中は .env ファイルで管理しますが、本番環境(RailwayやFly.io)ではダッシュボードの環境変数設定画面から入力します。

帰宅したら実装が始められる状態になっていた

このBotを動かしてから、移動時間の使い方が変わりました。

以前は「考えたことをメモする」という作業が別に必要でした。思考と記録が分離していた。

今は歩きながら考えたことを喋って、後でアップロードするだけ。Discordを確認したらMarkdownが届いていて、それをClaude Codeに貼り付けて実装を始められる。

思考と実装の間にあった「整理」という手作業が、ほぼなくなっています。

毎朝届く作業ログと組み合わせると、「昨日やったことの振り返り」と「今日やりたいことのインプット」が両方Discordで揃う状態になります。

将来的には、このBotをClaude Code APIと直接繋いで、Discordにアップロードした音声が自動で実装まで走る——という構成も視野に入ります。Hermes AgentやOpenClawが目指している「エージェントが自律的に動く」世界は、実はこういう自前Botの延長線上にあります。

RELATED ARTICLES

関連記事

ryryo

Author

ryryo

CODENOTEの管理人。Web開発・AI・デザインについて発信しています。

この記事をシェア