0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Chatworkシリーズ #13】Chatwork APIのファイル機能、使ったことある? — アップロード/ダウンロードの実装と落とし穴

0
Last updated at Posted at 2026-03-20

Chatwork APIのメッセージ取得やタスク管理は使い倒してきた。が、「ファイル」のエンドポイントだけは長いこと素通りしていた。

理由は単純で、ファイル共有はSlackやGoogle Driveでやるもの、という先入観があったからだ。ところがチーム運用を自動化していく中で「定期レポートをChatworkのルームに自動配布したい」「ルームに上がったファイルを自動で別フォルダにバックアップしたい」という場面が出てきた。ファイルAPIの出番だった。

実際に触ってみたら、ダウンロードURLの有効期限30秒とか、アップロードの5MB制限とか、事前に知っておかないとハマる罠がいくつかある。順番に書いていく。

ファイル一覧を取得する

ルーム内のファイル一覧を取得するエンドポイント。

curl -s -H "X-ChatWorkToken: $TOKEN" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files"

レスポンスはこんな感じだ。

[
  {
    "file_id": 12345,
    "account": {
      "account_id": 99999,
      "name": "田中太郎",
      "avatar_image_url": "https://..."
    },
    "message_id": "67890",
    "filename": "report_2026_03.pdf",
    "filesize": 1048576,
    "upload_time": 1711000000
  }
]

filesizeはバイト単位。upload_timeはUnixタイムスタンプ。誰がいつ何をアップしたかが一発で分かる。

特定ユーザーのファイルだけ欲しいときは account_id でフィルタできる。

curl -s -H "X-ChatWorkToken: $TOKEN" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files?account_id=${ACCOUNT_ID}"

「このルームに上がった経理資料だけ自動取得したい」みたいなケースで使える。ファイル名でフィルタするAPIパラメータは用意されていないので、一覧を取得してからスクリプト側でfilenameを正規表現で絞る運用になる。

ファイルをダウンロードする

ファイルの情報取得とダウンロードは2ステップ必要だ。

ステップ1: ダウンロードURL を生成する

curl -s -H "X-ChatWorkToken: $TOKEN" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files/${FILE_ID}?create_download_url=1"

レスポンス:

{
  "file_id": 12345,
  "filename": "report_2026_03.pdf",
  "filesize": 1048576,
  "download_url": "https://appdata.chatwork.com/..."
}

ポイントは create_download_url=1 パラメータ。これを付けないと download_url フィールドが返ってこない。ファイルのメタ情報だけ欲しいなら省略すればいい。

ステップ2: ダウンロードURLからファイルを取得

curl -o "report_2026_03.pdf" \
  "https://appdata.chatwork.com/..."

ここで認証ヘッダーは不要。URLにトークンが含まれている。

30秒の罠 — ダウンロードURLの有効期限

ここが一番ハマったところだ。

download_url の有効期限は30秒。URLを取得してから30秒以内にダウンロードしないと、403が返ってくる。

最初、ファイル一覧を全件取得してからループでダウンロードする処理を書いた。ファイル数が多いとURL生成からダウンロードまでの間に30秒を超えるケースが出た。こうなる。

# ダメなパターン: 一括でURL生成してからダウンロード
for file_id in "${FILE_IDS[@]}"; do
  # URL取得
  urls+=("$(get_download_url $file_id)")
done
# ↑ ここまでで30秒以上経つと、最初のURLが死んでいる

for i in "${!urls[@]}"; do
  curl -o "file_$i" "${urls[$i]}"  # → 403 Forbidden
done

正しくはURL生成と即ダウンロードをセットにする。

# 正しいパターン: URL取得→即ダウンロード を1ファイルずつ
for file_id in "${FILE_IDS[@]}"; do
  # URL取得
  response=$(curl -s -H "X-ChatWorkToken: $TOKEN" \
    "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files/${file_id}?create_download_url=1")

  download_url=$(echo "$response" | jq -r '.download_url')
  filename=$(echo "$response" | jq -r '.filename')

  # 即ダウンロード(30秒以内)
  curl -s -o "$filename" "$download_url"

  echo "Downloaded: $filename"

  # レートリミット対策
  sleep 1
done

「URL取得→即ダウンロード→次のURL取得」のサイクルを守れば問題ない。Pythonで書くなら requests.get を2連続で呼ぶだけだが、間に重い処理を挟まないよう注意。

ファイルをアップロードする

アップロードは multipart/form-data で送る。curlだとこう。

curl -s -X POST \
  -H "X-ChatWorkToken: $TOKEN" \
  -F "file=@./monthly_report.pdf" \
  -F "message=3月の月次レポートです" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files"

レスポンス:

{
  "file_id": 12346
}

message パラメータはオプション。付けるとファイルと一緒にメッセージが投稿される。「レポート貼っときました」的な一言を添えられるので、自動配布のときは付けた方が親切だ。

5MB制限との付き合い方

Chatwork APIのファイルアップロード上限は5MB。超えると 413 Request Entity Too Large が返る。

正直、5MBは結構きつい。画像数枚入ったPDFや、ログファイルの集約だと簡単に超える。対処法はいくつかある。

圧縮してから投げる。 一番シンプルだ。

# gzip圧縮してからアップロード
gzip -k ./large_log.txt

curl -s -X POST \
  -H "X-ChatWorkToken: $TOKEN" \
  -F "file=@./large_log.txt.gz" \
  -F "message=圧縮済みログファイル" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files"

分割する。 ファイルを分割して複数回アップロードする方法もあるが、受け取る側が結合しないといけない。人間が見るファイルには向かない。

別の場所に置いてリンクだけ投げる。 Google DriveやS3にアップロードして、共有リンクをメッセージとして投稿する。5MBを超えるファイルを日常的に扱うなら、こっちの方が現実的だ。

# Google Driveにアップ → 共有リンクをChatworkに投稿
curl -s -X POST \
  -H "X-ChatWorkToken: $TOKEN" \
  -d "body=月次レポート(大容量版)%0Ahttps://drive.google.com/file/d/xxxxx/view" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/messages"

うちでは5MB未満のものはChatwork直接アップ、超えるものはDrive経由と使い分けている。

実用パターン: 日次レポートの自動配布

実際に動かしているのは、日次で生成されるレポートPDFをChatworkルームに自動投下するパターンだ。cronやlaunchdでスクリプトを定期実行する。

#!/bin/bash
TOKEN="$CHATWORK_TOKEN"
ROOM_ID="$TARGET_ROOM_ID"
REPORT_DIR="./reports"
TODAY=$(date +%Y-%m-%d)
FILE="${REPORT_DIR}/daily_report_${TODAY}.pdf"

if [ ! -f "$FILE" ]; then
  echo "Report not found: $FILE"
  exit 1
fi

FILESIZE=$(stat -f%z "$FILE" 2>/dev/null || stat -c%s "$FILE" 2>/dev/null)

if [ "$FILESIZE" -gt 5242880 ]; then
  echo "File exceeds 5MB limit. Compressing..."
  gzip -k "$FILE"
  FILE="${FILE}.gz"
fi

curl -s -X POST \
  -H "X-ChatWorkToken: $TOKEN" \
  -F "file=@${FILE}" \
  -F "message=${TODAY} の日次レポート" \
  "https://api.chatwork.com/v2/rooms/${ROOM_ID}/files"

echo "Uploaded: ${FILE}"

ファイルサイズを事前チェックして、5MBを超えていたら自動で圧縮してからアップする。これで413エラーに怯えなくて済む。

まとめ

Chatwork APIのファイル機能、地味だけど自動化には欠かせない。

覚えておくべきは3つ。

  1. ダウンロードURLは30秒で死ぬ。 URL生成と即ダウンロードをセットにする
  2. アップロード上限は5MB。 超えるなら圧縮かDrive経由
  3. create_download_url=1 を忘れるとURLが返ってこない。 ファイル情報だけ欲しいのか、ダウンロードしたいのかで使い分ける

メッセージAPIやタスクAPIに比べると地味なエンドポイントだが、「レポートの自動配布」「添付ファイルの自動バックアップ」あたりは使い始めると手放せなくなる。Chatworkをハブにしてファイルも回す運用、割とアリだと思う。


Chatworkシリーズ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?