UnifyPort のメディア送信:URL と配信結果のトラブルシューティング
UnifyPort で画像、動画、音声、文書を送信するには、POST /v1/messages に対応する message.type を指定し、message.url、message.file_url、message.file_key の少なくとも一つに空でないソースを設定します。URL は絶対 HTTP(S) URL が必要です。ローカルのファイル名は取得可能な URL ではなく、レスポンスの status: accepted も受信者への配信完了を意味しません。
要点
- メディア形式を有効にする前に、メッセージングアカウントのチャネル対応を確認します。
- まずは取得可能な URL を一つ指定し、複数ソースの優先順位を推測しません。
- 送信側の
messageと受信側のdata.message.attachments[]は別の構造です。 - ファイル取得、リクエスト検証、アカウント接続、配信結果を分けて調べます。
最初に送信 API の契約を確認する
UnifyPort の非公式インターフェースは、メディア送信リファレンスに従います。LINE Messaging API や Telegram Bot API とは別の API です。Telegram のファイル送信仕様には、ファイル識別子、HTTP URL、multipart アップロードが記載されています。しかし、それを根拠に Telegram の file_id を UnifyPort の file_key として使ったり、同じアップロード形式を使ったりすることはできません。
| 入力 | UnifyPort の文書で確認できる内容 |
|---|---|
message.type | image、video、audio、document、file。チャネルごとの対応確認も必要 |
message.url または message.file_url | 空でない絶対 HTTP(S) URL |
message.file_key | 文書化された別のソース指定。キーやアップロードエンドポイントを自作する根拠にはならない |
message.caption | 画像、動画、文書、ファイルで任意指定 |
provider_data.seconds | WhatsApp の音声・動画で任意指定する、秒単位の非負整数 |
WhatsApp 動画の時長の範囲は 0–4294967295 です。provider_data.waveform は音声専用です。受信データの duration_ms を秒数へそのままコピーしないでください。不要なメタデータは推測せず省略します。
現在の送信対応表では、TikTok の音声と文書・ファイル送信は未対応、X の音声は部分対応です。whatsapp-protocol と whatsapp も別々に記載されています。LINE を中心とした実装でも、別チャネルへの展開時には形式ごとに確認してください。共通エンドポイントは、同一機能や同一制限の保証ではありません。
リクエストを作る前にファイルを準備する
以下はアプリケーション設計の推奨事項であり、追加のプラットフォーム保証ではありません。
- 操作者が選択したアカウントから対象会話へ送信できることを確認します。グループでは投稿者 ID ではなく、会話 ID と種別を使います。
- 認証状態と
runtime_statusを別々に確認します。認証済みでも接続中とは限りません。 - 正しいファイルを管理下の取得可能なソースへ配置します。ブラウザーでログイン後に開けるページだけでは、送信サービスが取得できる証拠になりません。
- ブラウザーの Cookie を使わない別サーバー環境で取得を確認し、HTML のログイン画面やエラーページではなく、目的のメディアが返るか調べます。
- 有効期限付き URL は、想定するキュー待機と取得時間を考慮して発行します。送信仕様に一律の取得期限はなく、事前確認の成功も後の取得を保証しません。
HTTPS、必要最小限のアクセス、アプリケーションが承認したストレージを推奨します。署名付きクエリや認証情報はログに残さないでください。これは安全な設計の提案であり、UnifyPort の非公開ネットワーク制御についての説明ではありません。
URL ベースの送信リクエストを作る
次の JavaScript 関数は、選択済みアカウント、会話、承認済み URL からリクエスト本文を作ります。アップロードも到達性確認も行いません。呼び出す前に、チャネル対応と操作権限を確認してください。
function buildMediaRequest({ accountId, conversation, type, url, caption }) {
const types = new Set(['image', 'video', 'audio', 'document', 'file']);
if (!accountId || !conversation?.id || !conversation?.type) {
throw new Error('Account and conversation are required');
}
if (!types.has(type)) throw new Error('Unsupported media type');
const source = new URL(url);
if (!['http:', 'https:'].includes(source.protocol) ||
source.username || source.password) {
throw new Error('Use an approved HTTP(S) media source');
}
const message = { type, url: source.href };
if (caption !== undefined) {
if (type === 'audio' || typeof caption !== 'string') {
throw new Error('Caption is not valid for this request');
}
message.caption = caption;
}
return {
account_id: accountId,
to: { id: conversation.id, type: conversation.type },
message,
};
}
生成した JSON を POST /v1/messages へ送ります。X-Api-Key による認証はサーバー側で行い、Content-Type: application/json を指定してください。この関数は意図的に message.url だけを設定しています。文書は少なくとも一つのソースを要求していますが、競合するソースの優先順位は示していません。
受信した添付オブジェクトを、そのまま送信本文へ貼り付けないでください。受信メディアのマッピングガイドにある attachments[].type、url、mimetype などは受信フィールドであり、送信リクエスト全体ではありません。元の URL が失効している場合は、ダウンロードリンクの復旧ガイドで利用中の API に合った復旧方法を確認してから転送を検討します。
失敗した段階ごとに調べる
| 状況 | 次の確認 | 避けること |
|---|---|---|
ローカルパス、相対 URL、data: URL を指定した | 絶対 HTTP(S) URL を準備 | パスを file_key と呼び替える |
| 自分のブラウザーだけで開ける | 認証依存、有効期限、リダイレクト、実際のレスポンス | ブラウザーセッションが送信側にも渡ると考える |
unsupported_message_type | チャネルとメディア形式の組み合わせ | 同じリクエストの繰り返し |
provider_not_ready | 認証と実行状態 | 調査せずに認証をやり直す |
| タイムアウト | 送信操作の記録を保持し、不確定な結果を調査 | 重複し得る自動再送 |
accepted が返った | 返された識別子を保存し、対応する配信証拠を別途確認 | 即座に配信済み・既読と表示 |
エラーリファレンスの機械可読コードで分岐し、説明文の推測に頼らないでください。request_id は診断用に保存しますが、重複排除のトークンではありません。リクエスト追跡ガイドでその違いを確認できます。
配信通知を扱う場合は、イベント仕様とチャネル別対応表を確認し、webhook 署名を検証して、重複や順序の前後に対応します。すべてのチャネルがすべての通知を出すわけではありません。確認がなければ不明のまま保持し、再送の根拠にしないでください。
受け入れ確認と FAQ
本番前には、取得可能なファイル、期限切れ URL、ログイン画面の応答、未対応の形式、切断中のアカウント、送信レスポンス消失をテスト項目に含めます。本記事は、これらの実環境テストを実施済みとは述べていません。
この JSON でローカルファイルを直接アップロードできますか?
文書化されたリクエストは URL またはファイルキーを使います。本記事は multipart アップロード用エンドポイントの存在を示すものではありません。承認されたストレージ経由でファイルを配置し、取得可能な URL を使ってください。
Telegram の file_id を file_key にできますか?
その互換性は文書化されていません。Telegram 固有の識別子と UnifyPort のソースフィールドは分けて扱います。
accepted はファイルが相手に届いたという意味ですか?
いいえ。受付を示すだけで、配信通知や既読通知ではありません。
次のステップと参照資料
画像・ファイル送信ガイドに沿って、承認済みのテスト会話とメディアソースを一つずつ確認してから、キュー送信や自動化を有効にしてください。
参照確認日:2026-10-09。
メッセージ連携を安定したプロダクトパイプラインへ。
まずは 1 つの API で送信を始め、標準イベントですべての inbound メッセージを業務システムへ戻しましょう。