Lark 開発ガイド
01 — はじめに

Lark Open Platform 概要

まずはプラットフォームの全体像と、開発で「何ができるか」をつかみましょう。

Lark とは

Lark(海外版飛書 / Feishu)は、ByteDance が提供するエンタープライズ向けコラボレーションプラットフォームです。メッセージング、ビデオ会議、ドキュメント、プロジェクト管理、承認フローなどを1つに統合した「スーパーアプリ」として位置づけられています。

主要機能

機能説明
Messengerチャット、グループ、Bot連携。チャット内でアプリと直接対話
Meetingsリアルタイム翻訳、自動議事録生成、ビデオ会議
Docsリアルタイム共同編集、権限管理付きドキュメント
Base (Bitable)多次元テーブル。自動化・データ分析・プロジェクト管理
Calendar / Approvalスケジュール管理 / ワークフロー承認
Workplace / Wikiポータル / ナレッジベース

Open Platform でできること

  1. Server API 呼び出し — メッセージ送信、ユーザー管理、ドキュメント操作 など
  2. イベント購読 — メッセージ受信、ユーザー変更などのリアルタイム通知
  3. Bot 開発 — チャット内で動作するインタラクティブ Bot
  4. カスタムアプリ / Docs Add-on / Base Extension — Lark 内に埋め込む拡張
  5. Workflow Automation — AnyCross によるローコード自動化

アプリの種類

種類説明公開範囲
Custom App特定の企業内でのみ使用社内のみ
Marketplace AppApp Directory に公開全企業

ドメインの違い

ドメイン対象
open.larksuite.comLark(海外版)
open.feishu.cn飛書(中国国内版)

SDK / API は共通ですが、ドメイン指定が異なります。Node SDK では lark.Domain.Lark / lark.Domain.Feishu で切り替えます。

アーキテクチャの全体像

architecture
┌─────────────────────────────────────────────┐
│              Lark Client                      │
│  Messenger │ Docs │ Base │ Calendar │ Approval│
├────────────────────┬──────────────────────────┤
│  Custom App (H5)   │  Bot / Webhook            │
│  Docs Add-on       │  Event Subscription       │
│  Base Extension    │                           │
├────────────────────┴──────────────────────────┤
│           Lark Open Platform                  │
│   Server API  │  Event Sub  │  Message Card   │
├───────────────────────────────────────────────┤
│           Developer Console                   │
└───────────────────────────────────────────────┘
              ↕ REST API / WebSocket
┌───────────────────────────────────────────────┐
│  Your Backend (Node.js / Python / Go / Java)  │
│  SDK: @larksuiteoapi/node-sdk                 │
└───────────────────────────────────────────────┘

公式リンク

リソースURL
Developer Consoleopen.larksuite.com/app
Documentationopen.larksuite.com/document
API Exploreropen.larksuite.com/api-explorer
Help Center (JP)larksuite.com/hc/ja-JP
02 — はじめに

アプリ開発フロー

Developer Console でのアプリ作成から公開まで、全体の流れを6ステップで押さえます。

開発フロー全体像

flow
1. Developer Console でアプリ作成
2. App ID / App Secret 取得
3. 必要な権限(Scope)を設定
4. 機能を実装(Bot / Web App / API 呼び出し)
5. テスト・デバッグ
6. 管理者承認 → アプリ公開

Step 1–2: アプリ作成と認証情報

Developer Console で「Create Custom App」→ 名前・アイコン・説明を入力すると、App ID と App Secret が発行されます。

項目用途
App IDアプリ識別子
App SecretAPI 認証用シークレット
Encrypt Keyイベント暗号化用(任意)
Verification TokenWebhook 検証用
⚠️ App Secret は秘密情報
ソースにハードコードせず環境変数で管理してください。フロントエンドに露出させてはいけません。

Step 3: 権限(Scope)設定

「Permissions & Scopes」で、利用する API の権限を追加します。権限追加後は企業管理者の承認が必要な場合があります。

カテゴリ権限例説明
IMim:message, im:message:send_as_botメッセージ読取・送信
Contactcontact:user.base:readonlyユーザー・部署情報読取
Bitablebitable:appBitable 操作
Docs / Calendar / Approvaldocs:doc, calendar:calendar, approval:approval各機能の操作

Step 4: 開発方式の選択

  • Bot 開発 — チャット内で動作する Bot(Bot 開発へ)
  • H5 Web App — Lark 内に埋め込む Web アプリ(H5 Web App へ)
  • Gadget — Lark 専用ミニアプリ(Gadget へ)
  • Server API 呼び出し — バックエンドから REST API(SDK へ)

Step 5–6: テストと公開

  • Test Enterprise and Users でテスト環境を設定(最大50名まで無料)
  • API Explorer で API を直接テスト、Event Debugging でイベント確認
  • Version Management & Release でバージョン作成 → 管理者承認 → 公開
  • Marketplace App は追加で Lark の審査(通常 1〜3 営業日)が必要

環境変数とプロジェクト構成の例

.env
LARK_APP_ID=cli_xxxxxxxxxxxx
LARK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx
LARK_ENCRYPT_KEY=xxxxxxxxxxxx          # イベント暗号化(任意)
LARK_VERIFICATION_TOKEN=xxxxxxxxxxxx   # Webhook 検証用
03 — 基礎

認証・認可

API を呼び出すためのトークンの種類と取得方法、OAuth フロー、Webhook 検証を押さえます。

Access Token の種類

種類用途取得有効期限
tenant_access_tokenアプリとして呼び出し(最も一般的)App ID + Secret2時間
app_access_tokenアプリレベルの操作App ID + Secret2時間
user_access_tokenユーザーの代理として操作OAuth 2.02時間(更新可)

tenant_access_token の取得

HTTP
POST https://open.larksuite.com/open-apis/auth/v3/tenant_access_token/internal

// リクエスト
{ "app_id": "cli_xxx", "app_secret": "xxx" }

// レスポンス
{ "code": 0, "tenant_access_token": "t-xxx", "expire": 7200 }

呼び出し時は HTTP ヘッダに Authorization: Bearer t-xxx を付与します。

SDK を使う(推奨)

SDK はトークンの取得・キャッシュ・自動更新を内部で処理します。手動管理は不要です。

Node.js
import * as lark from '@larksuiteoapi/node-sdk';

const client = new lark.Client({
  appId: process.env.LARK_APP_ID,
  appSecret: process.env.LARK_APP_SECRET,
  // domain: lark.Domain.Lark  // 海外版
});

user_access_token(OAuth 2.0)

OAuth flow
1. 認証URLへリダイレクト
https://open.larksuite.com/open-apis/authen/v1/authorize
  ?app_id={app_id}&redirect_uri={uri}&state={state}

2. 承認 → redirect_uri に code が返る

3. code を access_token に交換
POST /open-apis/authen/v1/oidc/access_token
{ "grant_type": "authorization_code", "code": "{code}" }

SDK では lark.withUserAccessToken('u-xxx')、ISV アプリは lark.withTenantKey('tenant_key') を第2引数に渡します。

Webhook 検証

イベント購読の初回 URL 登録時に、Lark から challenge リクエストが届きます。同じ値をそのまま返します。

JSON
// 受信
{ "challenge": "ajls384kdjx98XX", "type": "url_verification" }
// 返却
{ "challenge": "ajls384kdjx98XX" }

Encrypt Key を設定するとイベントは AES-256-CBC で暗号化され、SDK が自動で復号します。署名検証の実装は セキュリティ を参照。

認証系のエラーコード

コード意味対処
99991668トークン無効トークン再取得
99991663権限不足Scope 追加 + 管理者承認
99991664app_id / app_secret 不正認証情報を確認
99991672テナント未承認管理者にアプリ承認を依頼
04 — 基礎

Bot 開発

チャット内でユーザーと対話する Bot を作ります。自動応答・通知・ワークフロートリガーに使えます。

Bot の種類

種類説明使い方
Custom Bot企業内で作成する BotDeveloper Console で作成
Webhook Botグループ内 WebhookURL に POST するだけ

開発フロー

アプリ作成 →「Bot」有効化 → Event Subscription URL 設定 → 権限追加 → ハンドラ実装 → テスト → 公開。購読イベントは im.message.receive_v1(メッセージ受信)などを追加します。

実装例:エコー Bot(Node.js)

Node.js
import * as lark from '@larksuiteoapi/node-sdk';
import express from 'express';

const client = new lark.Client({
  appId: process.env.LARK_APP_ID,
  appSecret: process.env.LARK_APP_SECRET,
});

const dispatcher = new lark.EventDispatcher({
  verificationToken: process.env.LARK_VERIFICATION_TOKEN,
}).register({
  'im.message.receive_v1': async (data) => {
    const { message } = data;
    const content = JSON.parse(message.content);
    if (message.message_type === 'text') {
      await client.im.message.create({
        params: { receive_id_type: 'chat_id' },
        data: {
          receive_id: message.chat_id,
          content: JSON.stringify({ text: `受信: ${content.text}` }),
          msg_type: 'text',
        },
      });
    }
  },
});

const app = express();
app.use('/webhook/event', lark.adaptExpress(dispatcher));
app.listen(3000);

Webhook Bot(コードなしで通知)

グループ設定 →「Bots」→「Custom Bot」で Webhook URL を取得。URL に POST するだけで送信できます。

curl
curl -X POST 'https://open.larksuite.com/open-apis/bot/v2/hook/xxx' \
  -H 'Content-Type: application/json' \
  -d '{"msg_type":"text","content":{"text":"CPU使用率が90%を超えました"}}'

主なイベント

イベント名説明
im.message.receive_v1メッセージ受信
im.message.reaction.created_v1リアクション追加
im.chat.member.bot.added_v1Bot がグループ追加
contact.user.created_v3ユーザー作成
approval.approval.updated承認ステータス変更
🛠 デバッグのヒント
  • Event Subscription の URL が正しいか(Challenge が通っているか)
  • 権限が足りているか / 管理者承認が完了しているか
  • Bot がグループに追加されているか
  • content は JSON 文字列(JSON.stringify() 必須)
  • Webhook は 3 秒以内にレスポンスを返す(重い処理は非同期に)
05 — 基礎

インタラクティブメッセージカード

ボタン・フォーム・画像・マークダウンを組み合わせたリッチな UI をメッセージとして送信します。

💡 GUI で作れるカードビルダー
公式の Card Builder で視覚的に組み立て、生成された JSON をそのまま content に使えます。

基本構造

JSON
{
  "config": { "wide_screen_mode": true },
  "header": {
    "template": "blue",
    "title": { "content": "カードタイトル", "tag": "plain_text" }
  },
  "elements": [ /* 本文要素 */ ]
}

ヘッダーカラー

template色template色
blue青red赤
green緑orangeオレンジ
turquoiseターコイズgreyグレー

アクション(ボタン)

JSON
{
  "tag": "action",
  "actions": [
    { "tag": "button",
      "text": { "tag": "plain_text", "content": "承認" },
      "type": "primary", "value": { "action": "approve" } },
    { "tag": "button",
      "text": { "tag": "plain_text", "content": "却下" },
      "type": "danger", "value": { "action": "reject" } }
  ]
}

ボタン type は default(グレー)/ primary(青)/ danger(赤)。ほかに select_static(ドロップダウン)、date_picker(日付)、hr(区切り線)、note(フッター)、column_set(横並び)などの要素があります。

カードの送信(Node.js SDK)

Node.js
await client.im.message.create({
  params: { receive_id_type: 'chat_id' },
  data: {
    receive_id: 'oc_xxx',
    msg_type: 'interactive',
    content: JSON.stringify({
      header: { template: 'green',
        title: { content: 'デプロイ完了', tag: 'plain_text' } },
      elements: [
        { tag: 'markdown', content: '**v1.2.3** を本番にデプロイしました' },
        { tag: 'hr' },
        { tag: 'action', actions: [
          { tag: 'button', type: 'primary',
            text: { tag: 'plain_text', content: 'ログを確認' },
            url: 'https://example.com/logs' } ] },
      ],
    }),
  },
});

テンプレート ID で送る場合は client.im.message.createByCard() に template_id と template_variable を渡します。

カードアクションの処理

Node.js
const handler = new lark.CardActionHandler({
  verificationToken: process.env.LARK_VERIFICATION_TOKEN,
});
handler.register((data) => {
  console.log('アクション:', data.action.value);
  return {   // 更新後のカードを返す(任意)
    header: { template: 'green',
      title: { content: '承認済み', tag: 'plain_text' } },
    elements: [ { tag: 'markdown', content: '承認が完了しました' } ],
  };
});
app.use('/webhook/card', lark.adaptExpress(handler));
06 — SDK・API

Server API カテゴリ一覧

全 API は REST 形式。ベース URL は https://open.larksuite.com/open-apis/、レスポンスは JSON、認証は Bearer Token(tenant_access_token が主流)です。

公式 API 一覧: server-api-list

IM(Messenger)

操作メソッドエンドポイント
メッセージ送信POST/im/v1/messages
メッセージ返信POST/im/v1/messages/{message_id}/reply
メッセージ取得 / 一覧GET/im/v1/messages/{message_id} / /im/v1/messages
チャット作成POST/im/v1/chats
メンバー追加POST/im/v1/chats/{chat_id}/members
画像 / ファイルアップロードPOST/im/v1/images / /im/v1/files

メッセージ種別(msg_type)

msg_typecontent 例
text{"text": "hello"}
post(リッチテキスト){"ja_jp": {"title": "...", "content": [...]}}
image / file / audio / media{"image_key": "img_xxx"} / {"file_key": "file_xxx"}
interactive(カード){...card JSON...}

Contact(連絡先)

操作メソッドエンドポイント
ユーザー取得 / 一覧GET/contact/v3/users/{user_id} / /contact/v3/users
ユーザー作成 / 更新POST / PATCH/contact/v3/users
部署取得 / 子部署一覧GET/contact/v3/departments/{department_id}[/children]

ユーザー ID 種別

種別スコープ形式
open_idアプリ固有ou_xxx
union_id同一開発者の複数アプリ間共通on_xxx
user_id企業内(employee_id)管理コンソールで設定

その他の主要 API

ドメイン代表的な操作
Docxドキュメント作成、ブロック取得・作成・更新(/docx/v1/documents)
Bitableアプリ/テーブル/レコード/フィールドの CRUD(Base API 参照)
Sheetsセル範囲の読取・書込・追記(/sheets/v2/spreadsheets/...)
Calendarカレンダー/イベントの CRUD(/calendar/v4/...)
Approval承認インスタンス作成・承認/却下(/approval/v4/instances)
Driveファイルのアップロード・ダウンロード・権限設定(/drive/v1/...)
Wiki / VC / Task / MailWiki ノード、ビデオ会議、タスク、メール

共通レスポンス形式とエラーコード

JSON
{
  "code": 0,          // 0 = 成功, 非0 = エラー
  "msg": "success",
  "data": { /* レスポンスデータ */ }
}
コード説明
0成功
10001パラメータエラー
10002リクエスト頻度超過
10003認証失敗
10004権限不足
10005リソースが見つからない
07 — SDK・API

Node.js SDK リファレンス

パッケージ @larksuiteoapi/node-sdk。トークン管理・ページネーション・イベント処理を SDK に任せられます。

リポジトリ: github.com/larksuite/node-sdk

インストールとクライアント作成

bash
npm install @larksuiteoapi/node-sdk
Node.js
import * as lark from '@larksuiteoapi/node-sdk';

const client = new lark.Client({
  appId: 'cli_xxx',          // 必須
  appSecret: 'xxx',           // 必須
  domain: lark.Domain.Lark,     // Lark(海外) / Feishu(中国)
  appType: lark.AppType.SelfBuild, // SelfBuild / ISV
  loggerLevel: lark.LoggerLevel.INFO,
});

API 呼び出しパターン

基本形は client.[ドメイン].[リソース].[メソッド]()。params(クエリ)、data(ボディ)、path(パスパラメータ)を渡します。

Node.js
// メッセージ送信
const res = await client.im.message.create({
  params: { receive_id_type: 'chat_id' },
  data: {
    receive_id: 'oc_xxx',
    content: JSON.stringify({ text: 'hello world' }),
    msg_type: 'text',
  },
});
console.log(res.code, res.msg, res.data);  // 0, "success", {...}

ページネーション(自動イテレータ)

Node.js
for await (const items of await client.contact.user.listWithIterator({
  params: { department_id: '0', page_size: 20 },
})) {
  console.log(items);
}

イベント購読

Node.js
const dispatcher = new lark.EventDispatcher({
  encryptKey: 'encrypt_key',            // 任意
  verificationToken: 'verification_token',
}).register({
  'im.message.receive_v1': async (data) => { /* ... */ },
});

// Express / Koa アダプタ
app.use('/webhook/event', lark.adaptExpress(dispatcher));

ファイル操作

Node.js
// アップロード
const res = await client.im.file.create({
  data: { file_type: 'mp4', file_name: 'test.mp4',
    file: fs.readFileSync('path/to/file.mp4') },
});

// ダウンロード
const resp = await client.im.file.get({ path: { file_key: 'file_key' } });
await resp.writeFile('output.mp4');

汎用リクエスト

SDK にメソッドが無い API は client.request() で直接呼び出せます。

Node.js
const res = await client.request({
  method: 'POST',
  url: '/open-apis/some/new/endpoint',
  data: { key: 'value' },
});

主要ドメイン

im / contact / calendar / drive / docx / sheets / bitable / wiki / approval / attendance / vc / task / mail / application / auth

08 — SDK・API

Python SDK リファレンス

パッケージ lark-oapi(MIT ライセンス)。ビルダーパターンでリクエストを組み立てます。

リポジトリ: github.com/larksuite/oapi-sdk-python(v2_main)

インストールとクライアント作成

bash
pip install lark-oapi
Python
import lark_oapi as lark

client = lark.Client.builder() \
    .app_id("cli_xxx") \
    .app_secret("xxx") \
    .domain(lark.LARK_DOMAIN) \
    .log_level(lark.LogLevel.DEBUG) \
    .build()

メッセージ送信

Python
from lark_oapi.api.im.v1 import *

request = CreateMessageRequest.builder() \
    .receive_id_type("chat_id") \
    .request_body(CreateMessageRequestBody.builder()
        .receive_id("oc_xxx")
        .msg_type("text")
        .content('{"text": "hello world"}')
        .build()) \
    .build()

response = client.im.v1.message.create(request)
if not response.success():
    print(f"Error: {response.code} - {response.msg}")
else:
    print(response.data)

イベント購読(Flask)

Python
def handle_message_receive(data: P2ImMessageReceiveV1) -> None:
    print(f"受信: {data.event.message.content}")

event_handler = lark.EventDispatcherHandler.builder("", "verification_token") \
    .register_p2_im_message_receive_v1(handle_message_receive) \
    .build()

@app.route("/webhook/event", methods=["POST"])
def event():
    return lark.flask_dispatcher(event_handler)

FastAPI では await lark.fastapi_dispatcher(event_handler, request) を使います。

主要モジュール

モジュールインポート
IMlark_oapi.api.im.v1
Contactlark_oapi.api.contact.v3
Bitablelark_oapi.api.bitable.v1
Docx / Sheets / Wikilark_oapi.api.docx.v1 ほか
Calendar / Approval / VC / Tasklark_oapi.api.calendar.v4 ほか
09 — Base (Bitable)

Lark Base(Bitable)概要

Lark Base(Bitable)は多次元テーブル。見た目はスプレッドシートですが、中身はフィールド型を持つデータベースに近い機能です。

基本概念

structure
Bitable App (アプリ / app_token)
  └── Table (テーブル / table_id)
        ├── Field  (フィールド/列, 型付き / field_id)
        ├── Record (レコード/行 / record_id)
        └── View   (ビュー / view_id)
              Grid / Kanban / Gallery / Gantt / Form / Calendar

フィールド型(主要)

型API type型API type
テキスト1チェックボックス7
数値2人11
単一選択3URL15
複数選択4添付ファイル17
日付5リンク(他テーブル参照)18

ほかに ルックアップ(19)、数式(20)、作成日時(1001)、更新日時(1002)、作成者(1003)、自動番号(1005) などがあります。

ビューの種類

ビュー適した用途
Gridデータ入力・一覧(表形式)
Kanbanステータス管理(単一選択で列分け)
Ganttスケジュール管理(日付でタイムライン)
Form外部共有可能な入力フォーム
Calendar / Gallery日程管理 / 画像付きカード表示

識別子の取得

Bitable の URL から app_token・table_id・view_id を取得できます。

URL
https://xxx.larksuite.com/base/BascXXXXXX?table=tblYYYYYY&view=vewZZZZZZ
                               ^^^^^^^^^^         ^^^^^^^^^      ^^^^^^^^
                               app_token          table_id       view_id
🔎 GUI か API か
フィルタ・ソート・組み込み自動化(トリガー+アクション)は GUI だけで実現できます。外部システム連携・バッチ処理・複雑な条件分岐が必要な部分だけ API で補うのが定石です。
10 — Base (Bitable)

Base API 実装ガイド(Node.js)

Bitable を Node.js SDK で操作します。権限は bitable:app(読み書き)または bitable:app:readonly が必要です。

レコード CRUD

Node.js
// 作成
await client.bitable.appTableRecord.create({
  path: { app_token: APP_TOKEN, table_id: tableId },
  data: { fields: {
    'タスク名': 'API設計',
    'ステータス': '未着手',
    '期限': 1710288000000,  // Unix timestamp (ms)
  } },
});

// 一覧
const res = await client.bitable.appTableRecord.list({
  path: { app_token: APP_TOKEN, table_id: tableId },
  params: { page_size: 100 },
});

// 更新 / 削除
await client.bitable.appTableRecord.update({
  path: { app_token: APP_TOKEN, table_id: tableId, record_id: recId },
  data: { fields: { 'ステータス': '進行中' } },
});
await client.bitable.appTableRecord.delete({
  path: { app_token: APP_TOKEN, table_id: tableId, record_id: recId },
});

フィルタとソート

Node.js
params: {
  page_size: 100,
  filter: JSON.stringify({
    conjunction: 'and',
    conditions: [
      { field_name: 'ステータス', operator: 'is', value: ['未着手'] },
    ],
  }),
  sort: JSON.stringify([ { field_name: '期限', desc: false } ]),
}

演算子: is / isNot / contains / doesNotContain / isEmpty / isNotEmpty / isGreater / isLess / isGreaterEqual / isLessEqual。

バッチ操作と全件取得

1 リクエスト最大 500 件。全件取得は page_token でページ送りします。バッチは batchCreate / batchUpdate / batchDelete。

Node.js
async function getAllRecords(tableId) {
  const all = [];
  let pageToken;
  do {
    const res = await client.bitable.appTableRecord.list({
      path: { app_token: APP_TOKEN, table_id: tableId },
      params: { page_size: 500, ...(pageToken ? { page_token: pageToken } : {}) },
    });
    all.push(...(res.data?.items || []));
    pageToken = res.data?.has_more ? res.data.page_token : undefined;
  } while (pageToken);
  return all;
}

フィールド型ごとの値の書き方

型書き方
テキスト(1)'テキスト値'
数値(2)50000
単一選択(3)'進行中'(選択肢名)
複数選択(4)['重要','緊急']
日付(5)1710288000000(ミリ秒)
チェックボックス(7)true
人(11)[{ id: 'ou_xxx' }]
URL(15){ text: 'Google', link: 'https://google.com' }
リンク(18)[{ record_id: 'recXXX' }]
⚠️ レートリミット
Bitable API は約 100 リクエスト/分/アプリ。バッチ API を活用し、必要に応じてスリープを挟んでください。よくあるエラー: 1254043(テーブル未存在)、1254044(フィールド名不一致)、1254607(値の型不一致)。
11 — Base (Bitable)

Base Extension(拡張機能)開発

Base Extension は、Base に導入された柔軟なオープン機能です。コードを書いてカスタム機能を実装し、Base をより強力な業務システムに拡張できます。

⚠️ ベータ機能
本機能は現在ベータテスト中です。仕様は変更される可能性があります。最新情報は公式ドキュメント/開発者コミュニティを確認してください。

主なユースケース

  • バッチデータ処理 — フィールド内の非構造化データから特定のデータを抽出し、他のフィールドで利用する
  • カスタム関数 — 特定の機能を実装し、計算能力を強化する関数を書く
  • データ同期 — データを読み書きし、サードパーティのシステムと接続・連携する

準備

スクリプトは「有効な URL」さえあれば利用できます。ドキュメントの例では Replit(ブラウザ上でコードを書いて実行できるオンライン環境)を使いますが、サービスがデプロイされていれば Vercel / GitHub / localhost / 自前サーバー など、どのプラットフォームでも構いません。

フロントエンド vs サーバーサイド

種別読み書きの基礎ユーザーとの対話スクリプト/Base を閉じた後も実行
フロントエンドスクリプト✅✅❌
サーバーサイドスクリプト✅❌✅

テンプレート

種別テンプレートエントリーポイント
フロントエンドHTMLsrc/index.ts
Reactsrc/App.tsx
Vuesrc/App.vue
フロント+サーバーNext.jspages/index.tsx
サーバーサイドNode Expressserver.ts

技術スタックと用途に応じてテンプレートを選び、右上の「Fork」ボタンで Replit アカウントにフォークします。

フロントエンドスクリプトの開発手順

  1. フロントエンドテンプレートを選び「Fork」でフォーク
  2. IDE 上部の「Run」でプロジェクトを起動し、右側のプレビュー URL をコピー
  3. 任意の Base を開き、右上の「Base Extensions」をクリック
  4. 「+ スクリプトを追加」→ プレビュー URL を入力 →「確認」で実行

IDE でコードを変更すると拡張スクリプトが動的に更新されます。デバッグ情報は Base 上で F12 を押してコンソールで確認できます。

コード例:検索と置換(React / Base JS SDK)

現在のテーブルの「複数行テキスト(多行文本 / Multiline)」フィールドで hi を hello に置換する例です。

React / @base-open/web-api
import './App.css';
import { bitable, IOpenSegmentType } from "@base-open/web-api";
import { Button } from '@douyinfe/semi-ui';

const findText = 'hi';        // 検索する文字列
const replaceText = 'hello';  // 置換する文字列

export default function App() {
  const replace = async () => {
    const selection = await bitable.base.getSelection();
    const table = await bitable.base.getTableById(selection?.tableId!);
    const fieldMetaList = await table.getFieldMetaList();
    const textField = fieldMetaList.find(({ name }) => name === 'Multiline' || name === '多行文本');
    const recordIdList = await table.getRecordIdList();
    for (let i = 0; i < recordIdList.length; i++) {
      const cellString = await table.getCellString(textField?.id!, recordIdList[i]!);
      if (cellString?.includes(findText)) {
        const newText = cellString.replaceAll(findText, replaceText);
        await table.setCellValue(textField?.id!, recordIdList[i]!, [{
          type: IOpenSegmentType.Text,
          text: newText,
        }]);
      }
    }
  };

  return (
    <main>
      <Button theme='solid' type='primary' onClick={replace}>Replace hi to hello</Button>
    </main>
  );
}

サーバーサイドスクリプトの開発手順

  1. サーバーサイドテンプレート(Node Express など)を選び「Fork」
  2. 「Run」で起動し、プレビュー URL をコピー
  3. Base の「Base Extensions」を開く
  4. Replit で personalBaseToken(認証コード) と appToken を取得して利用
  5. 「+ スクリプトを追加」→ プレビュー URL を入力 →「確認」で実行

サーバーサイド拡張は Automations の HTTP リクエストと組み合わせ、「新規レコード追加時」「レコード変更時」など各種トリガー条件で起動することもできます。

ホスティング方式の比較

方式スリープ環境想定シナリオ
Replit デフォルト一定時間の非アクティブでスリープ(Always On で回避)開発/本番の区別なし(変更が本番に直接影響)個人利用・開発/テスト
Replit Deployment一定時間でスリープ開発と本番を分離一般提供するサービス
Base Hosting自動スリープしない開発と本番を分離(変更が本番に直接影響しない)広く公開・利用してほしい優れた事例

Base Hosting へ提出するには、共有フォームに記入 → 承認されるとプロジェクトがフォーク・デプロイされます。

トークンと識別子

  • personalBaseToken — 右上の「認証コードを取得」→ ポップアップで「認証コードを有効にする」で取得
  • appToken / table_id / view_id — いずれも Base の URL から取得(Base 概要参照)
🔐 Replit ではトークンを Secrets に保存
作成した Repl は既定で「公開」のため、誰でもソースを閲覧できます。appToken・personalBaseToken・各種キーなどの機密情報は、必ず「Tools → Secrets」パネルに保存してください(コードに直書きしない)。

権限モデル

  • フロントエンド拡張 — 権限はスクリプトを実行するユーザーに従う。ユーザーが閲覧権限を持たないデータにはスクリプトもアクセスできない
  • サーバーサイド拡張 — 実行はドキュメント所有者が提供する personalBaseToken に依存。この権限は「ドキュメント所有者」の ID 相当(所有者自身が取得・提供する必要がある)
❓ 「無効な応答が送信されました」と出る場合
お使いの端末・社内ネットワークが次のドメインをブロックしていないか確認してください:*.plz.click / *.shicaizhaopin.net

さらに学ぶ(公式)

  • フロントエンド拡張 API(@base-open/web-api)のリファレンス
  • Base Open SDK(Node.js)ドキュメント — Node.js API と Base データの読み書き
  • Base Open SDK(Python)ドキュメント — Python API と Base データの読み書き
  • PersonalBaseToken ユーザーガイド

出典: Lark 公式ドキュメント「Base Extensions」(ユーザー提供)。正確な仕様・最新の API は公式ドキュメントを参照してください。

12 — アプリ形態

H5 Web App 開発ガイド

既存の Web サイトや SPA を、Lark クライアントのサイドバー・メインエリア・モバイル画面に埋め込めます。

公式: client-docs/h5/introduction

開発フロー

アプリ作成 →「Web App」有効化 → Desktop / Mobile の URL を設定 → JS SDK 導入 → 権限設定・テスト → 管理者承認・公開。URL には lark_version / platform / locale が自動付与されます。

表示モード

モード説明
Sidebar左サイドバーのアイコン → クリックで展開(PC・デフォルト)
Main Areaメインエリアにフルサイズ表示
Mobileモバイルは全画面表示

JS SDK の初期化と認証

TypeScript
import lark from '@nicegoodthings/jssdk';

lark.ready(() => console.log('Lark JS SDK ready'));
lark.error((err) => console.error(err));

// 機能利用前に config で認証(署名はサーバーで生成)
lark.config({
  appId: 'cli_xxx',
  timestamp: '...', nonceStr: '...', signature: '...',
  jsApiList: ['getUserInfo', 'chooseImage', 'scanCode'],
});

署名は jsapi_ticket を取得し、jsapi_ticket & noncestr & timestamp & url を SHA-1 でハッシュしてサーバーサイドで生成します。

主要 JS SDK API

API用途
getUserInfoユーザー ID・テナントキー取得
requestAuthCode免登 code 取得 → user_access_token 交換
scanCode / chooseImageQR スキャン / 画像選択
showToast / openWebURLトースト / 外部 URL
openChat / openProfile / openDocumentアプリ内ナビゲーション

AppLink(ディープリンク)

applink
# Web App を直接開く
https://applink.larksuite.com/client/web_app/open?appId=cli_xxx&mode=sidebar
# チャットを開く
https://applink.larksuite.com/client/chat/open?chatId=oc_xxx
⚠️ 制約
HTTPS 必須。iframe で読み込まれるため Cookie の SameSite に注意。JS SDK の config はページ遷移ごとに実行が必要です。
13 — アプリ形態

Gadget(ミニアプリ)開発ガイド

Gadget は Lark クライアント内で動作するミニアプリ。専用の Block Kit UI(TTML)と tt.* API を使い、ネイティブに近い体験を提供します。

公式: client-docs/gadget/introduction

H5 Web App との違い

比較項目GadgetH5 Web App
技術スタックLark Block Kit(独自)任意の Web 技術
ホスティングLark プラットフォーム上自前サーバー
パフォーマンスネイティブ並みWeb 標準
既存 Web 統合不可可能
審査必要URL 設定のみ

プロジェクト構成

Lark Developer Tool(専用 IDE)で開発します。1 ページは .js(ロジック)/ .ttml(テンプレート)/ .css / .json で構成します。

TTML
<view class="container">
  <text class="title">タスク一覧</text>
  <view tt:for="{{tasks}}" tt:key="id" class="task-item">
    <text>{{item.name}}</text>
    <button size="mini" bindtap="onComplete" data-id="{{item.id}}">完了</button>
  </view>
  <view tt:if="{{tasks.length === 0}}"><text>タスクはありません</text></view>
</view>

ディレクティブ: tt:for / tt:key / tt:if / tt:elif / tt:else / bindtap / bindinput。

ページロジックと API

JavaScript
Page({
  data: { tasks: [], inputValue: '' },
  onLoad() { this.fetchTasks(); },
  async fetchTasks() {
    const res = await tt.request({ url: 'https://your-api.com/tasks', method: 'GET' });
    this.setData({ tasks: res.data });
  },
});

// Lark 連携
tt.login({ success: (res) => { /* res.code をサーバーへ */ } });
tt.scanCode({ success: (res) => console.log(res.result) });
tt.shareAppMessage({ title: '共有', path: '/pages/detail/detail?id=123' });
⚠️ 制約
主パッケージ 4MB(合計 16MB)、ストレージ最大 10MB、HTTPS + ドメインのホワイトリスト設定が必要。外部ページは <web-view> で表示可能。
14 — 自動化・運用

AnyCross ローコード自動化

コードを書かずに、GUI で Lark 内外のサービス連携・ワークフロー自動化・カスタムアプリ構築ができるプラットフォームです。

公式: anycross.larksuite.com

ワークフローの基本構造

flow
トリガー(イベント発生)
    ↓
条件分岐(フィルタリング)
    ↓
アクション(実行)
    ↓
通知(結果報告)

トリガーとアクション

トリガー種別例
Webhook外部システムからの HTTP 通知
スケジュール毎日 / 毎週 / 毎月の定期実行
Lark イベントメッセージ受信、承認完了 など
外部サービスGitHub Push、Jira 更新 など

アクションには データ変換、条件分岐、ループ、HTTP リクエスト、Lark 操作(メッセージ送信・Base 更新)、遅延 などがあります。

対応コネクタ(例)

カテゴリサービス
Lark 内部Docs, Sheets, Base, Approval, Calendar, IM
CRM / PMSalesforce, HubSpot / Jira, Trello, Asana
開発GitHub, GitLab, Jenkins
ストレージ / DBGoogle Drive, Dropbox, S3 / MySQL, PostgreSQL
カスタムWebhook, HTTP Request

ユースケース例

example
# GitHub Issue → Lark 通知
トリガー: GitHub で Issue 作成
  → 変換: タイトル・本文・ラベルを抽出
  → アクション: グループにメッセージカード送信

# 承認完了 → Base 更新 + メール
トリガー: Lark 承認が完了
  → 条件: 結果が「承認」
  → アクション1: Base のステータス更新
  → アクション2: 申請者にメール通知
🔗 API との併用
AnyCross 単体で難しい処理は、HTTP Request アクションで自社 API を呼び出し、複雑なロジックはサーバー側で実行してレスポンスを返す構成にできます。
15 — 自動化・運用

セキュリティ・コンプライアンス

アプリを安全に開発・運用するための、認証情報管理・Webhook 検証・API セキュリティ・データ保護のポイントです。

認証情報とトークンの管理

  • app_id / app_secret は環境変数で管理し、.env は .gitignore に追加
  • 本番では Secret Manager を使用し、定期的にローテーション
  • user_access_token はセッションに、refresh_token は暗号化して保存

Webhook 署名検証(必須)

Node.js
import crypto from 'crypto';

function verify(timestamp, nonce, encryptKey, body, signature) {
  const str = timestamp + nonce + encryptKey + body;
  const hash = crypto.createHash('sha256').update(str).digest('hex');
  return hash === signature;
}
// リプレイ対策: timestamp が現在時刻の±5分以内か確認する

API セキュリティ

API目安レート対策
IM(メッセージ)5 回/秒/アプリキューイング
Bitable(レコード)10 回/秒/アプリバッチ API
Contact(ユーザー)50 回/秒/アプリキャッシュ活用

最小権限の原則: 必要な Scope のみを付与し、使わない権限は申請しないこと。レート超過(99991400)は Exponential backoff でリトライします。

データ保護

  • ユーザー情報は必要最小限のフィールドのみ取得
  • ログには個人情報をマスクして出力(メール・電話・氏名など)
  • 保存データは AES-256-CBC 等で暗号化
✅ セキュリティチェックリスト
  • app_secret を環境変数管理 / .env を .gitignore
  • Webhook 署名検証 + タイムスタンプ検証
  • API のレート制限対策・エラーメッセージに機密情報を含めない
  • HTTPS のみ・不要な Scope を削除・監視/アラート設定
  • 依存パッケージの脆弱性を定期チェック・シークレットの定期ローテーション

コンプライアンス

Lark は TLS 1.2/1.3(転送中)・AES-256(保存時)で暗号化し、SOC 2 Type II / ISO 27001 / GDPR に対応しています。EU ユーザー対象時は GDPR(同意取得・アクセス/削除権・データポータビリティ)、日本では個人情報保護法(利用目的の特定・安全管理措置・第三者提供の制限)への対応が必要です。

参考: larksuite.com/security / privacy-policy

16 — 自動化・運用

トラブルシューティング・FAQ

開発でよく遭遇するエラーと対処、デバッグ手順、よくある質問をまとめます。

ヘルプセンター: larksuite.com/hc/ja-JP

よくあるエラー

コード意味対処
99991668トークン無効/期限切れキャッシュクリア → 再取得
99991663権限不足Scope 追加 → 管理者承認
99991664app_id/app_secret 不正環境変数・アプリ状態を確認
99991672テナント未承認管理コンソールでアプリ承認
99991400レート制限超過backoff + バッチ API
1254043 / 1254044テーブル/フィールド未存在ID・フィールド名の完全一致を確認

パラメータ関連のよくあるミス

Node.js
// 1. user_id_type の指定忘れ → params に必須
params: { receive_id_type: 'open_id' }

// 2. content が文字列でない → JSON.stringify 必須
data: { content: JSON.stringify({ text: 'hello' }) }

// 3. 日付の単位: Bitable=ミリ秒 / Calendar=秒(文字列)

Bot / Webhook が動かない時

  • Bot 有効化・Event Subscription URL・URL 検証(challenge)応答を確認
  • im.message.receive_v1 が有効か、Bot がグループに追加されているか
  • Webhook は HTTPS 必須・外部からアクセス可能か・3 秒以内に応答しているか
Node.js
app.post('/webhook', (req, res) => {
  if (req.body.type === 'url_verification') {
    return res.json({ challenge: req.body.challenge });
  }
  res.json({ code: 0 });               // 即座に応答
  processEvent(req.body).catch(console.error); // 重い処理は非同期
});

デバッグツール

ツール用途
API ExplorerAPI を GUI でテスト
Event Debuggerイベント受信テスト
Log Viewer(Monitoring)API 呼び出しログ確認
ngrokローカルサーバーを HTTPS 公開

FAQ

Q. 無料で開発できますか?

はい。アカウント作成・API 呼び出し(レート制限あり)は基本無料で、テスト企業は最大 50 名まで無料です。

Q. Feishu(飛書)と Lark の違いは?

Lark は海外向け(larksuite.com)、Feishu は中国本土向け(feishu.cn)。SDK は同一で、ドメイン設定で切り替えます。

Q. open_id / union_id / user_id の違いは?

open_id はアプリ固有、union_id は同一開発者の複数アプリ間で共通、user_id はテナント(企業)が設定する社員 ID です。API 呼び出し時は user_id_type で指定します。

Q. 本番公開の流れは?

バージョン作成 → テスト → 審査提出(Marketplace の場合)→ 承認 → テナント管理者がデプロイ、で Workplace に表示されます。

非公式のオリジナル解説教材です。仕様は 公式ドキュメント が正となります。
非公式・日本語オリジナルガイド

Lark Open Platform
日本語開発ガイド

Lark(海外版飛書)のアプリ開発を、日本語で・実装コード付きで解説します。概要から SDK・API・Base・Web App・Gadget・AnyCross・セキュリティまで、手を動かして作れる形で網羅しました。

このガイドについて

本ガイドは Lark Open Platform を使ったアプリ開発を日本語で学ぶためのオリジナル解説です。公式サイトの複製・翻訳ではなく、独自にまとめた入門教材として作成しています。正確な仕様は各ページのリンク先の公式ドキュメントを参照してください。

全セクション

本サイトは非公式のオリジナル解説教材です。Lark / 飛書 は ByteDance の商標です。API 仕様は 公式ドキュメント が正となります。