以前TwitterのTwilogの代替えとして、mytweetsというツールキットを作りました。

今回、mytweetsBlueskyにも対応させました。

合わせて、Vercelで動くようにしたりとか色々変更したので紹介します。

特徴

  • TwitterのTwitter archive dataをインポートできます
    • 全部の履歴を取り込めます。
  • TwitterBlueskyをサポートしています。
  • アーカイブからの差分をAPIを使って取得して、常に全部のTweetsをまとめて検索できます。
    • このデータの更新はGitHub Actionsで自動化できます
  • 専用のウェブフロントエンドがあります。
    • データに対して全文検索して、結果を表示できます
    • 全文検索にはS3 Selectを使っています
    • Next.js and Vercelであなたしか検索できないようにできます

使い方

全部書くと長いので、詳細はREADMEを読んでください。 ローカルとCIどちらでも基本的に動くようになっています(設定方法が違うだけです)。

おそらく基本的には、一度ローカルでTwitterのアーカイブを一度インポートして、 その後はGitHub Actionで定期的に更新していくという流れになると思います。

ここでは、GitHub Actionsでのデータの更新とVercelにウェブフロントエンドをデプロイする方法を紹介します。

データを保存するS3のBucketとIAMユーザーを作成する

  1. S3でmytweetsのデータを保存するBucketを作成します
  2. 次のPolicyを持つユーザーを作成します。
  3. このユーザーのアクセスキー(AWS の外部で実行されるアプリケーション)を作成し、アクセスキーとアクセスキーシークレットを控えておきます
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "mytweets",
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::{your-mytweets-bucket-name}/*"
        }
    ]
}

Twitterのアーカイブをインポートする

mytweetsはテンプレートリポジトリになっているので、これをForkします。

  1. Twitter archiveをリクエスト
  2. twitter-*.zipというzipをダウンロード
  3. 中身のtweeet*.jstwitter-archives/ にコピーする
twitter-archives/
├── tweet.js
├── tweet-part1.js
└── tweet-part2.js
  1. S3の設定を .env に追加する

リポジトリのルートに.envを作成して、次のように設定します。

S3_AWS_ACCESS_KEY_ID="アクセスキー"
S3_AWS_SECRET_ACCESS_KEY="アクセスキーシークレット"
S3_BUCKET_NAME="作成したバケット名"
  1. データを変換してS3にアップロードする
yarn install
yarn import-twitter-archives # Concvert twitter-archives
yarn upload-s3 # upload to S3

これでアーカイブデータがインポートできます。

GitHub Actionsでのデータの更新

デフォルトで、.github/workflows/update.ymlに定期的にデータを更新するGitHub Actionsが用意されています。

  1. https://github.com/you!!!/mytweets/settings/secrets/actions にアクセスして、Secretsに設定します。
  • S3_AWS_ACCESS_KEY_ID: 作成したアクセスキー
  • S3_AWS_SECRET_ACCESS_KEY: 作成したアクセスキーのシークっと
  • S3_BUCKET_NAME: 作成したS3のバケット名
  • Twitterからデータを取得する場合は、Twitter Appを作成して次の値を設定します
    • TWITTER_APP_KEY
    • TWITTER_APP_SECRET
    • TWITTER_ACCESS_TOKEN
    • TWITTER_ACCESS_SECRET
  • Blueskyからデータを取得する場合は、Bluesky のApp Passwordを作成して次の値を設定します
    • BLUESKY_IDENTIFIER: azu.bsky.social のような値です。
    • BLUESKY_APPPASSWORD: App Passwordの値です。
  1. これで設定完了です

デフォルトでは.github/workflows/update.ymlは毎日1度APIを叩いてデータを更新します。 TwitterかBlueskyどちらから取得するかは、定義されている環境変数で自動的に切り替わります。(試してないですが、両方も動くはず?)

これで、GitHub Actionsで定期的にデータが更新されるようになります。

📝 Forkした直後はGitHub Actionsが無効になってる場合もあるので、https://github.com/{your!}/mytweets/actions に行って有効化する必要があるかもしれません。

ウェブフロントエンドをVercelにデプロイする

Next.jsが動くところならどこでも問題ないですが、ここではVercelにデプロイする方法を紹介します。

  1. Vercelのアカウントを作成する
  2. 新しいプロジェクトを作成する
  3. “Import Git Repository”を選択する
  4. Forkしたリポジトリを選択する
  5. “Root Directory”にweb/を設定する
  6. “Environment Variables”に次の値を設定する
    • S3_AWS_ACCESS_KEY_ID
    • S3_AWS_SECRET_ACCESS_KEY
    • S3_BUCKET_NAME
    • NEXT_PUBLIC_AUTH_KEY=<secure random string>
    • ⚠️ ウェブサイトへのアクセスを制限したい場合は、NEXT_PUBLIC_AUTH_KEYにランダムな文字列を設定してください
    • ℹ️ ウェブサイトへのアクセスを制限しない場合は、NEXT_PUBLIC_AUTH_KEY=publicと設定してください
  7. デプロイする
  8. https://<yourmytweets>.vercel.app/?k=<NEXT_PUBLIC_AUTH_KEY>のようにアクセスできます

NEXT_PUBLIC_AUTH_KEYという環境変数で、とても簡易なパスワード認証が設定できます。 (この辺は将来変更する可能性があります。)

このフロントエンドは、S3からデータを取ってきているので、一度デプロイすれば、S3のデータが更新されると自動的に更新されます。 あとは、検索するだけです。

検索もすごくシンプルに文字列一致を行なっているだけです。

数十万件ぐらいなら1-2秒以内で返ってくるので、個人的には十分な速度です。 まだWebStreamの対応をやってないので、この辺は改善したいです。

まとめ

mytweetsをBlueskyに対応しました。 投稿専用クライアントのpostemとpost-tweetをBlueskyに対応した | Web Scratchでも書きましたが、BlueskyのAPIは比較的シンプルです。(did周りは癖がある)

https://bsky.app/profile/azu.bsky.social/post/3jzlbbvchu52m というのが個別のポストのURLです。 実はこのポストは、did:plcを使ってAuthorを指定してもアクセスできます。

mytweetsだとat://なuriのみしか保存してないので、この辺の仕組みがあってよかった(適当にガチャガチャしてて気づいた)

mytweetsはデータの取得と変換を追加すれば、任意のサービスに対応できると思うので、興味がある方はぜひPRを送ってください。 データ量が多いので、保存するデータはものすごくシンプルにしています。

export type LineTweet = {
    id: string;
    text: string;
    timestamp: number;
};

AWS SDK v3への移行が中途半端なので、S3 Selectの移行ができてないですが、わかる人PRをお願いします。