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?

LINE WORKS API AiNote の議事録 (文字起こし・要約) を取得する

0
Last updated at Posted at 2026-09-22

LINE WORKS の AI 議事録サービス「AiNote」に保存されたノートを API で取得する方法を解説します。ノートの一覧、キーワード検索、詳細 (文字起こしと要約) の 3 つの API を、Google Colab で試せる Python コードとあわせて紹介します。

概要

AiNote API には 6 つのエンドポイントがあり、この記事ではユーザー自身のノートを読み取る 3 つを扱います。

用途 エンドポイント この記事
ノート一覧 GET /users/{userId}/ainote/notes 扱う
ノート検索 GET /users/{userId}/ainote/search?query=... 扱う
ノート詳細 GET /users/{userId}/ainote/notes/{noteId} 扱う
ノート削除 DELETE /users/{userId}/ainote/notes/{noteId} 扱わない
メンバー別使用状況 GET /ainote/users/statistics 扱わない (管理者権限が必要)
使用状況 GET /ainote/quota 扱わない (管理者権限が必要)

利用にあたって押さえておく点は 3 つです。

  • User Account 認証専用です。 ユーザーのノートを扱う API は「User Account 認証で発行された Access Token でのみ呼び出すことができる」と明記されています。Service Account 認証 (JWT) では利用できません
  • スコープは ainote.read で足ります (削除まで行う場合は ainote)
  • 対応プランは Team / Business / Enterprise です。公開当初は Enterprise 限定でしたが、2026 年 8 月 21 日のリリースノートで「エンタープライズプランに加え、チームおよびビジネスプランでも利用可能になりました」と告知されています。Developer Console のスコープ選択に ainote.read が表示されなければ、そのテナントでは利用できません

必要な準備

1. アクセストークンの取得

User Account 認証でアクセストークンを取得します。手順は LINE WORKS API トークン取得 (User Account 認証) を参照してください。アプリの OAuth Scopes には ainote.read を追加します。

Developer Console でアプリを作成するには開発者権限が必要です。一般メンバーの権限では作成できないことが多いので、その場合は管理者にアプリの作成か権限の付与を依頼してください。

Developer Console で ainote.read を選択

2. Google Colab の準備

以下のノートブックを開き、セルを上から順に実行します。「このノートブックは Google が作成したものではありません」という警告が出た場合は、内容を確認のうえ「このまま実行」で進めてください。手元に残したい場合は「ドライブにコピー」しておきます。

Google Colab ノートブックを開く

ノートブックのソースは GitHub にあります。

アクセストークンは実行時に入力欄で聞かれる形にしてあり、ノートブックには保存されません。Colab の「シークレット」に LINEWORKS_ACCESS_TOKEN という名前で登録しておくと、入力を省略できます。

サンプルコード

3 つの API を呼ぶ最小のコードです。パスの {userId} には me を指定すると、トークンの持ち主自身に解決されます。自分の userId を別途取得する必要はありません。

import requests
from getpass import getpass

ACCESS_TOKEN = getpass("アクセストークン: ")   # コードやノートブックに直接書かない
BASE_URL = "https://www.worksapis.com/v1.0"
HEADERS = {"Authorization": f"Bearer {ACCESS_TOKEN}"}


def hms(milliseconds):
    """ミリ秒を H:MM:SS に整形する。audioDuration と発言の offset はミリ秒。"""
    total = int(milliseconds or 0) // 1000
    h, rem = divmod(total, 3600)
    m, s = divmod(rem, 60)
    return f"{h}:{m:02d}:{s:02d}" if h else f"{m}:{s:02d}"


def call(path, params=None):
    """API を呼び、エラー時は API が返す code / description を表示する。"""
    res = requests.get(f"{BASE_URL}/{path}", headers=HEADERS, params=params, timeout=30)
    if res.status_code >= 400:
        print(f"HTTP {res.status_code}")
        print(res.text)
        return None
    return res.json()


# 1. ノート一覧 (新しい順)。要約も文字起こしも含まれない
data = call("users/me/ainote/notes", {"count": 10})
if data:
    for n in data["notes"]:
        print(f"{n['createdTime'][:16]}  {hms(n['audioDuration']):>7}  {n['title']}")
        print(f"    noteId: {n['noteId']}")

# 2. ノート検索 (query は必須)。応答の構造は一覧と同じ
data = call("users/me/ainote/search", {"query": "営業", "count": 10})
if data:
    print(f"{len(data['notes'])}")

# 3. ノート詳細 (要約と文字起こし)
note = call("users/me/ainote/notes/<noteId>")
if note:
    print(note["title"], hms(note["audioDuration"]))

    for s in note.get("summaries") or []:          # 要約 (作成者が生成した場合のみ)
        print(f"--- {s['summaryName']} ({s['summaryType']}) ---")
        print(s["content"])

    for b in (note.get("scripts") or [])[:10]:     # 文字起こし (先頭 10 ブロック)
        text = b["text"].strip().replace("\n", " ")  # ブロック内の改行を潰して 1 行にする
        print(f"[{hms(b['startOffset'])}] {b.get('attendeeName') or '話者不明'}: {text}")

トークンは getpass で入力し、コードに書き残さないようにしています。Colab のノートブックにトークンを直接貼ると、Drive に保存されたノートブックを共有した時点で漏れるので注意してください。

入力例

項目 内容
ACCESS_TOKEN User Account 認証で取得したアクセストークン (ainote.read スコープ)
count 一覧・検索の取得件数
query 検索キーワード。必須です
noteId 一覧か検索の結果に含まれる noteId

一覧と検索の応答には responseMetaData.nextCursor が含まれます。次のページを取るときは cursor パラメータにこの値を渡します。

実行結果

成功時: ノート一覧

{
  "notes": [
    {
      "noteId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "workspaceId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "userId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "createdTime": "2026-09-21T22:51:22+09:00",
      "updatedTime": "2026-09-21T22:52:07+09:00",
      "title": "次期営業戦略重点施策検討会議",
      "recognitionLanguage": "ja",
      "audioDuration": 308260
    }
  ],
  "responseMetaData": {
    "nextCursor": "MjAyNi0wOS0yMVQx...(省略)"
  }
}

audioDuration の 308260 はミリ秒で、5 分 8 秒です。検索の応答も同じ構造です。

成功時: ノート詳細

一覧の項目に加えて attendees (参加者)、scripts (文字起こし)、summaries (要約) が入ります。文字起こしは長いので先頭 2 ブロックだけ載せています。各種 ID と attendees の氏名は置き換えていますが、scripts の「参加者 1」「参加者 2」は AiNote が話者に名前を割り当てていないときの既定の表示で、実際の応答のままです。

{
  "noteId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "title": "次期営業戦略重点施策検討会議",
  "recognitionLanguage": "ja",
  "audioDuration": 308260,
  "attendees": [
    {
      "attendeeId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "userId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "attendeeName": "山田 太郎"
    }
  ],
  "scripts": [
    {
      "blockId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "text": "はい、では始めましょう。今日は次期営業戦略重点施策を検討する会議です。\nまず、現状の営業活動の課題を共有しましょう。",
      "attendeeId": null,
      "attendeeName": "参加者 1",
      "startOffset": 12610,
      "endOffset": 25770
    },
    {
      "blockId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "text": "直近受注率がやや低下傾向です。問い合わせ件数自体は増えていますが、最終的な制約率で苦戦しています。\nお客様からは他社との違いがわかりにくいという声が多く聞かれます。",
      "attendeeId": null,
      "attendeeName": "参加者 2",
      "startOffset": 27380,
      "endOffset": 44100
    }
  ],
  "summary": null,
  "summaries": [
    {
      "summaryId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "summaryType": "AI",
      "summaryName": "AIおまかせ要約",
      "content": "## 現状の課題\n- 受注率が低下傾向にあり、競合製品との比較検討での離脱が増加している。... [[00:27~00:55]]\n\n## 顧客ニーズと訴求方針\n- 顧客は業務効率化やコスト削減を重視しており、... [[01:10~01:28]]\n...(省略)",
      "createdTime": "2026-09-21T22:52:03+09:00",
      "updatedTime": "2026-09-21T22:52:03+09:00"
    },
    {
      "summaryId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "summaryType": "TIMELINE",
      "summaryName": "区間ごとの要約",
      "content": "[[00:12~05:02]]\n\n**差別化強化に向けた営業施策の決定**\n\n- 問い合わせ件数は増加する一方で受注率が低下し差別化不足が課題である\n...(省略)",
      "createdTime": "2026-09-21T22:52:07+09:00",
      "updatedTime": "2026-09-21T22:52:07+09:00"
    }
  ]
}

要約の content は Markdown で、[[00:27~00:55]] のように該当区間のタイムスタンプが入ります。この例では「AIおまかせ要約」と「区間ごとの要約」の 2 種類が生成されています。

attendees には録音した本人 (LINE WORKS のユーザーとして紐づく人) だけが入り、scripts で発言している「参加者 2」は含まれていない点に注目してください。参加者の一覧が欲しい場合は、attendees ではなく scriptsattendeeName を集めるほうが確実です。

サンプルコードで整形すると、文字起こしは次のように表示されます。

[0:12] 参加者 1: はい、では始めましょう。今日は次期営業戦略重点施策を検討する会議です。 まず、現状の営業活動の課題を共有しましょう。
[0:27] 参加者 2: 直近受注率がやや低下傾向です。問い合わせ件数自体は増えていますが、最終的な制約率で苦戦しています。 お客様からは他社との違いがわかりにくいという声が多く聞かれます。

失敗時

スコープが足りない場合は 403 が返ります。次はトークンに含まれないスコープの API を呼んだときの実際の応答です。

{"code": "FORBIDDEN", "description": "has not permission api scope"}

403 は後述の権限不足でも返るので、ステータスコードだけで判断せず、応答本文の codedescription を必ず確認してください。

検索で query を省くと 400 です。パラメータ名を qkeyword にしても同じエラーになります。

{"code": "INVALID_PARAMETER", "description": "'query' field is required"}

パスの末尾の /notes を省いて /users/me/ainote を呼ぶと 404 です。

{"code": "NOT_FOUND", "description": "Api not exists"}

統計系の API (/ainote/quota/ainote/users/statistics) を一般ユーザーのトークンで呼ぶと 403 ですが、スコープ不足とは別のエラーです。管理者権限が必要なので、スコープを足しても解決しません。

{"code": "ACCESS_DENIED", "description": "no authority to access. memberAuthLevel is not admin"}

注意事項

  • 時間の単位はミリ秒です。 audioDurationstartOffsetendOffset はすべてミリ秒で、秒だと思って扱うと 1000 倍ずれます
  • 要約は summaries (複数形) を見ます。 summary (単数形) というフィールドもありますが、2026 年 8 月 21 日のリリースノートによると、summary には 2026 年 8 月下旬以降に生成された AI 要約が含まれず、将来の廃止が予定されています。新しく作るコードでは summaries だけを使ってください
  • 要約は自動では生成されません。 ノートの作成者が AiNote の画面でテンプレート (「AIおまかせ要約」「意思決定会議」など) を選んだときに生成されます。生成していないノートでは summaries が空配列になるので、その場合は scripts から内容を読む必要があります
  • 検索 API の呼び出し上限は 60 回/分 で、他の API (240 回/分) より厳しく制限されています。同じ条件で繰り返し呼ばず、cursor でページを進めてください
  • 一覧と検索の応答には要約も文字起こしも含まれません。 どちらもタイトルと日時、音声の長さといったメタデータだけです。内容が必要なときだけ詳細を取る、という使い方になります
  • 文字起こしは長くなります。 5 分の会議で scripts が約 8KB でした。録音時間に比例すると仮定した目安ですが、1 時間なら 100KB 近くになります。詳細を取るときは必要なブロック数に絞ると扱いやすくなります
  • attendees は話者を網羅していません。 LINE WORKS のユーザーとして紐づいた参加者 (通常は録音した本人) だけが入り、それ以外の話者は scripts にしか現れません。話者の一覧は scriptsattendeeName から集めてください
  • 発言ブロックの attendeeIdnull のことがあり、名前を割り当てていない話者は attendeeName が「参加者 1」「参加者 2」のような既定の表示になります

この API でできること

ノートを API で取り出せると、AiNote の画面を開かずに議事録を活用できます。たとえば次のような使い方が考えられます。

  • 会議が終わったら要約を社内 Wiki やドキュメントに自動で転記する
  • 要約の中の決定事項やアクションアイテムを Bot でトークルームに流す
  • 文字起こしを LLM に渡して、質問に答えさせたり横断的に検索させたりする

3 つ目については、この API を MCP サーバーにして Claude から使う記事を別に書いています (関連記事を参照)。

関連記事

参考

AiNote のノートを API で取り出せると、議事録を他のシステムに連携したり、AI に読ませたりといった活用が広がります。この記事がその入口になれば幸いです。

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?