はじめに
Minds Connect SDK
あなたのアプリケーションをHello Mindsにつなぎます。ユーザーはMindsアカウントでサインインするか、その場でアカウントを作ります。アプリは彼らのマインドを見て、メッセージを送り、一緒に働けます。
Minds Connect SDK は、その接続を行うTypeScriptパッケージです。Webアプリに
BuilderコンソールでOAuthクライアントを登録し、クライアントIDをSDKにコピーし、登録したリダイレクトURIにコールバックのルートを追加します。以下の例はTypeScriptです。
@animocabrands/minds-connect を追加します。ユーザーはHello Mindsでサインインします。ログインと同意画面はそちらにあり、初めてアカウントを作る人も含まれます。戻ってくると、 oauth.client は Mindsクライアントライブラリ で、彼らのマインドの一覧、メッセージ送信、許可されたその先の操作がすぐにできます。Connectは呼び出しの前にセッションを新しく保ちます。画面はあなたのままです。Connectがリダイレクト、保存されたセッション、アプリからのサインアウトを担当します。インストール
型定義はパッケージに含まれます。実行場所はブラウザです。Vite、webpack、または他のバンドラーから読み込みます。Next.jsのApp Routerでは、Reactバインディングを"use client" の境界に置いてください。
npm install @animocabrands/minds-connect| Import | 用途 |
|---|---|
@animocabrands/minds-connect | Reactを使わないTypeScript |
@animocabrands/minds-connect/react | React。オプションのpeerとして react と react-dom 18以降が必要 |
OAuthクライアントを登録する
OAuthクライアント タブでクライアントを作成します。クライアントIDをclientId にコピーしてください。IDは公開情報です。保存するクライアントシークレットはありません。
リダイレクトURIは、サインインを完了するあなたのアプリのページです。認可オリジンは、サインインを開始してよいサイトです。どちらも、登録した値とスキーム、ホスト、ポートまで一致させます。
ユーザーは同じブラウザタブに留めてください。Connectはそのタブの sessionStorage に一度きりの確認を保存します。新しいタブ、ポップアップ、ブックマークしたコールバックURLではサインインを完了できません。
タブの 利用可能なスコープ が、このクライアントの許可リストです。そこで一覧は編集できません。その中から MindsScope で渡してください。一覧に無いスコープを求めると、サインインは失敗します。 MindsScope.Email はサインインしたユーザーのアカウントのメールで、許可リストに含まれます。 MindsScope.MindsEmail は別のスコープで、マインド自身のアドレスです。
React
ルーターを一度MindsConnect で包み、ホームページとコールバックで同じクライアントを共有します。オプションはプロバイダのマウント時に読まれます。変えるときはページを再読み込みしてください。
LoginCallback は redirectUri と同じパスに置きます。 signIn() はユーザーをHello Mindsへ送ります。戻ったあとは oauth.client でBuilder APIを呼びます。
import { BrowserRouter, Route, Routes, useNavigate } from "react-router-dom";
import {
LoginCallback,
MindsConnect,
MindsScope,
useMindsConnect,
type MindsOAuthOptions,
} from "@animocabrands/minds-connect/react";
const opts: MindsOAuthOptions = {
clientId: "YOUR_CLIENT_ID",
redirectUri: `${window.location.origin}/callback`,
scopes: [MindsScope.Email, MindsScope.MindsList],
};
export function Root() {
return (
<BrowserRouter>
<MindsConnect opts={opts}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/callback" element={<Callback />} />
</Routes>
</MindsConnect>
</BrowserRouter>
);
}
function Home() {
const { isInitialized, isAuthenticated, signIn, signOut, oauth } = useMindsConnect();
if (!isInitialized || !oauth) return <p>Loading…</p>;
if (!isAuthenticated) {
return (
<button type="button" onClick={() => signIn()}>
Sign in with Minds
</button>
);
}
async function listMinds() {
const minds = await oauth.client.listMinds();
console.log(minds);
}
return (
<>
<button type="button" onClick={() => listMinds()}>
List minds
</button>
<button type="button" onClick={() => signOut()}>
Log out
</button>
</>
);
}
function Callback() {
const navigate = useNavigate();
return (
<LoginCallback
onSuccess={() => navigate("/", { replace: true })}
onError={(err) => console.error(err)}
/>
);
}LoginCallback に子要素を渡さないと、組み込みの状態表示が出ます。子要素を渡すと、それは常に描画されます。 onSuccess でユーザーをホームへ戻してください。
useMindsConnect() は hasScopes 、 tokens 、 getAccessToken も返します。
Reactを使わない場合
手順は同じです。オプションのモジュールを一つ共有し、ボタンからサインインを始め、コールバックページで終えます。コールバックは新しいページ読み込みなので、同じclientId と redirectUri で MindsOAuth を再び作ります。
onTokensChanged は、このタブでConnectがセッションを書き込むときに動きます。サインアウト、更新、またはストアを消す失敗した更新です。新しいページ読み込みでは動きません。最初の画面を描くときは oauth.tokens を読んでください。
// oauth.ts
import { MindsOAuth, MindsScope, type MindsOAuthOptions } from "@animocabrands/minds-connect";
export const opts: MindsOAuthOptions = {
clientId: "YOUR_CLIENT_ID",
redirectUri: `${window.location.origin}/callback`,
scopes: [MindsScope.Email, MindsScope.MindsList],
};
export const oauth = new MindsOAuth(opts);// main.ts — home page
import { oauth } from "./oauth";
const connectBtn = document.getElementById("connect");
const listBtn = document.getElementById("list");
const logoutBtn = document.getElementById("logout");
oauth.onTokensChanged((tokens) => {
const signedIn = Boolean(tokens);
if (connectBtn) connectBtn.hidden = signedIn;
if (listBtn) listBtn.hidden = !signedIn;
if (logoutBtn) logoutBtn.hidden = !signedIn;
});
connectBtn?.addEventListener("click", async () => {
await oauth.signIn();
});
listBtn?.addEventListener("click", async () => {
const minds = await oauth.client.listMinds();
console.log(minds);
});
logoutBtn?.addEventListener("click", async () => {
await oauth.signOut();
});// callback.ts — same path as redirectUri
import { OAuthRedirectError } from "@animocabrands/minds-connect";
import { oauth } from "./oauth";
try {
await oauth.handleRedirect();
window.location.replace("/");
} catch (err) {
if (err instanceof OAuthRedirectError) {
console.error(err.error, err.errorDescription);
} else {
console.error(err);
}
}handleRedirect() は返されたstateを確認し、コードを交換し、トークンを保存します。ユーザーが拒否した場合、またはstateが一致しない場合は OAuthRedirectError をスローします。
スコープ
スコープは、サインインしたユーザーがアプリに許すことです。SDKを作るとき、必要な一式をopts.scopes に置きます。 MindsScope は、そのIDのTypeScript定数です。両方のエントリからエクスポートされます。
あとから広げるときは、すでに許可されたスコープも含めた 完全な一覧 を signIn({ scopes }) に渡します。その操作が必要かどうかは hasScopes が知らせます。
import { MindsScope } from "@animocabrands/minds-connect";
const scopes = [MindsScope.MindsList, MindsScope.ConversationsList, MindsScope.MessagingSend];
if (oauth.tokens && !oauth.hasScopes(scopes)) {
await oauth.signIn({ scopes });
}isAuthenticated 、 hasScopes 、 signIn に使います。
oauth.client が呼べるのは、その許可に含まれるものだけです。 listMinds() には MindsScope.MindsList が必要です。メッセージを送るには MindsScope.MessagingSend が必要です。メソッド一覧は クライアントライブラリ のページにあります。
MindsScope | Scope | ユーザーが許すこと |
|---|---|---|
MindsScope.Email | email | メールアドレスを見る |
MindsScope.MindsList | minds:list | マインドを見る |
MindsScope.MindsStatus | minds:status | マインドがオンかどうかを見る |
MindsScope.MindsCognition | minds:cognition | マインドの認知を見る |
MindsScope.MindsSkillsList | minds:skills:list | マインドのスキルを見る |
MindsScope.MindsToolsList | minds:tools:list | マインドのツールを見る |
MindsScope.MindsAppsList | minds:apps:list | マインドのアプリを見る |
MindsScope.MindsEmail | minds:email | マインドのメールを見る |
MindsScope.MindsWallets | minds:wallets | マインドのウォレットアドレスを見る |
MindsScope.MindsAwaken | minds:awaken | マインドを目覚めさせる |
MindsScope.MindsEnable | minds:enable | マインドをオンにする |
MindsScope.MindsDisable | minds:disable | マインドをオフにする |
MindsScope.MindsSkillsEquip | minds:skills:equip | マインドにスキルを装備する |
MindsScope.MindsSkillsUnequip | minds:skills:unequip | マインドのスキルを外す |
MindsScope.MindsToolsEquip | minds:tools:equip | マインドにツールを装備する |
MindsScope.MindsToolsUnequip | minds:tools:unequip | マインドのツールを外す |
MindsScope.MindsAppsEquip | minds:apps:equip | マインドにアプリを装備する |
MindsScope.MindsAppsUnequip | minds:apps:unequip | マインドのアプリを外す |
MindsScope.ConversationsCreate | conversations:create | マインドとのチャットを始める |
MindsScope.ConversationsList | conversations:list | チャットを見る |
MindsScope.ConversationsRead | conversations:read | マインドとのチャットを見る |
MindsScope.MessagingSend | messaging:send | そのユーザーとしてメッセージを送る |
MindsScope.MessagingBeacon | messaging:beacon | マインドに声をかける |
MindsScope.MessagingHistory | messaging:history | チャット履歴を見る |
MindsScope.MessagingActivityStream | messaging:activity:stream | 一つのマインドの動きを見る |
MindsScope.MessagingStream | messaging:stream | マインド全体のメッセージイベントを見る |
呼び出しをどこで行うか
バックエンドの無いWebアプリは、Connectだけで足ります。oauth.client はクライアントライブラリで、サインインしたユーザーに向いています。Connectは @animocabrands/minds-client-lib に依存するので、ブラウザからの呼び出しのためにそのパッケージを自分で入れる必要はありません。
const minds = await oauth.client.listMinds();import { createMindsClient } from "@animocabrands/minds-client-lib";
const accessToken = req.headers.authorization?.replace(/^Bearer\s+/i, "");
const minds = await createMindsClient({ accessToken }).listMinds();getAccessToken() は、まだ有効なトークンを返します。期限の60秒前になると更新します。セッションが無いときは null です。 oauth.tokens は保存されたスナップショットで、すでに期限切れのことがあります。バックエンドへ送るときは getAccessToken() を使ってください。
サインアウト
signOut() はアプリ内のセッションを消し、リフレッシュトークンを無効にします。Hello Mindsのアカウントはサインインしたままなので、次の訪問ではアカウントを作り直さずに続けられます。
await oauth.signOut();セッション
セッションはlocalStorage に、 minds_oauth_session: とクライアントIDを繋げたキーで保存されます。再読み込みしても、このオリジンの他のタブでも残ります。ページ上のどのスクリプトも読めます。
別の保存先が要るときは storage を渡します。 TokenStore を拡張し、 get 、 set 、 clear を実装してください。 signOut() はそのストアを消します。
| フィールド | 意味 |
|---|---|
accessToken | Builder API呼び出し用のBearerトークン |
refreshToken | 更新のたびに置き換わる。ストアは最新を保持する |
expiresIn | ストアを読んだ時点の残り秒数 |
scope | 許可されたスコープ。空白区切り。確認には hasScopes を使う |
オプション
同じオブジェクトをnew MindsOAuth(opts) と MindsConnect に渡します。
| 項目 | 必須 | 既定 | 渡すもの |
|---|---|---|---|
clientId | はい | — | OAuthクライアント タブの公開クライアントID |
redirectUri | はい | — | 登録したコールバックURL。オリジンを含む |
scopes | はい | — | 最初の signIn() に使う MindsScope の完全な一覧。空にはできない。アカウントのメールが要るときは MindsScope.Email を含める |
storage | いいえ | "localStorage" | "localStorage"、または独自の TokenStore |
signIn() には state (文字列またはオブジェクト。 handleRedirect から戻る)と scopes (その回だけ opts.scopes を置き換える完全な一覧)も渡せます。
メソッド
| 領域 | 呼び出すもの |
|---|---|
| サインイン | signIn, handleRedirect |
| セッション | getAccessToken, tokens, hasScopes, onTokensChanged, signOut |
| Builder API | client — クライアントライブラリ( listMinds 、 sendMessage 、ほか) |
| React | MindsConnect, useMindsConnect, LoginCallback |
MindsOAuth 、 MindsScope 、 OAuthRedirectError 、 TokenStore 、および型 MindsOAuthOptions 、 TokenSuccess 、 SignInOptions 、 OAuthSession は @animocabrands/minds-connect からエクスポートされます。Reactエントリは MindsScope を再エクスポートします。