Qt Network Authorization を使った Twitter API の利用post

さて、先月に続いて今月も参加した Qt 勉強会 @ Nagoya No6(17.03) のまとめ。

今回はいつもに増して短め。

sharkpp/Jugemutter: 長文投稿専用クライアント「じゅげむったー」 で成果物を公開しています。

はじめに

まずは、クラスの実装をしていきます。

Qt Network Authorization Examples | Qt Network Authorization 5.8 に Twitter認証のサンプルがあるので、それを参考にしつつ NetworkStorageAccessSample で実装した認証済みトークンの保存処理を実装していきました。

あ、はじめての Qt Network Authorization も参考にしています。

そろそろ、だれか Qt Network Authorization を触った記事を書いてくれないだろうか?

ポイント

実装するクラスは QOAuth1 クラスから派生します。

これは、認証した後のトークンの復帰処理で setStatus(QAbstractOAuth::Status::Granted) の実行が必要となります。 ただし、該当のメソッドが protected として実装されているので、 QOAuth1 クラスから派生する必要があるのです。

APIの各エンドポイントを設定

まあ、この辺はサンプルと同じです。

setTemporaryCredentialsUrl(QUrl("https://api.twitter.com/oauth/request_token"));
setAuthorizationUrl(QUrl("https://api.twitter.com/oauth/authenticate"));
setTokenCredentialsUrl(QUrl("https://api.twitter.com/oauth/access_token"));

OAuth の認証を、ブラウザを利用するために、

setReplyHandler(new QOAuthHttpServerReplyHandler(this));

としますが、これを実行するとポートを開きに行くので、必要な時のみポートを開くか PIN 認証にする方が良いかもしれません。

この時、

connect(this, &QAbstractOAuth::authorizeWithBrowser,
        this, &Twitter::handleAuthorizeWithBrowser);

としてシグナルをスロットと関連づけて、

void Twitter::handleAuthorizeWithBrowser(QUrl url)
{
    QDesktopServices::openUrl(url);
}

のような感じで実装することで、ブラウザで認証することができます。

grant() を呼び出すことで認証開始するので、適当なメソッドでラップします。

認証後は、

connect(this, &QOAuth1::granted, this, &Twitter::authenticated);

とすることで、 authenticated() を認証時に呼ばされるシグナルとして登録できます。

つぶやくには

    QUrl url("https://api.twitter.com/1.1/statuses/update.json");
    QUrlQuery query(url);
    query.addQueryItem("status", "hogehoge");
    url.setQuery(query);
    QNetworkReply *reply = post(url);
    connect(reply, &QNetworkReply::finished, this, &Twitter::tweetFinished);

みたいな感じです。

まあ、後から振り返ると割と簡単な部類になると思うけど、いろいろハマってしまいました。

いろいろ失敗談

なぜか今回はハマることハマること。

ハマった所をメモとして残しておきます。

  • setClientIdentifier() / setClientSharedSecret()token() / tokenSecret() をなぜかとり間違える なぜ間違えたし。
  • 設定したはずの、Consumer Key / Consumer Secret が設定されていなくて、QOAuthOobReplyHandler::networkReplyFinished: Host requires authentication とデバッグ主力に出る。 setModifyParametersFunction で今の Stage とライブラリのソースをにらめっこで原因を見つけた。
  • 呟く内容が別の変数を参照していたために空っぽで Missing required parameter: status. と返答が返ってくる。 うん、たしかに設定されてなかったね。
  • connect() でラムダ式を使うとなぜか qobject_cast<QNetworkReply*>(sender())nullptr横着せずに 別メソッドを作って設定すると大丈夫だった。何で? 後で試したら大丈夫だった。

と、こんな感じ。

結局、時間内になんとかつぶやきを書き込むまでは行けたけど、先のハマりがなければ、もう少し行けたかもしれない。

ツイッターのアプリケーション登録

Create an application | Twitter Application Management でアプリケーションを登録できる。

ただし、電話番号を認証していないと You must add your mobile phone to your Twitter profile before creating an application.(アプリケーションを作成する前に携帯電話を Twitter プロファイルに追加する必要があります。) って怒られる。

一度登録したら、電話番号の登録を解除しても、登録内容の変更とかは問題なくできる模様。

で、登録時、SMSで飛んでくるトークンを何回入力しても弾かれるので、途方にくれてたけど twitterの電話番号認証がうまくいかないとき - やったこと を見たらリロードすれば大丈夫のようなので試して見たらできた。 何じゃそりゃ?

まあともかく、アプリケーションを登録したら、Consumer Key / Consumer Secret を確認しアプリケーションに設定。

これでOK。

参考


   /   変更履歴  /   Permalink  /  このエントリーをはてなブックマークに追加 
 カテゴリ: ブログ  /   タグ: Qt, Twitter, OAuth, C++, cpp, 勉強会