😉
Next.js のページから Bluesky にツイート(?)する
はじめに
- Next.js で立ち上げたwebページから @atproto/api を叩いて Bluesky に投稿しました。
- 筆者は Next.js を学習し始めて1か月ほどのため、コードの書き方はひどいかもしれませんがご容赦ください。
手順1: アカウントを用意する
- 周囲の方に招待コードを貰ったり公式ページからwait listに登録して待つなどしてアカウントを作成してください。
手順2: Next.js の環境構築をする
- 詳細は割愛します。
- 今回筆者はcreate-next-appのオプションでTypeScript, ESLint, src directory, App Router をyesで環境構築しましたが、各自お好みの環境をご用意ください。
手順3: .envファイルの設定
-
.env
ファイルに Bluesky のユーザ名(またはメールアドレス)、パスワードを記述します。値を{}や""で囲む必要はないです。
.env
NEXT_PUBLIC_BSKY_ID=[ユーザ名(.bsky.socialまで書く)またはメールアドレス]
NEXT_PUBLIC_BSKY_PASSWORD=[パスワード]
- アカウントのパスワードをそのまま書いてもいいですが、パスワードが流出した際にすぐに権限を削除できるApp Passwordsを発行して書くのが丸いと思います。
- 今回はお試しなので雑にClient Componentで書いています。よって変数の最初に
NEXT_PUBLIC_
を付ける必要がありました。
手順4: @atproto/apiをインストールする
npm i @atproto/api
手順5: メインページに書いていく
page.tsx
"use client"
import React, { useRef } from "react";
import { BskyAgent } from "@atproto/api";
- 今回はClient Componentで書いていくので、最初に"use client"と記述する必要があります。
-
@atproto/api
から BskyAgent を import しておきます。
page.tsx
const postBsky = async (text: string | undefined) => {
const agent = new BskyAgent({ service: bskyServer });
await agent.login({
identifier: process.env.NEXT_PUBLIC_BSKY_ID ?? "",
password: process.env.NEXT_PUBLIC_BSKY_PASSWORD ?? "",
});
await agent.post({
text: text,
langs: ["ja"]
});
};
- 投稿する関数
postBsky
を定義します。ツイート内容が入ったtext
引数を受け取ります。 - 先ほど import した BskyAgent を継承した agent を定義し、サーバー名が入った定数 bskyServer を渡します。
- BskyAgentの中の login 関数と手順3で用意した.envファイルの中のID・パスワードを用いてログインします。
- BskyAgentの中の post関数で引数で受け取ったtextをツイートしています。
- post 関数で post をすると初期設定が英語になるらしく、画像のように Translate this post という表示が出てしまいます。post関数の引数に
langs: ["ja"]
を入れることでこれを解決します。
langs設定をしなかった場合の投稿結果
page.tsx
export default function Home() {
const textRef = useRef<HTMLTextAreaElement | null>(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await postBsky(textRef.current?.value);
};
return (
<div>
<form onSubmit={handleSubmit}>
<textarea
ref={textRef}
></textarea>
<button>Send</button>
</form>
</div>
);
}
- このあたりはごく普通の Next.js コードなので詳細は割愛しますが、Sendボタンを押したときに useRef で管理しているツイート内容を先ほど定義した postBsky 関数に入れて投稿しています。
作成したコード全体
page.tsx
"use client"
import React, { useRef } from "react";
import { BskyAgent } from "@atproto/api";
const bskyServer = "https://bsky.social";
const postBsky = async (text: string | undefined) => {
const agent = new BskyAgent({ service: bskyServer });
await agent.login({
identifier: process.env.NEXT_PUBLIC_BSKY_ID ?? "",
password: process.env.NEXT_PUBLIC_BSKY_PASSWORD ?? "",
});
await agent.post({
text: text,
langs: ["ja"]
});
};
export default function Home() {
const textRef = useRef<HTMLTextAreaElement | null>(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
await postBsky(textRef.current?.value);
};
return (
<div>
<form onSubmit={handleSubmit}>
<textarea
ref={textRef}
></textarea>
<button>Send</button>
</form>
</div>
);
}
実際に投稿してみた
- 今回は面倒だったので CSS のデザインは省きました。ごめんなさい。
localhost:3000 の textarea にツイートを入力して送信
ツイートできてた
最後に
- URLリンクを付けてツイートしたいときなどはもう一工夫必要みたいです。↓参考↓
https://zenn.dev/ryo_kawamata/articles/8d1966f6bb0a82
Discussion