Lark Open Platform 概要
まずはプラットフォームの全体像と、開発で「何ができるか」をつかみましょう。
Lark とは
Lark(海外版飛書 / Feishu)は、ByteDance が提供するエンタープライズ向けコラボレーションプラットフォームです。メッセージング、ビデオ会議、ドキュメント、プロジェクト管理、承認フローなどを1つに統合した「スーパーアプリ」として位置づけられています。
主要機能
| 機能 | 説明 |
|---|---|
| Messenger | チャット、グループ、Bot連携。チャット内でアプリと直接対話 |
| Meetings | リアルタイム翻訳、自動議事録生成、ビデオ会議 |
| Docs | リアルタイム共同編集、権限管理付きドキュメント |
| Base (Bitable) | 多次元テーブル。自動化・データ分析・プロジェクト管理 |
| Calendar / Approval | スケジュール管理 / ワークフロー承認 |
| Workplace / Wiki | ポータル / ナレッジベース |
Open Platform でできること
- Server API 呼び出し — メッセージ送信、ユーザー管理、ドキュメント操作 など
- イベント購読 — メッセージ受信、ユーザー変更などのリアルタイム通知
- Bot 開発 — チャット内で動作するインタラクティブ Bot
- カスタムアプリ / Docs Add-on / Base Extension — Lark 内に埋め込む拡張
- Workflow Automation — AnyCross によるローコード自動化
アプリの種類
| 種類 | 説明 | 公開範囲 |
|---|---|---|
| Custom App | 特定の企業内でのみ使用 | 社内のみ |
| Marketplace App | App Directory に公開 | 全企業 |
ドメインの違い
| ドメイン | 対象 |
|---|---|
open.larksuite.com | Lark(海外版) |
open.feishu.cn | 飛書(中国国内版) |
SDK / API は共通ですが、ドメイン指定が異なります。Node SDK では lark.Domain.Lark / lark.Domain.Feishu で切り替えます。
アーキテクチャの全体像
┌─────────────────────────────────────────────┐
│ 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 Console | open.larksuite.com/app |
| Documentation | open.larksuite.com/document |
| API Explorer | open.larksuite.com/api-explorer |
| Help Center (JP) | larksuite.com/hc/ja-JP |
アプリ開発フロー
Developer Console でのアプリ作成から公開まで、全体の流れを6ステップで押さえます。
開発フロー全体像
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 Secret | API 認証用シークレット |
| Encrypt Key | イベント暗号化用(任意) |
| Verification Token | Webhook 検証用 |
Step 3: 権限(Scope)設定
「Permissions & Scopes」で、利用する API の権限を追加します。権限追加後は企業管理者の承認が必要な場合があります。
| カテゴリ | 権限例 | 説明 |
|---|---|---|
| IM | im:message, im:message:send_as_bot | メッセージ読取・送信 |
| Contact | contact:user.base:readonly | ユーザー・部署情報読取 |
| Bitable | bitable:app | Bitable 操作 |
| Docs / Calendar / Approval | docs: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 営業日)が必要
環境変数とプロジェクト構成の例
LARK_APP_ID=cli_xxxxxxxxxxxx
LARK_APP_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx
LARK_ENCRYPT_KEY=xxxxxxxxxxxx # イベント暗号化(任意)
LARK_VERIFICATION_TOKEN=xxxxxxxxxxxx # Webhook 検証用認証・認可
API を呼び出すためのトークンの種類と取得方法、OAuth フロー、Webhook 検証を押さえます。
Access Token の種類
| 種類 | 用途 | 取得 | 有効期限 |
|---|---|---|---|
| tenant_access_token | アプリとして呼び出し(最も一般的) | App ID + Secret | 2時間 |
| app_access_token | アプリレベルの操作 | App ID + Secret | 2時間 |
| user_access_token | ユーザーの代理として操作 | OAuth 2.0 | 2時間(更新可) |
tenant_access_token の取得
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 はトークンの取得・キャッシュ・自動更新を内部で処理します。手動管理は不要です。
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)
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 リクエストが届きます。同じ値をそのまま返します。
// 受信
{ "challenge": "ajls384kdjx98XX", "type": "url_verification" }
// 返却
{ "challenge": "ajls384kdjx98XX" }Encrypt Key を設定するとイベントは AES-256-CBC で暗号化され、SDK が自動で復号します。署名検証の実装は セキュリティ を参照。
認証系のエラーコード
| コード | 意味 | 対処 |
|---|---|---|
99991668 | トークン無効 | トークン再取得 |
99991663 | 権限不足 | Scope 追加 + 管理者承認 |
99991664 | app_id / app_secret 不正 | 認証情報を確認 |
99991672 | テナント未承認 | 管理者にアプリ承認を依頼 |
Bot 開発
チャット内でユーザーと対話する Bot を作ります。自動応答・通知・ワークフロートリガーに使えます。
Bot の種類
| 種類 | 説明 | 使い方 |
|---|---|---|
| Custom Bot | 企業内で作成する Bot | Developer Console で作成 |
| Webhook Bot | グループ内 Webhook | URL に POST するだけ |
開発フロー
アプリ作成 →「Bot」有効化 → Event Subscription URL 設定 → 権限追加 → ハンドラ実装 → テスト → 公開。購読イベントは im.message.receive_v1(メッセージ受信)などを追加します。
実装例:エコー Bot(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 -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_v1 | Bot がグループ追加 |
contact.user.created_v3 | ユーザー作成 |
approval.approval.updated | 承認ステータス変更 |
- Event Subscription の URL が正しいか(Challenge が通っているか)
- 権限が足りているか / 管理者承認が完了しているか
- Bot がグループに追加されているか
contentは JSON 文字列(JSON.stringify()必須)- Webhook は 3 秒以内にレスポンスを返す(重い処理は非同期に)
インタラクティブメッセージカード
ボタン・フォーム・画像・マークダウンを組み合わせたリッチな UI をメッセージとして送信します。
基本構造
{
"config": { "wide_screen_mode": true },
"header": {
"template": "blue",
"title": { "content": "カードタイトル", "tag": "plain_text" }
},
"elements": [ /* 本文要素 */ ]
}ヘッダーカラー
| template | 色 | template | 色 |
|---|---|---|---|
blue | 青 | red | 赤 |
green | 緑 | orange | オレンジ |
turquoise | ターコイズ | grey | グレー |
アクション(ボタン)
{
"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)
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 を渡します。
カードアクションの処理
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));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_type | content 例 |
|---|---|
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 / Mail | Wiki ノード、ビデオ会議、タスク、メール |
共通レスポンス形式とエラーコード
{
"code": 0, // 0 = 成功, 非0 = エラー
"msg": "success",
"data": { /* レスポンスデータ */ }
}| コード | 説明 |
|---|---|
| 0 | 成功 |
| 10001 | パラメータエラー |
| 10002 | リクエスト頻度超過 |
| 10003 | 認証失敗 |
| 10004 | 権限不足 |
| 10005 | リソースが見つからない |
Node.js SDK リファレンス
パッケージ @larksuiteoapi/node-sdk。トークン管理・ページネーション・イベント処理を SDK に任せられます。
リポジトリ: github.com/larksuite/node-sdk
インストールとクライアント作成
npm install @larksuiteoapi/node-sdkimport * 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(パスパラメータ)を渡します。
// メッセージ送信
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", {...}ページネーション(自動イテレータ)
for await (const items of await client.contact.user.listWithIterator({
params: { department_id: '0', page_size: 20 },
})) {
console.log(items);
}イベント購読
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));ファイル操作
// アップロード
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() で直接呼び出せます。
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
Python SDK リファレンス
パッケージ lark-oapi(MIT ライセンス)。ビルダーパターンでリクエストを組み立てます。
リポジトリ: github.com/larksuite/oapi-sdk-python(v2_main)
インストールとクライアント作成
pip install lark-oapiimport 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()メッセージ送信
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)
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) を使います。
主要モジュール
| モジュール | インポート |
|---|---|
| IM | lark_oapi.api.im.v1 |
| Contact | lark_oapi.api.contact.v3 |
| Bitable | lark_oapi.api.bitable.v1 |
| Docx / Sheets / Wiki | lark_oapi.api.docx.v1 ほか |
| Calendar / Approval / VC / Task | lark_oapi.api.calendar.v4 ほか |
Lark Base(Bitable)概要
Lark Base(Bitable)は多次元テーブル。見た目はスプレッドシートですが、中身はフィールド型を持つデータベースに近い機能です。
基本概念
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 |
| 単一選択 | 3 | URL | 15 |
| 複数選択 | 4 | 添付ファイル | 17 |
| 日付 | 5 | リンク(他テーブル参照) | 18 |
ほかに ルックアップ(19)、数式(20)、作成日時(1001)、更新日時(1002)、作成者(1003)、自動番号(1005) などがあります。
ビューの種類
| ビュー | 適した用途 |
|---|---|
| Grid | データ入力・一覧(表形式) |
| Kanban | ステータス管理(単一選択で列分け) |
| Gantt | スケジュール管理(日付でタイムライン) |
| Form | 外部共有可能な入力フォーム |
| Calendar / Gallery | 日程管理 / 画像付きカード表示 |
識別子の取得
Bitable の URL から app_token・table_id・view_id を取得できます。
https://xxx.larksuite.com/base/BascXXXXXX?table=tblYYYYYY&view=vewZZZZZZ
^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^
app_token table_id view_idBase API 実装ガイド(Node.js)
Bitable を Node.js SDK で操作します。権限は bitable:app(読み書き)または bitable:app:readonly が必要です。
レコード CRUD
// 作成
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 },
});フィルタとソート
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。
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' }] |
1254043(テーブル未存在)、1254044(フィールド名不一致)、1254607(値の型不一致)。Base Extension(拡張機能)開発
Base Extension は、Base に導入された柔軟なオープン機能です。コードを書いてカスタム機能を実装し、Base をより強力な業務システムに拡張できます。
主なユースケース
- バッチデータ処理 — フィールド内の非構造化データから特定のデータを抽出し、他のフィールドで利用する
- カスタム関数 — 特定の機能を実装し、計算能力を強化する関数を書く
- データ同期 — データを読み書きし、サードパーティのシステムと接続・連携する
準備
スクリプトは「有効な URL」さえあれば利用できます。ドキュメントの例では Replit(ブラウザ上でコードを書いて実行できるオンライン環境)を使いますが、サービスがデプロイされていれば Vercel / GitHub / localhost / 自前サーバー など、どのプラットフォームでも構いません。
フロントエンド vs サーバーサイド
| 種別 | 読み書きの基礎 | ユーザーとの対話 | スクリプト/Base を閉じた後も実行 |
|---|---|---|---|
| フロントエンドスクリプト | ✅ | ✅ | ❌ |
| サーバーサイドスクリプト | ✅ | ❌ | ✅ |
テンプレート
| 種別 | テンプレート | エントリーポイント |
|---|---|---|
| フロントエンド | HTML | src/index.ts |
| React | src/App.tsx | |
| Vue | src/App.vue | |
| フロント+サーバー | Next.js | pages/index.tsx |
| サーバーサイド | Node Express | server.ts |
技術スタックと用途に応じてテンプレートを選び、右上の「Fork」ボタンで Replit アカウントにフォークします。
フロントエンドスクリプトの開発手順
- フロントエンドテンプレートを選び「Fork」でフォーク
- IDE 上部の「Run」でプロジェクトを起動し、右側のプレビュー URL をコピー
- 任意の Base を開き、右上の「Base Extensions」をクリック
- 「+ スクリプトを追加」→ プレビュー URL を入力 →「確認」で実行
IDE でコードを変更すると拡張スクリプトが動的に更新されます。デバッグ情報は Base 上で F12 を押してコンソールで確認できます。
コード例:検索と置換(React / Base JS SDK)
現在のテーブルの「複数行テキスト(多行文本 / Multiline)」フィールドで hi を hello に置換する例です。
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>
);
}サーバーサイドスクリプトの開発手順
- サーバーサイドテンプレート(Node Express など)を選び「Fork」
- 「Run」で起動し、プレビュー URL をコピー
- Base の「Base Extensions」を開く
- Replit で personalBaseToken(認証コード) と appToken を取得して利用
- 「+ スクリプトを追加」→ プレビュー URL を入力 →「確認」で実行
サーバーサイド拡張は Automations の HTTP リクエストと組み合わせ、「新規レコード追加時」「レコード変更時」など各種トリガー条件で起動することもできます。
ホスティング方式の比較
| 方式 | スリープ | 環境 | 想定シナリオ |
|---|---|---|---|
| Replit デフォルト | 一定時間の非アクティブでスリープ(Always On で回避) | 開発/本番の区別なし(変更が本番に直接影響) | 個人利用・開発/テスト |
| Replit Deployment | 一定時間でスリープ | 開発と本番を分離 | 一般提供するサービス |
| Base Hosting | 自動スリープしない | 開発と本番を分離(変更が本番に直接影響しない) | 広く公開・利用してほしい優れた事例 |
Base Hosting へ提出するには、共有フォームに記入 → 承認されるとプロジェクトがフォーク・デプロイされます。
トークンと識別子
- personalBaseToken — 右上の「認証コードを取得」→ ポップアップで「認証コードを有効にする」で取得
- appToken / table_id / view_id — いずれも Base の URL から取得(Base 概要参照)
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 は公式ドキュメントを参照してください。
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 の初期化と認証
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 / chooseImage | QR スキャン / 画像選択 |
showToast / openWebURL | トースト / 外部 URL |
openChat / openProfile / openDocument | アプリ内ナビゲーション |
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_xxxconfig はページ遷移ごとに実行が必要です。Gadget(ミニアプリ)開発ガイド
Gadget は Lark クライアント内で動作するミニアプリ。専用の Block Kit UI(TTML)と tt.* API を使い、ネイティブに近い体験を提供します。
公式: client-docs/gadget/introduction
H5 Web App との違い
| 比較項目 | Gadget | H5 Web App |
|---|---|---|
| 技術スタック | Lark Block Kit(独自) | 任意の Web 技術 |
| ホスティング | Lark プラットフォーム上 | 自前サーバー |
| パフォーマンス | ネイティブ並み | Web 標準 |
| 既存 Web 統合 | 不可 | 可能 |
| 審査 | 必要 | URL 設定のみ |
プロジェクト構成
Lark Developer Tool(専用 IDE)で開発します。1 ページは .js(ロジック)/ .ttml(テンプレート)/ .css / .json で構成します。
<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
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' });<web-view> で表示可能。AnyCross ローコード自動化
コードを書かずに、GUI で Lark 内外のサービス連携・ワークフロー自動化・カスタムアプリ構築ができるプラットフォームです。
ワークフローの基本構造
トリガー(イベント発生)
↓
条件分岐(フィルタリング)
↓
アクション(実行)
↓
通知(結果報告)トリガーとアクション
| トリガー種別 | 例 |
|---|---|
| Webhook | 外部システムからの HTTP 通知 |
| スケジュール | 毎日 / 毎週 / 毎月の定期実行 |
| Lark イベント | メッセージ受信、承認完了 など |
| 外部サービス | GitHub Push、Jira 更新 など |
アクションには データ変換、条件分岐、ループ、HTTP リクエスト、Lark 操作(メッセージ送信・Base 更新)、遅延 などがあります。
対応コネクタ(例)
| カテゴリ | サービス |
|---|---|
| Lark 内部 | Docs, Sheets, Base, Approval, Calendar, IM |
| CRM / PM | Salesforce, HubSpot / Jira, Trello, Asana |
| 開発 | GitHub, GitLab, Jenkins |
| ストレージ / DB | Google Drive, Dropbox, S3 / MySQL, PostgreSQL |
| カスタム | Webhook, HTTP Request |
ユースケース例
# GitHub Issue → Lark 通知
トリガー: GitHub で Issue 作成
→ 変換: タイトル・本文・ラベルを抽出
→ アクション: グループにメッセージカード送信
# 承認完了 → Base 更新 + メール
トリガー: Lark 承認が完了
→ 条件: 結果が「承認」
→ アクション1: Base のステータス更新
→ アクション2: 申請者にメール通知セキュリティ・コンプライアンス
アプリを安全に開発・運用するための、認証情報管理・Webhook 検証・API セキュリティ・データ保護のポイントです。
認証情報とトークンの管理
app_id/app_secretは環境変数で管理し、.envは.gitignoreに追加- 本番では Secret Manager を使用し、定期的にローテーション
- user_access_token はセッションに、refresh_token は暗号化して保存
Webhook 署名検証(必須)
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(同意取得・アクセス/削除権・データポータビリティ)、日本では個人情報保護法(利用目的の特定・安全管理措置・第三者提供の制限)への対応が必要です。
トラブルシューティング・FAQ
開発でよく遭遇するエラーと対処、デバッグ手順、よくある質問をまとめます。
ヘルプセンター: larksuite.com/hc/ja-JP
よくあるエラー
| コード | 意味 | 対処 |
|---|---|---|
99991668 | トークン無効/期限切れ | キャッシュクリア → 再取得 |
99991663 | 権限不足 | Scope 追加 → 管理者承認 |
99991664 | app_id/app_secret 不正 | 環境変数・アプリ状態を確認 |
99991672 | テナント未承認 | 管理コンソールでアプリ承認 |
99991400 | レート制限超過 | backoff + バッチ API |
1254043 / 1254044 | テーブル/フィールド未存在 | ID・フィールド名の完全一致を確認 |
パラメータ関連のよくあるミス
// 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 秒以内に応答しているか
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 Explorer | API を 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 公式の一次情報です。
- 本ガイドの該当セクションで大枠・概略をつかむ
- 下の公式リンクを開き、AI に要約・解説させながら精読・理解する
- 分かったことをメモ(ナレッジ)として積む
- 次のトピックへ。これを繰り返して Lark Developer を体系的に理解する
開発の入口
| ページ | 内容 |
|---|---|
| Documentation Home | 公式ドキュメントの入口。全カテゴリの起点 |
| Developer Console | アプリ作成・権限・公開の管理画面 |
| API Explorer | 各 API を GUI で試せるツール |
| Card Builder | メッセージカードを視覚的に作成 |
| Changelog | API・機能の更新履歴 |
| Help Center(日本語) | 製品ヘルプ(日本語) |
API リファレンス
| ページ | 内容 |
|---|---|
| Server API 一覧 | 全 Server API の一覧。ここから IM / Contact / Docx / Bitable / Sheets / Calendar / Approval / VC / Drive / Wiki へ |
| API Explorer | 個々の API の入出力を実際に試す |
SDK
| ページ | 内容 |
|---|---|
| node-sdk(GitHub) | Node.js SDK 本体・README・サンプル |
| oapi-sdk-python(GitHub) | Python SDK 本体(v2_main) |
| oapi-sdk-python-demo | Python 実装サンプル集 |
クライアント開発(チュートリアル)
| ページ | 内容 |
|---|---|
| H5 Web App 入門 | H5 Web App の概要とクライアント連携 |
| Gadget 入門 | ミニアプリ開発の概要 |
| Bot を5分で開発 | Bot のクイックスタート |
| Gadget を5分で開発 | ミニアプリのクイックスタート |
| Web App を5分で統合 | Web App のクイックスタート |
自動化・法務・サポート
| ページ | 内容 |
|---|---|
| AnyCross | ノーコード自動化プラットフォーム |
| Developer Tools | 開発者向けツール一覧 |
| Security / Privacy / Terms | セキュリティ・プライバシー・利用規約 |
Lark Open Platform
日本語開発ガイド
Lark(海外版飛書)のアプリ開発を、日本語で・実装コード付きで解説します。概要から SDK・API・Base・Web App・Gadget・AnyCross・セキュリティまで、手を動かして作れる形で網羅しました。
このガイドについて
本ガイドは Lark Open Platform を使ったアプリ開発を日本語で学ぶためのオリジナル解説です。公式サイトの複製・翻訳ではなく、独自にまとめた入門教材として作成しています。正確な仕様は各ページのリンク先の公式ドキュメントを参照してください。
全セクション
Open Platform 概要
全体像・アプリの種類・アーキテクチャ。
アプリ開発フロー
作成から公開までの6ステップ。
認証・認可
トークン・OAuth・Webhook 検証。
Bot 開発
イベント購読・応答・Webhook Bot。
メッセージカード
ボタン・フォーム付き UI。
API カテゴリ一覧
IM・Contact ほか主要エンドポイント。
Node.js SDK
クライアント・イベント・ファイル。
Python SDK
lark-oapi のビルダー API。
Base 概要
フィールド型・ビュー・識別子。
Base API 実装
レコード CRUD・フィルタ・バッチ。
Base Extension
拡張スクリプト・JS SDK・ホスティング。
H5 Web App
JS SDK・表示モード・AppLink。
Gadget
TTML・tt.* API・制約。
AnyCross
ノーコード連携・自動化。
セキュリティ
署名検証・レート・データ保護。
トラブル・FAQ
エラー対処・デバッグ・FAQ。
公式リンク集
深掘り用の公式ページ一覧。