元々のブログ投稿: https://lazy.bearblog.dev/go-mime-wtf/
ある週末、私は ToDo リストや買い物リストを自動化するために自分用の Telegram ボットを作成することにしました。
アイデアはシンプルです。購入するアイテムのリストをボットに送信すると、片手に携帯電話を持ち、もう一方の手に買い物かごを持った状態で、チェックボックスをオンにできるチェックボックスを含む Web ページが作成されます。
ボットはかなり早く書かれましたが、その後、OpenAI の Whisper モデルを試してみたくなりました。そこで、アプリケーションに音声認識を追加することにしました。
これで、プログラムは次のように動作します:
さて、記事について。 go-openai では、openai.AudioRequest 構造体を使用してオーディオを送信できます。これにより、Reader フィールドにオーディオ データ ストリームを指定するか、FilePath フィールドにファイル パスを指定できます。これらのフィールドは相互に排他的だと思っていましたが、オーディオ ストリームを使用する場合でも FilePath を指定する必要があることがわかりました。 API はおそらくこれを使用してストリーム タイプを決定します。
Telegram 側では、MimeType フィールドを持つ tgbotapi.Voice 構造体を受け取ります。音声メッセージの場合は audio/ogg ですが、将来簡単に変更される可能性があります。
したがって、オーディオ ストリームの MIME タイプがわかったので、そこからファイル拡張子を決定し、OpenAI API が不明なファイル タイプについて文句を言わないようにファイル名を作成する必要があります。
コードは簡単そうに見えます:
ローカルでテスト - 動作します:
クラウドへのデプロイ - 機能しません:
ローカルとビルドに使用された CI/CD で Go のバージョンを確認すると、それらは同じです。
MIME パッケージの動作は決定的ではなく、実行時にオペレーティング システムに /etc/mime.types ファイルが存在するかどうかとその内容に依存することが判明しました。
ここで、MIME パッケージは MIME タイプとファイル拡張子のマッピングのランタイム テーブルを読み取ります。
私は本当に真剣です。バイナリをコンパイルし、すべてのテストを実行すると、すべてがうまくいっているように見えますが、このバイナリは、同じ MIME タイプに対して想定されるファイル拡張子を異なる環境で異なる方法で決定します。
オーディオ ファイルの既知の MIME タイプとその拡張子を取得し、mime.AddExtensionType を使用して init 関数に手動で追加しましょう。
これにより、アプリケーションの動作が、動作するドメイン (私の場合はオーディオ ファイル) に関して決定的になります。
この経験は、Go の物事が必ずしも決定的ではないことを示しました。何かが奇妙に思われる場合は、ためらわずにライブラリのソース コードを調べて、それがどのように実装されているかを確認してください。これにより、長期的には多くの時間とトラブルを節約できます。
以上がGo の「mime」パッケージの不確定性: 信頼するが検証するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。