😉

Next.js のページから Bluesky にツイート(?)する

2023/09/04に公開

はじめに

  • 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 にツイートを入力して送信

    ツイートできてた

最後に

Discussion