GNU Social のボットを C++ で作る

プログラミング界隈の姫になるためにはツイッターのボットをPHPで作ることが有効であることが知られています。しかし、ツイッターは2018年を迎えられないかもしれないので、かわりにGNU Socialのボットを作ります。あと、2017年にもなってPHPを学ぶのもダサいので、C++でやります。

GNU Socialは自由なソフトウェアとして実装されたツイッタークローンです。外見はツイッターを丸パクリしている (補足: Qvitterというプラグインを入れるとツイッターそっくりな外見になります。オリジナルのUIはダサいです。) ので、簡単に移行できます。ツイッターにはない特徴として、複数のサーバーの連合であることが挙げられます。すなわち、有志がそれぞれサーバーを建てて、それらが互いに情報を共有することでGNU Socialの全体が成り立っています。ユーザーは所属したいサーバーを選んでユーザー登録します。他のサーバーのユーザーをフォローすることもできる (ただし操作のクリック数がちょっと多い) し、検索とハッシュタグはすべてのサーバーで共有されます。地味に不便なところとしては、他のサーバーから流れてくる画像は、埋め込みではなくリンクになります。これは不便ですが必要な仕様で、悪意のあるサーバーがユーザーの閲覧履歴を勝手に取るのを防ぐためだと思います。

FAQとしては、スマートフォンアプリなどという軟弱なものはありません。がんばってウェブUIを使ってください。

あと、用語の説明ですが、ツイッターの「ツイート」に相当するものはGNU Socialでは「クイップ」と呼びます。

GNU Socialは複数のサーバーの連合なので、好きなサーバーを選べばいいのですが、日本では FreezePeach を選ぶ人が多いです。これは Kawana Kiyoshi が誘致したのがきっかけのようです。特にこだわりがなければFreezePeachを選べばよいのですが、注意が必要なのは、女児の水着姿をクイップするとWe have 1 simple ruleされるということです。

GNU SocialのAPIは AtomPub 形式と Twitter互換 形式があります。AtomPubのほうが仕様がきれいなのですが、誰も使ってないみたいなので、Twitter互換のやつにします。

例として、サーバーは freezepeach.xyz、ユーザー名は vaginaplant、パスワードは XXXXX で、LGBTPZN という文字列をクイップしたいとします。とりあえず wget コマンドで試します。

wget -O - \
    --http-user=vaginaplant \
    --http-passwd=XXXXXX \
    --post-data='status=LGBTPZN' \
    https://freezepeach.xyz/api/statuses/update.json

あとはこれをC++でやります。定番のcURLです。パスワードは /etc/fubai-gnusocial-password というファイルに書いてあると思ってください。なお、このファイルを他人に読まれるとセキュリティが終了します。

#include <curl/curl.h>
#include <string>
#include <fstream>

using namespace std;

static int writer
    (char * data, size_t size, size_t nmemb,
    std::string * writerData)
{
	if (writerData == nullptr) {
		return 0;
	}
	writerData->append (data, size * nmemb);
	return size * nmemb;
}

void quip (string message)
{
    CURL *curl;
    CURLcode res;
    curl_global_init (CURL_GLOBAL_ALL);
    curl = curl_easy_init ();
    if (! curl) {
        return;
    }

    curl_easy_setopt (curl, CURLOPT_URL,
        "https://freezepeach.xyz/api/statuses/update.json");

    string user_name {"vaginaplant"};
    string password;
    ifstream secret_file {"/etc/fubai-gnusocial-password"};
    secret_file >> password;
    string userpwd = user_name + string {":"} + password;
    curl_easy_setopt (curl, CURLOPT_USERPWD, userpwd.c_str ());

    curl_easy_setopt (curl, CURLOPT_POST, 1);

    string arguments = string {"status="} + message;
    curl_easy_setopt (curl, CURLOPT_POSTFIELDS, arguments.c_str ());

    string reply;
    curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, writer);
    curl_easy_setopt (curl, CURLOPT_WRITEDATA, & reply);

    res = curl_easy_perform (curl);

    if (res != CURLE_OK) {
        return;
    }
    curl_easy_cleanup (curl);
    curl_global_cleanup ();
}

quip 関数の message 引数に適当な文字列を入れてください。リンクとハッシュタグは自動的に解釈されます。

読者の知識をどのくらいに想定すればいいのかわからないのですが、リンクするとき -lcurl を指定すべきであることを申し添えます。

広告