Mastodonへの投稿を X (Twitter) にも自動でポストする

最近はもっぱら Mastodon に滞在しているが、MastodonTwitter の投稿を連携したいと思うことがある。 そんな中偶然以下の記事で、Bluesky と Twitter を連携する方法が紹介されているのを見つけたので、この Mastodon 版を作ってみた。

zenn.dev

なお、実装には Google Apps Script を使っているがここでは説明しないので適当にググって調べてほしい。

また、スクリプトで投稿すると bot 判定されて凍結される恐れもあるので、試す人は自己責任でお願いしたい。

変更箇所

記事では連携を

  1. Bluesky の投稿をスプレッドシートに記録する
  2. スプレッドシートに記録された新規の投稿を Twitter へポストする

の二段階で実装しているので、一段目を Mastodon で置き換えれば良い。

元記事の Bluesky 部分のスクリプトを以下で置き換えることでうまくいった

function ListUpMastodonPosts() {
  const userId = "<Mastodon のユーザーID>"
  const accessToken = "<Mastodonのアクセストークン>";
  
  const sheetId = '<利用しているSpreadsheetのID部分>';
  const sheetName = 'List'; // シートの名前

  const sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
  const lastRow = sheet.getLastRow();
  const rowNum = lastRow === 1 ? lastRow : lastRow - 1;
  const postIdRange = sheet.getRange(2, 1, rowNum);
  const postIdValues = postIdRange.getValues().flat();

  const responseJSON = getPosts(userId, accessToken);

  responseJSON.forEach((post) => {
    const postId = post.id;
    const text = stripHtml(post.content);
    const isReply = post.in_reply_to_id !== null;
    const isIncludeEmbed = post.media_attachments.length != 0;

    if (postIdValues.includes(postId)) {
      return;
    }

    sheet.appendRow([postId, text, isReply, isIncludeEmbed, false, false]);
  });
}

function getPosts(userId, accessToken) {
  // fedibird.com は所属インスタンスに応じて変える
  let url = "https://fedibird.com/api/v1/accounts/" + userId + "/statuses"

  const options = {
    "method": "get",
    "contentType": "application/json",
    "headers": {
      "Authorization": `Bearer ${accessToken}`
    }
  };

  let response = UrlFetchApp.fetch(url, options);
  let responseJSON = JSON.parse(response.getContentText());

  return responseJSON;
}

function stripHtml(html) {
  return html.replace(/<\/?[^>]+(>|$)/g, "");
}

Twitter 部分は特に変更しておらず、他の箇所は元記事の通りにやればよい。

以下 Mastodon 特有の注意点を紹介する。

MastodonのユーザIDの取得方法

マストドンのアカウントにはユーザーIDが割り振られており、ブラウザに https://<INSTANCE>/api/v1/accounts/lookup?acct=<USERNAME> と打ち込み、表示された jsonid 要素で確認できる。

dev.to

ここで <INSTANCE> は所属インスタンス名、<USERNAME> はアカウント名。例えば、自分の場合は、https://fedibird.com/api/v1/accounts/lookup?acct=mewon となる。

Mastodon のアクセストークンの取得方法

以下の記事等を参考にしてほしい

www.mizdra.net