Amazonで商品を見るセール会場へ

FigmaのコメントをREST APIで取得・CSV出力する方法

Figmaのファイルに付いたコメントは、REST APIのGET /v1/files/:key/commentsで取得できます。レビュー内容を一覧化する場合は、コメント本文だけでなく、返信先のparent_idと解決日時を残すと、会話のつながりを確認しやすくなります。

この記事では、必要な権限、PythonによるCSV出力、返信・削除、エラーの確認順を説明します。2026年10月3日に確認した公式仕様に基づく例です。CSV処理は模擬データで確認していますが、実際のFigmaファイルへのAPI接続は未検証です。公式コメントAPI

目次

必要なものと権限

  1. コメントを取得したいFigmaファイルへのアクセス権を確認します。
  2. 個人アクセストークンへfile_comments:readスコープを付けます。
  3. 対象ファイルのURLからファイルキーを確認します。
  4. Pythonとrequestsを用意し、環境変数FIGMA_TOKEN・FIGMA_FILE_KEYへ設定します。

取得だけなら書き込みスコープは不要です。投稿・返信・自分のコメントの削除も行う場合に、file_comments:writeを追加します。トークンの取得方法

ファイルキーはURLの/design/や/file/の直後にある文字列です。node-idはレイヤーのIDなので、コメント取得先のファイルキーとして使わないでください。ブランチのコメントを扱う場合は、ブランチキーを指定する方法もあります。REST APIとPlugin APIの違い

コメントと返信を区別する

取得結果のcomments配列には、ルートのコメントと返信が含まれます。親子関係はparent_idで追います。画面のコメント番号であるorder_idはトップレベルのコメントだけに設定されるため、識別にはidを使います。

項目用途
idAPI上のコメント識別子
parent_id返信先のコメントID
user.handle投稿者の表示名
created_at投稿日時。UTCのISO 8601形式
resolved_at解決済みの日時。返信自身にない場合も親を確認
client_metaピンの位置・フレームへの相対位置など

返信のresolved_atだけを見て、スレッド全体が未解決と判断しないようにします。次のCSV例は、親コメントの解決日時も参照したthread_resolved_at列を作ります。コメントの型と位置情報

PythonでCSVへ出力する

次をexport_comments.pyとして保存します。as_md=trueは、対応するコメントをMarkdown形式で取得する指定です。CSVにはその文字列を保存し、HTMLとして実行しません。

import csv
import json
import os
import re
import tempfile
from pathlib import Path

import requests


def csv_text(value):
    text = "" if value is None else str(value)
    if text.lstrip().startswith(("=", "+", "-", "@")):
        return "'" + text
    return text


def write_comments(comments, destination):
    by_id = {str(c["id"]): c for c in comments}
    destination = Path(destination)
    columns = ["id", "parent_id", "user", "created_at",
               "resolved_at", "thread_resolved_at", "message", "client_meta"]
    temporary = None
    try:
        with tempfile.NamedTemporaryFile(
            mode="w", newline="", encoding="utf-8-sig",
            dir=destination.parent, delete=False
        ) as handle:
            temporary = Path(handle.name)
            writer = csv.writer(handle)
            writer.writerow(columns)
            for comment in comments:
                parent_id = str(comment.get("parent_id") or "")
                root = by_id.get(parent_id, comment)
                values = [comment["id"], parent_id,
                          (comment.get("user") or {}).get("handle", ""),
                          comment.get("created_at", ""),
                          comment.get("resolved_at", ""),
                          root.get("resolved_at", ""),
                          comment.get("message", ""),
                          json.dumps(comment.get("client_meta"), ensure_ascii=False)]
                writer.writerow([csv_text(v) for v in values])
        temporary.replace(destination)
    finally:
        if temporary is not None:
            temporary.unlink(missing_ok=True)


def main():
    key = os.environ["FIGMA_FILE_KEY"]
    if not re.fullmatch(r"[A-Za-z0-9_-]+", key):
        raise SystemExit("FIGMA_FILE_KEYにはURL全体ではなくファイルキーを設定してください")
    response = requests.get(
        f"https://api.figma.com/v1/files/{key}/comments",
        headers={"X-Figma-Token": os.environ["FIGMA_TOKEN"]},
        params={"as_md": "true"}, timeout=60
    )
    if response.status_code == 429:
        raise SystemExit("API制限に達しました。Retry-Afterを確認して再実行してください")
    response.raise_for_status()
    comments = response.json()["comments"]
    if not isinstance(comments, list):
        raise ValueError("commentsの形式が想定と異なります")
    write_comments(comments, "comments.csv")
    print(f"{len(comments)}件をcomments.csvへ保存しました")


if __name__ == "__main__":
    main()
python -m pip install requests
python export_comments.py

実行が成功すると、作業フォルダーにcomments.csvを保存します。UTF-8 BOM付きで日本語を扱い、カンマ・改行・引用符はCSVライブラリでエスケープします。数式として解釈されやすい先頭文字にはアポストロフィを付けるため、該当セルの内容は元の本文と完全には同一ではありません。

一時ファイルへ書いてから置き換えるので、取得や変換が途中で失敗した場合は既存のCSVを更新しません。成功時には同名のCSVを置き換えます。出力に投稿者名や非公開のコメントが含まれる場合は、元ファイルの共有範囲に合わせて扱ってください。

投稿・返信・削除のAPI

操作エンドポイントと条件
新規投稿POST /v1/files/:file_key/comments。messageと必要な位置情報を指定
返信同じPOST先でcomment_idにルートコメントのIDを指定
削除DELETE /v1/files/:file_key/comments/:comment_id。投稿した本人だけ
リアクションcomments/:comment_id/reactionsへGET・POST・DELETE

返信先のcomment_idには、返信コメント自身のIDは指定できません。返信のparent_idでルートを探します。また、取得できたコメントをすべて削除できるわけではありません。位置を指定するclient_metaは、キャンバス座標やフレーム相対位置など、目的に合う型を選びます。投稿・返信の仕様

403・404・429の確認順

403ならトークンの有効期限と読み取りスコープ、対象ファイルへの権限を確認します。404ならファイルキー、ブランチ、削除・アクセス権を確認します。429なら応答のRetry-Afterに従い、短い間隔での再取得を止めます。

コメントAPIはTier 2です。上限は席と対象リソースのプランに関係するので、MCPの回数表と混同しないでください。REST APIの利用制限

新しいコメントの発生を契機に処理したい場合は、毎回全件取得する代わりにWebhookのFILE_COMMENTを検討します。Webhookの通知本文はこのGETの返り値とは形式が異なります。

サービス

Service

デザイン制作に関心がありましたら、ぜひ詳細をご覧ください。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Figmaのおすすめ書籍

Figma用PCの選び方

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次