開発者向けドキュメント
このページでは、外部アプリへTsukuttaログイン・データ保存・ランキングを導入する最小手順を解説します。
<script src="https://tsukutta.app/sdk/v1.js" data-app-id="YOUR_APP_ID"></script>
<div data-tsukutta-login></div>こう表示されます
ログインして書いたメモが、あなたのTsukuttaアカウントに保存され、別の端末やブラウザで開いても残ります。「Tsukuttaでログイン」と「クラウド保存」だけで実現していて、サーバーもデータベースも自分で用意していません。まず触ってみてください。
デモを開いて試す →このデモページのHTMLが、そのままコピーして使える完成ソースです(ブラウザの「ページのソースを表示」でコピーできます)。data-app-id を自分のアプリIDに変えれば、あなたのアプリになります。
コードは書きません。下の1行をAI(Cursor / Claude / v0 など)に貼るだけで実装できます。
https://tsukutta.app/sdk/llms.txt を読んで、私のアプリに「Tsukuttaでログイン」ボタンを追加して。app-id は「あなたのアプリID」です。会員機能や課金などでサーバー側の本人確認が必要な場合も、上のプロンプトだけでAIが正しく実装します(下の詳細は手動で組む人向けです)。
動的にレンダリングするアプリでは、要素を指定して1行で呼び出せます。戻り値を呼ぶと後片付け(購読解除・ボタン除去)ができます。
const cleanup = Tsukutta.renderLoginButton("#login", {
theme: "light", // "light" | "dark"
label: "Sign in with", // optional label text
redirect: "/home", // navigate after a successful login (optional)
onLogin: (user) => setUser(user),
});ログイン状態はクライアント側で次のように扱えます。
// Current user (null when signed out)
const user = Tsukutta.user; // { id, name, avatarUrl }
// React to sign-in / sign-out
Tsukutta.onAuthChange((user) => { updateUI(user); });
// Sign out
Tsukutta.logout();「Tsukuttaでログイン」を自分のアプリのアカウントに紐づける場合は、ブラウザで得たトークンを自分のサーバーへ送り、サーバーから検証エンドポイントに問い合わせます。ブラウザから届いた情報をそのまま信用せず、必ずサーバー側で検証してください。
// 1) Browser: send the SDK token to your own server
const user = await Tsukutta.login();
await fetch("/api/auth/tsukutta", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: Tsukutta.token }),
});
// 2) Your server: verify the token with Tsukutta
const res = await fetch("https://tsukutta.app/api/sdk/v1/verify", {
method: "POST",
headers: { Authorization: "Bearer " + token },
});
if (!res.ok) throw new Error("verify failed");
const data = await res.json();
// 3) CRITICAL: check the token audience
if (data.appId !== MY_APP_ID) throw new Error("audience mismatch");
// 4) Link data.userId to your own account system重要: appId (audience) の照合
verify のレスポンスに含まれる appId が自分のアプリIDと一致することを必ず確認してください。トークンはアプリごとに発行されるため、この照合を省略すると、悪意ある別のアプリが正規に取得したトークンを使い回して、あなたのアプリのユーザーになりすましてログインできてしまいます。
実行フロー例:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Tsukutta SDK sample</title>
<script src="https://tsukutta.app/sdk/v1.js" data-app-id="YOUR_APP_ID"></script>
</head>
<body>
<button id="login-button">Login with Tsukutta</button>
<button id="save-button">Save progress</button>
<button id="score-button">Submit score</button>
<pre id="log"></pre>
<script>
const log = (message) => {
const target = document.getElementById("log");
if (target) target.textContent += message + "\n";
};
document.getElementById("login-button")?.addEventListener("click", async () => {
try {
const user = await Tsukutta.login();
log("login: " + user.id);
} catch (error) {
log("login error: " + error);
}
});
document.getElementById("save-button")?.addEventListener("click", async () => {
try {
await Tsukutta.storage.set("progress/level", { level: 3 });
log("storage.set: ok");
} catch (error) {
log("storage.set error: " + error);
}
});
document.getElementById("score-button")?.addEventListener("click", async () => {
try {
const best = await Tsukutta.scores.submit("global", 1200, { stage: 3 });
log("scores.submit: " + best);
} catch (error) {
log("scores.submit error: " + error);
}
});
(async () => {
const top = await Tsukutta.scores.top("global", { limit: 5 });
const views = await Tsukutta.counters.get("visits");
log("scores.top top[0]: " + JSON.stringify(top[0] ?? null));
log("counters.get: " + views);
})();
</script>
</body>
</html>`scores.top` と `counters.get` はログイン不要で呼び出せます。どちらも `app_id` クエリが必要です。
| コード | HTTP | 意味と対処 |
|---|---|---|
| unauthorized | 401 | トークンが無い・無効・期限切れ、または連携が解除済み。再ログインで解消 |
| forbidden | 403 | アプリのSDK連携が無効。マイページのSDK設定を確認 |
| not_found | 404 | 対象が存在しない。storage.get で未保存のキーを読んだ場合など |
| invalid_arg | 400 | 引数が不正 (キー名・値のサイズ・型など) |
| quota_exceeded | 413 / 429 | クォータ超過 (保存容量・キー数は413、アプリの1日あたり呼び出し上限は429) |
| rate_limited | 429 | レート制限 (毎分・毎日の上限) に到達。時間をおいて再試行 |
| server_error | 500 | Tsukutta側のサーバーエラー。時間をおいて再試行 |
| timeout | - | 通信タイムアウト (クライアント側で発生) |
マイページ →対象アプリ→「SDK連携」をONにすると表示されます。未取得のままAIに頼むと実装が止まるので、先にコピーしておきましょう。
「許可サイト」に開発用のURL(例: http://localhost:3000)を登録してください。未登録のオリジンではログインのポップアップがブロックされます。本番ドメインも忘れずに追加します。
data-theme(light / dark)と data-label で調整できます。完全に独自のボタンにしたい場合は、自分のボタンのクリックで Tsukutta.login() を呼んでください。
ユーザーID・表示名・アバターURLの3つです。メールアドレスなどの個人情報は渡されません。
Web上で動くアプリなら何でも使えます。素のHTMLでも、React・Vueなどのフレームワークでも同じ2行で導入できます。
クラウド保存(storage)・ランキング(scores)・カウンター(counters)が使えます。使い方は上の折りたたみと「コピペで動く1ファイルサンプル」を参照してください。