さて、先月に続いて今月も参加した 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 でアプリケーションを登録できる。
ただし、電話番号を認証していないと
一度登録したら、電話番号の登録を解除しても、登録内容の変更とかは問題なくできる模様。
で、登録時、SMSで飛んでくるトークンを何回入力しても弾かれるので、途方にくれてたけど twitterの電話番号認証がうまくいかないとき - やったこと を見たらリロードすれば大丈夫のようなので試して見たらできた。 何じゃそりゃ?
まあともかく、アプリケーションを登録したら、Consumer Key / Consumer Secret を確認しアプリケーションに設定。
これでOK。
参考
- はじめての Qt Network Authorization — さめたすたすのお家
- Qt Network Authorization Examples | Qt Network Authorization 5.8
- Twitter Developer Documentation — Twitter Developers
- sharkpp/NetworkStorageAccessSample: Qt Network Authorization "Network storage access" sample
- POST statuses/update - ツイートを投稿する ※情報が古いようだ
- POST statuses/update - Twitter 開発者ドキュメント 日本語訳
- API Console — Twitter Developers
- twitterの電話番号認証がうまくいかないとき - やったこと