GASでTwitterからMastodonにツイートを転送するbotの構成要素

概要

某所用に指定したアカウントのツイートを自動的にMastodonに転載するbotを作成したのでメモ程度に方法をまとめてみる。

1.GAS

GAS(Google Apps Script)はGoogleが提供しているJavaScriptベースの開発環境です。無料でGoogleの提供するスプレッドシート等のサービスを操作できる便利な機能です。
GASには設定したタイミングで自動的にスクリプトを実行できるトリガー機能があります。トリガーはGoogleのサーバーで実行されるので自前でサーバーを用意する必要がなく、実行間隔も最短1分という無料にあるまじき間隔に設定できるのでTwitterの更新を監視する目的にはうってつけです。

2.GAS + Mastdon API

2.1 GASからMastodonに投稿する

GASからは以下のようなコードでMastodonに投稿することができます。

2.1.1 ステータス用のAPI URLとアクセストークンを用意する。

//Mastodon APIのstatus URL
var api_status_url = "https://{MASTODON INSTANCE URL}/api/v1/statuses";

//Mastodonのアクセストークン
var AccessToken = "{MASTODON ACCESS TOKEN}";

2.1.2 データ内容を記述する

var message = "ほげほげ";//Mastodonに投稿する文字列(URLエンコード必須)

var payload = {
    "status" : message,
    "visibility" : "public"
};

statusはトゥートする内容を表示します。
visibilityでトゥートの公開範囲を設定できます。

public:公開タイムラインとホームタイムライン
unlisted:未収載。ローカルタイムラインに掲載されない
private:非公開。フォロワーのみにトゥートを見せる
direct:@に記載したユーザーだけが見ることができる

spoiler_textを加えることで「CW(Contents Warning)」で投稿することができます。spoiler_textは以下のように記述します。

var message = "ほげほげ";//Mastodonに投稿する文字列(URLエンコード必須)
var spoiler = "観覧注意";//警告文(URLエンコード必須)

var payload = {
    "status" : message,
    "spoiler_text" : spoiler,
    "visibility" : "public"
};

2.1.3 オプションを付けてAPIにアクセスする

var options = {
    "method"  : "post",
    "payload" : JSON.stringify(payload),
    "headers" : {"Authorization" : "Bearer "+ AccessToken},
    "contentType" : "application/json"
};

UrlFetchApp.fetch(api_status_url,options);

オプションを付けてAPIにアクセスすることで投稿が完了します。
必要があればUrlFetchApp.fetchからレスポンスを受け取ることもできます。

2.2 GASからMastodonに画像つきで投稿する

転載元のツイートに画像などのメディアが含まれている場合があるので、メディア付きで投稿する方法を用意しておきます。

2.2.1 メディア用のAPI URLとアクセストークンを用意する。

//Mastodon APIのmedia URL
var api_media_url = "https://{MASTODON INSTANCE URL}/api/v1/media";

//Mastodonのアクセストークン
var AccessToken = {MASTODON ACCESS TOKEN};

トゥート用のAPIとはURLが異なるので注意。アクセストークンは共用。

2.2.2 Blob型の配列にメディアを格納する

//Mediaの配列 Blob型
var medias = [];

//画像URL Yahooロゴ
var image_url = "https://s.yimg.jp/images/top/sp2/cmn/logo-170307.png";

//例えばfetchとgetBlob()でBlob型にする
medias[0] = UrlFetchApp.fetch(image_url).getBlob();

ここではUrlFetchApp.fetchでURLから画像を取得してgetBlobBlod型に変換しています。

2.2.3 Mastodonに画像をアップロードしてメディアIDを得る

//メディアIDを格納する配列
var media_ids = [];
  
if (medias.length>0) {

    medias.forEach(function(media,i){
        
        var params = {
            "method" : "post",
            "headers" : {"Authorization" : "Bearer "+ AccessToken},
            "payload" : {"file" : media}
        };
      
        var res = UrlFetchApp.fetch(api_media_url,params);
        media_ids[i] = JSON.parse(res.getContentText()).id;

    });
}

APIにアクセスしてメディアIDを得ます。

2.2.4 メディアIDの配列をpayloadに含めて投稿する

var payload = {
    "status" : message,
    "media_ids" : media_ids,
    "visibility" : "public"
};

payloadのmedia_idsでメディアIDを渡します。
payload以外は「GASからMastodonに投稿する」と同様です。

3.GAS + Twitter REST API

GASからMastdonにトゥートする準備が整ったので、次はTwitterから情報を取得します。

3.1 Twitter REST APIでユーザ情報を取得

可能な限りアクセス回数を減らしたいので、転載botを作る上で必要な情報が1度に取得できるusers/showを使用します。

3.1.1 アクセストークンを取得

var TWITTER_CONSUMER_KEY = "";
var TWITTER_CONSUMER_SECRET = "";

var token_url = "https://api.twitter.com/oauth2/token";

var key = TWITTER_CONSUMER_KEY + ":" + TWITTER_CONSUMER_SECRET;
var tokenCredential = Utilities.base64EncodeWebSafe(key);

var token_options = {
    headers : {
        "Authorization": "Basic " + tokenCredential,
        "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" 
    },
    method: "post",
    payload: "grant_type=client_credentials"
};

var res = UrlFetchApp.fetch(token_url, token_options);
var token = JSON.parse(res).access_token;

3.1.2 ユーザ情報を取得

var user_name = "Kancolle_STAFF";

var api_url = "https://api.twitter.com/1.1/users/show.json?screen_name=" + user_name;

var api_options = {
    "headers" : {
        "Authorization": "Bearer " + token
    },
    "method" : "get"
};

var res = UrlFetchApp.fetch(api_url, api_options);

//レスポンスをJSON化してTweetを取得
var user_profile = JSON.parse(res.getContentText());

アクセストークンを使ってTwitter APIのusers/showで対象ユーザーのプロフィールを取得します。

3.2 ユーザ情報から最新ツイートを取得

user_profile.status.id_str;//最新ツイートのID
user_profile.status.text://最新ツイートの内容

4.1.2で取得したuser_profileから最新ツイートのidと内容が取得できます。status.id(status.id_str)でツイートID(下記の*部分)を取得できます。
 https://twitter.com/{USER ID}/status/**********************
status.textからは最新のツイートの内容が取得できます。

3.3 プロフィール画像を取得

var image_url = tweets.profile_image_url_https;
image_url = image_url.replace('_normal', '');//元サイズの画像のURL

//Blob型にして色々使える
var image = UrlFetchApp.fetch(image_url).getBlob();

profile_image_url_httpsから幅と高さが48pxの画像のURLが取得できます。
URL中の「_normal」を消すことでオリジナルのサイズの画像URLになります。UrlFetchApp.fetchで画像を取得し、Blob型などに変換して使用します。

この記事が気に入ったらサポートをしてみませんか?