TypeScript でボットを作る
このガイドでは、公式の TypeScript SDK である @atproto/api を使って、Bluesky に投稿するボットを書きます。Node.js 20 以降で動作します。
1. アプリパスワードを作成する
ボットとして Bluesky にサインインし、「設定」→「プライバシーとセキュリティ」→「アプリパスワード」 を開いて作成します。ボットはアカウントのメインパスワードではなく、必ずアプリパスワードでサインインします。アプリパスワードなら、アカウントに手を付けずにいつでも取り消せます。
2. プロジェクトを準備する
mkdir my-bot && cd my-bot
npm init -y
npm pkg set type=module
npm install @atproto/api
npm install --save-dev tsx typescript認証情報はコードに書かず、環境変数に置きます。
export BLUESKY_HANDLE="weather.bluesky.bot"
export BLUESKY_APP_PASSWORD="xxxx-xxxx-xxxx-xxxx"3. ボットを書く
// bot.ts: ボットとして 1 回投稿します。`npx tsx bot.ts` で実行します。
import { AtpAgent, RichText } from "@atproto/api";
// ボット自身のアカウントに、アプリパスワードでサインインします
// (「設定」>「プライバシーとセキュリティ」>「アプリパスワード」)。
// メインパスワードは決して使いません。
const identifier = process.env.BLUESKY_HANDLE ?? "";
const password = process.env.BLUESKY_APP_PASSWORD ?? "";
if (!identifier || !password) {
throw new Error("Set BLUESKY_HANDLE and BLUESKY_APP_PASSWORD.");
}
const agent = new AtpAgent({ service: "https://bsky.social" });
await agent.login({ identifier, password });
// RichText がリンク、メンション、ハッシュタグを見つけてクリックできるようにします。
const text = new RichText({
text: "Today: sunny, 21°C. Forecast at https://example.com #weather",
});
await text.detectFacets(agent);
const { uri } = await agent.post({
text: text.text,
facets: text.facets,
createdAt: new Date().toISOString(),
});
console.log(`Posted ${uri}`);このコードがしていること:
AtpAgentは、Bluesky がホストするアカウントのサーバーhttps://bsky.socialと通信します。ボットが別のサーバー(セルフホストの PDS)にある場合は、そのサーバーの URL を指定します。loginは、ハンドルとアプリパスワードでセッションを開きます。RichTextとdetectFacetsは、リンクと#weatherをクリックできる facet に変換します。ただのtextでは、普通の文字として表示されてしまいます。postは投稿を作成し、そのat://URI を返します。
4. 実行する
npx tsx bot.ts対処しておきたいエラー
- レート制限: アカウントやサーバーの操作が多すぎると、Bluesky は
429を返します。間隔を空けて、あとで再試行してください。ベストプラクティス も参照してください。 - 認証情報の期限切れ: アプリパスワードを取り消すと
loginが失敗します。新しいアプリパスワードを作成してください。 - 長すぎる投稿: 投稿は 300 文字(書記素)までです。長い文章は短くするか、スレッドにして投稿します。
次のステップ
- ボットが自動で動くように投稿を予約する。
- ボットに bluesky.bot ハンドルを付ける。
- 詳しくは Bluesky 公式のボットのスターターテンプレート と投稿ガイド(英語)をご覧ください。