情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

Node.jsでMastodonのフォロワーやフォロイーを取得する

そもそもMastodonとは何?

Mastodonとは何かについて知りたい方は下の記事を参照してください。

準備

Mastodonのフォロワーやフォロイーを取得するには取得するユーザーの種類に応じて適切なMastodonのAPIを呼び出さなければなりません。

MastodonのAPIを呼び出すにはアクセストークンが必要になりますので、事前に取得しておく必要があります。

Mastodonのアクセストークンを手動で取得する方法については下の記事を参照してください。

Mastodonのアクセストークンを自動で取得する方法については後日記事を書く予定です。

フォロワーやフォロイーの取得

下のようなユーザーを取得するにはユーザーのインスタンスの下のようなパスに対してGETHTTPリクエストを行います。

  • 特定の番号のユーザーがフォローされているユーザー(特定の番号のユーザーのフォロワー)・・・/api/v1/accounts/:id/followers
  • 特定の番号のユーザーがフォローしているユーザー(特定の番号のユーザーのフォロイー)・・・/api/v1/accounts/:id/following

ただし、パスの:idの部分にはユーザーの番号を指定します。たとえば、番号が12345であるユーザーがフォローされているユーザーを取得するにはユーザーのインスタンスの/api/v1/accounts/12345/followersパスに対してGETHTTPリクエストを行います。フォローしているユーザーを取得するにはユーザーのインスタンスの/api/v1/accounts/12345/followingパスに対してGETHTTPリクエストを行います。

また、上の2つのHTTPリクエストには下のようなクエリパラメータを指定することもできます。

  • max_id・・・ユーザーの特定の範囲のフォロワーやフォロイーを取得する場合に指定します。範囲の上端を番号として指定します。このクエリパラメータを指定した場合には指定した番号以下で、指定した番号に最も近い0人以上のフォロワーやフォロイーが取得されます。
  • since_id・・・ユーザーの特定の範囲のフォロワーやフォロイーを取得する場合に指定します。範囲の下端を番号として指定します。このクエリパラメータを指定した場合には指定した番号より大きく、指定した番号に最も近い0人以上のフォロワーやフォロイーが取得されます。
  • limit・・・取得するユーザーの数の最大値を指定します。

また、上の2つのHTTPリクエストに対するHTTPレスポンスのボディはユーザーを表すオブジェクトの配列から成るJSONとなります。

ユーザーを表すオブジェクトは下のようなプロパティを有します。

  • id・・・ユーザーの番号です。
  • username・・・ユーザーの識別子です。
  • acct・・・ユーザーの完全な識別子です。ユーザーが異なるインスタンスに所属している場合にはインスタンスの名称が含まれます。
  • display_name・・・ユーザーの名称です。
  • locked・・・ユーザーをフォローする場合にユーザーからの承認が必要かどうかです。
  • created_at・・・ユーザーが作成された日時です。
  • followers_count・・・ユーザーがフォローされているユーザー(ユーザーのフォロワー)の数です。
  • following_count・・・ユーザーがフォローしているユーザー(ユーザーのフォロイー)の数です。
  • statuses_count・・・ユーザーのトゥートの数です。
  • note・・・ユーザーのプロフィールです。
  • url・・・ユーザーのウェブページのURLです。
  • avatar・・・ユーザーの画像のURLです。
  • header・・・ユーザーのヘッダ画像のURLです。

また、上の2つのHTTPリクエストに対するHTTPレスポンスのLinkヘッダフィールドにはボディに含まれているフォロワーやフォロイーの前のフォロワーやフォロイーを取得するためのリンクを表すprevリンクと後のフォロワーやフォロイーを取得するためのリンクを表すnextリンクが設定されています。

なお、GETHTTPリクエストを行う方法に関しては下の記事を参照してください。

ただし、HTTPリクエストを行う際にはAuthorizationヘッダフィールドの値にアクセストークンを設定しなければなりません。ただし、アクセストークンの冒頭にはBearerと1文字の空白を付加しなければなりませんので注意してください。

サンプルコード1

mstdn.jpインスタンスの番号が42480のユーザーのフォロワーを5人取得するGETHTTPリクエストを行い、HTTPレスポンスのボディをJSONとして標準出力に出力します。また、HTTPレスポンスのLinkヘッダフィールドの値も標準出力に出力します。

mastodon-follower.js

var http = require('http');
var https = require('https');
var concatStream = require('concat-stream');
var mimelib = require('mimelib');
var jschardet = require('jschardet');
var iconvLite = require('iconv-lite');
var pump = require('pump');

var u = {
    protocol: 'https:', 
    hostname: 'mstdn.jp', 
    path: '/api/v1/accounts/42480/followers?limit=5', 
    headers: {
        'Authorization': 'Bearer 1a5429d614323f78d6254d4c1a2446c53f6a027807ff73a2a237963fecc9ff44'
    }
};

var client = (u.protocol === 'https:' ? https : http).get(u, function (res) {
    if (res.statusCode === 200) {
        var writable = concatStream(function (data) {
            var encoding = undefined;
            if (res.headers['content-type'] !== undefined) {
                encoding = mimelib.parseHeaderLine(res.headers['content-type']).charset;
            }
            if (encoding === undefined) {
                encoding = jschardet.detect(data).encoding;
            }
            if (encoding !== undefined && iconvLite.encodingExists(encoding)) {
                console.log(JSON.parse(iconvLite.decode(data, encoding)));
                console.log(res.headers['link']);
            }
            else {
                console.error('can\'t detect encoding.');
                process.exit(1);
            }
        });
        pump(res, writable, function (err) {
            if (err) {
                console.error(err);
                process.exit(1);
            }
        });
    }
    else {
        console.error(http.STATUS_CODES[res.statusCode]);
        process.exit(1);
    }
});
client.setTimeout(10000, function () {
    console.error('timeouted.');
    client.abort();
});
client.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

実行結果

C:\work\node>node mastodon-follower.js
[ { id: 140389,
    username: 'AKILAS',
    acct: 'AKILAS',
    display_name: 'AKILAS:white_check_mark: ',
    locked: false,
    created_at: '2017-04-21T13:16:52.290Z',
    followers_count: 759,
    following_count: 1568,
    statuses_count: 25,
    note: '<p>プログラムを組んだりするのが生業です。<br />気軽にフォローしてくださいませ!</p>',
    url: 'https://mstdn.jp/@AKILAS',
    avatar: 'https://media.mstdn.jp/images/accounts/avatars/000/140/389/original/98f298a72e25cb34.jpg',
    avatar_static: 'https://media.mstdn.jp/images/accounts/avatars/000/140/389/original/98f298a72e25cb34.jpg',
    header: '/headers/original/missing.png',
    header_static: '/headers/original/missing.png' },
  { id: 174791,
    username: 'Tama',
    acct: 'Tama@friends.nico',
    display_name: '♠♥ たま ♦♣',
    locked: false,
    created_at: '2017-04-26T12:14:41.088Z',
    followers_count: 315,
    following_count: 320,
    statuses_count: 205,
    note: '♠♥ 楽しいことする ♦♣/セイバー/エゴグラムabaac型/変化系/アニメ/Fate/PHYCO-PASS/絶望先生/四畳半神話大系/キタエリ/V系/ヴィジュアル系/ヴィドール/シド
/Diaura/サブカル/飲み会/ポケモン/ジャンプオタク/漫画/イベント/オフ会/https://friends.nico/@Tama',
    url: 'https://friends.nico/@Tama',
    avatar: 'https://media.mstdn.jp/images/accounts/avatars/000/174/791/original/f242c1083a9949c3.jpg',
    avatar_static: 'https://media.mstdn.jp/images/accounts/avatars/000/174/791/original/f242c1083a9949c3.jpg',
    header: 'https://media.mstdn.jp/images/accounts/headers/000/174/791/original/1a485bb6dff0bb1e.jpg',
    header_static: 'https://media.mstdn.jp/images/accounts/headers/000/174/791/original/1a485bb6dff0bb1e.jpg' },
  { id: 167019,
    username: 'ssmatome',
    acct: 'ssmatome@pawoo.net',
    display_name: 'SSまとめ速報✅',
    locked: false,
    created_at: '2017-04-25T06:10:55.983Z',
    followers_count: 749,
    following_count: 5923,
    statuses_count: 197,
    note: '<p>厳選したSSまとめ記事を配信♪SSとはショートストーリーの事で、何百通りものストーリーが楽しめます!へいらっしゃい♪</p>',
    url: 'https://pawoo.net/@ssmatome',
    avatar: 'https://media.mstdn.jp/images/accounts/avatars/000/167/019/original/e9b27649d4991879.png',
    avatar_static: 'https://media.mstdn.jp/images/accounts/avatars/000/167/019/original/e9b27649d4991879.png',
    header: 'https://media.mstdn.jp/images/accounts/headers/000/167/019/original/816c0f79a4a498e0.png',
    header_static: 'https://media.mstdn.jp/images/accounts/headers/000/167/019/original/816c0f79a4a498e0.png' },
  { id: 195985,
    username: 'pokemon_matome',
    acct: 'pokemon_matome@pawoo.net',
    display_name: 'ポケモンまとめ速報',
    locked: false,
    created_at: '2017-05-01T00:56:18.823Z',
    followers_count: 458,
    following_count: 4069,
    statuses_count: 128,
    note: '<p>ポケモンに関する記事を配信します♪</p>',
    url: 'https://pawoo.net/@pokemon_matome',
    avatar: 'https://media.mstdn.jp/images/accounts/avatars/000/195/985/original/3e4fb4b1fe99e100.jpg',
    avatar_static: 'https://media.mstdn.jp/images/accounts/avatars/000/195/985/original/3e4fb4b1fe99e100.jpg',
    header: '/headers/original/missing.png',
    header_static: '/headers/original/missing.png' },
  { id: 188222,
    username: 'norida4351',
    acct: 'norida4351',
    display_name: 'のりだー_よさこい',
    locked: false,
    created_at: '2017-04-28T13:19:57.175Z',
    followers_count: 645,
    following_count: 1686,
    statuses_count: 96,
    note: '<p></p>',
    url: 'https://mstdn.jp/@norida4351',
    avatar: 'https://media.mstdn.jp/images/accounts/avatars/000/188/222/original/acbb20fbf13bbb33.jpeg',
    avatar_static: 'https://media.mstdn.jp/images/accounts/avatars/000/188/222/original/acbb20fbf13bbb33.jpeg',
    header: '/headers/original/missing.png',
    header_static: '/headers/original/missing.png' } ]
<https://mstdn.jp/api/v1/accounts/42480/followers?limit=5&max_id=2444907>; rel="next", <https://mstdn.jp/api/v1/accounts/42480/followers?limit=5&since_id=2541225>; rel="prev"

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-mastodon, Node.js