Skip to content

Instantly share code, notes, and snippets.

@skypenguins
Last active October 26, 2016 02:34
Show Gist options
  • Save skypenguins/9321f3cfea81784984e7 to your computer and use it in GitHub Desktop.
Save skypenguins/9321f3cfea81784984e7 to your computer and use it in GitHub Desktop.
Qt5.5(QtQuick 2.2/C++)でTwitterに投稿するサンプル
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QtQml>
#include "oauth.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
// QML側にクラスをセット
oauth Twitter;
engine.rootContext()->setContextProperty("twitter", &Twitter);
return app.exec();
}
import QtQuick 2.2
import QtQuick.Controls 1.1
ApplicationWindow {
id: applicationWindow1
width: 430
minimumWidth: 430
height: 700
minimumHeight: 300
title: qsTr("TwitterClientTest")
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("ファイル(&F)")
MenuItem {
text: qsTr("アプリケーションの終了(&X)")
onTriggered: Qt.quit();
}
}
}
Button {
id: post
x: 179
y: 373
text: qsTr("つぶやく(&P)")
anchors.horizontalCenterOffset: 2
anchors.horizontalCenter: parent.horizontalCenter
transformOrigin: Item.TopLeft
onClicked: twitter.post = tweetText.text
}
TextArea {
id: tweetText
text: ""
x: 97
y: 210
anchors.horizontalCenterOffset: 2
anchors.horizontalCenter: parent.horizontalCenter
}
TextField {
id: pincode
x: 126
y: 136
placeholderText: qsTr("PINコードを入力してね")
}
Button {
id: regButton
x: 261
y: 136
text: qsTr("認証する")
checked: true
checkable: false
onClicked: {
twitter.postPin = pincode.text
}
}
Button {
id: loginButton
x: 179
y: 60
text: qsTr("ログイン")
checkable: false
onClicked: twitter.regAct
}
Label {
id: infoLabel
x: 97
y: 177
text: qsTr("スクリーンネーム:")
horizontalAlignment: Text.AlignHCenter
}
Label {
id: sNameLabel
x: 182
y: 177
text: twitter.user
}
}
#include "oauth.h"
oauth::oauth(QObject *parent) :
QObject(parent)
{
consumer_key = "";
consumer_secret = "";
request_token_url = "https://api.twitter.com/oauth/request_token";
authorize_url = "https://api.twitter.com/oauth/authorize";
access_token_url = "https://api.twitter.com/oauth/access_token";
update_url = "https://api.twitter.com/1.1/statuses/update.json";
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
QString oauth::regAccount()
{
QMap<QString, QString> params; // 毎回初期化しないと、401エラーになる
params["oauth_consumer_key"] = consumer_key;
params["oauth_nonce"] = QString::number(qrand());
params["oauth_signature_method"] = "HMAC-SHA1";
params["oauth_timestamp"] = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
params["oauth_version"] = "1.0";
// 署名キー作成
QString key = consumer_secret + "&";
// 署名対象のテキスト(Signature Base String)の作成
// クエリにアイテムを追加
QUrlQuery RequestQuery;
QMapIterator<QString,QString> itr(params);
while (itr.hasNext()) {
itr.next();
RequestQuery.addQueryItem(itr.key(),itr.value());
}
QString signature = "GET&" +
request_token_url.toUtf8().toPercentEncoding() +
"&" +
RequestQuery.toString().toUtf8().toPercentEncoding();
// 署名の作成(キーとテキストでHMAC-SHA1アルゴリズムを利用して16進のダイジェスト値を生成し、その値をBase64エンコード)
QByteArray oauth_signature = QMessageAuthenticationCode::hash (
signature.toUtf8(),
key.toUtf8(),
QCryptographicHash::Sha1).toBase64();
// パラメータにsignatureを追加(signatureはURLエンコードする)
RequestQuery.addQueryItem("oauth_signature", QString::fromUtf8(oauth_signature.toPercentEncoding()));
//リクエストトークンとパラメータをセットしてクエリを作成
QUrl message(request_token_url);
message.setQuery(RequestQuery);
QUrl url(message);
QNetworkRequest request(url);
// クエリを Twitter に送信して Request Token を取得
oauth_manager = new QNetworkAccessManager(this);
connect(oauth_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(oauthreqFinished(QNetworkReply*)));
oauth_manager->get(request);
return "OK";
}
QString oauth::postPincode(const QString &pin)
{
oauth_verifier = pin;
QMap<QString, QString> params; // 毎回初期化しないと、401エラーになる
params["oauth_consumer_key"] = consumer_key;
params["oauth_nonce"] = QString::number(qrand());
params["oauth_signature_method"] = "HMAC-SHA1";
params["oauth_timestamp"] = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
params["oauth_version"] = "1.0";
params["oauth_token"] = oauth_token;
params["oauth_verifier"] = oauth_verifier;
// 署名キー作成
QString key = consumer_secret +
"&"+
oauth_token_secret;
// 署名対象のテキスト(Signature Base String)の作成
// クエリにアイテムを追加
QUrlQuery RequestQuery;
QMapIterator<QString,QString> itr(params);
while (itr.hasNext()) {
itr.next();
RequestQuery.addQueryItem(itr.key(),itr.value());
}
QString signature = "GET&" +
access_token_url.toUtf8().toPercentEncoding() +
"&" +
RequestQuery.toString().toUtf8().toPercentEncoding();
// 署名の作成(キーとテキストでHMAC-SHA1アルゴリズムを利用して16進のダイジェスト値を生成し、その値をBase64エンコード)
QByteArray oauth_signature = QMessageAuthenticationCode::hash (
signature.toUtf8(),
key.toUtf8(),
QCryptographicHash::Sha1).toBase64();
// パラメータにsignatureを追加(signatureはURLエンコードする)
RequestQuery.addQueryItem("oauth_signature", QString::fromUtf8(oauth_signature.toPercentEncoding()));
//URLをセット
QUrl url(access_token_url);
url.setQuery(RequestQuery);
QNetworkRequest request(url);
// ヘッダ追加
request.setRawHeader(QString("Authorization").toUtf8(), QString("OAuth").toUtf8());
// 認証する
oauthpin_manager = new QNetworkAccessManager(this);
connect(oauthpin_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(oauthFinished(QNetworkReply*)));
oauthpin_manager->get(request);
return "OK";
}
QString oauth::postTweet(const QString &str)
{
tweet = str;
QMap<QString, QString> params; // 毎回初期化しないと、401エラーになる
params["oauth_consumer_key"] = consumer_key;
params["oauth_nonce"] = QString::number(qrand()); // ランダムな文字列
params["oauth_signature_method"] = "HMAC-SHA1";
params["oauth_timestamp"] = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
params["oauth_version"] = "1.0";
params["oauth_token"] = access_token;
params["status"] = QString::fromUtf8(tweet.toUtf8().toPercentEncoding());
// 署名キーを作成
QString key = consumer_secret.toUtf8() + "&" + access_token_secret;
// 署名対象のテキスト(Signature Base String)の作成
// クエリにアイテムを追加
QUrlQuery RequestQuery;
QMapIterator<QString, QString> itr(params);
while(itr.hasNext()){
itr.next();
RequestQuery.addQueryItem(itr.key(), itr.value());
}
QString signature = "POST&" +
update_url.toUtf8().toPercentEncoding() +
"&" +
RequestQuery.toString(QUrl::FullyEncoded).toUtf8().toPercentEncoding();
// 署名の作成(キーとテキストでHMAC-SHA1アルゴリズムを利用して16進のダイジェスト値を生成し、その値をBase64エンコード)
QString oauth_signature = QMessageAuthenticationCode::hash (
signature.toUtf8(),
key.toUtf8(),
QCryptographicHash::Sha1).toBase64().toPercentEncoding();
// パラメータにsignatureを追加
params["oauth_signature"] = oauth_signature.toUtf8(); //その後URLエンコード
// URLをセット
QUrl url(update_url);
QNetworkRequest request(url);
// ヘッダ作成前にstatusを削除
params.remove("status");
// ヘッダ作成
QMapIterator<QString,QString> itr2(params);
QString params_header;
while (itr2.hasNext()) {
itr2.next();
params_header += QString("%1=\"%2\",").arg(itr2.key(),itr2.value());
}
params_header.resize(params_header.size() -1);
// ヘッダ追加
request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("application/x-www-form-urlencoded"));
request.setRawHeader( "Authorization", "OAuth " + params_header.toUtf8());
manager->post(request, QByteArray("status=") + tweet.toUtf8().toPercentEncoding());
return "Complete";
}
void oauth::oauthreqFinished(QNetworkReply *reply)
{
// oauth_token と oauth_token_secretを取得
QUrlQuery oauth_reply;
oauth_reply.setQuery(QString::fromUtf8(reply->readAll()));
oauth_token = oauth_reply.queryItemValue("oauth_token").toUtf8();
oauth_token_secret = oauth_reply.queryItemValue("oauth_token_secret").toUtf8();
QMessageBox res0;
res0.setText("Response");
res0.setInformativeText("oauth_token: " + oauth_token + "\n" + "oauth_token_secret: " + oauth_token_secret);
res0.exec();
// 既定のブラウザで認証画面に飛ばす
QUrlQuery request_pin;
QUrl oauth_url(authorize_url);
request_pin.addQueryItem("oauth_token", oauth_token);
oauth_url.setQuery(request_pin);
QDesktopServices::openUrl(QUrl(oauth_url));
}
void oauth::oauthFinished(QNetworkReply *reply)
{
QByteArray Response = reply->readAll();
QMessageBox res;
res.setText("Response");
res.setInformativeText(QString::fromUtf8(Response));
res.exec();
QUrlQuery oauth_reply;
oauth_reply.setQuery(QString::fromUtf8(Response));
access_token = oauth_reply.queryItemValue("oauth_token");
access_token_secret = oauth_reply.queryItemValue("oauth_token_secret");
QString user_id = oauth_reply.queryItemValue("user_id");
screen_name = oauth_reply.queryItemValue("screen_name");
QMessageBox keys;
keys.setText("OAuth");
keys.setInformativeText("Access Token: " + access_token.toUtf8() + "\n" +
"Access Token Secret: " + access_token_secret.toUtf8() + "\n" +
"User ID: " + user_id.toUtf8() + "\n" +
"Screen Name: " + screen_name.toUtf8()
);
keys.exec();
emit userChanged(); // ここでuserinfo()を呼び出し、sNameLabelにscreen_nameを表示させる
}
QString oauth::userInfo()
{
return "@" + screen_name.toUtf8();
}
void oauth::replyFinished(QNetworkReply *reply)
{
QString status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toString();
QString reason = reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
QMessageBox msg1;
msg1.setText(status_code.toUtf8());
msg1.setInformativeText(reason.toUtf8());
msg1.exec();
if (reply->error() != QNetworkReply::NoError)
{
QString err_msg = reply->errorString();
QMessageBox msg2;
msg2.setText(QString::fromLocal8Bit("エラーが発生しました"));
msg2.setInformativeText(err_msg.toUtf8());
msg2.exec();
return;
}
QByteArray result = reply->readAll().data();
QMessageBox msg3;
msg3.setText(QString::fromLocal8Bit("送信結果"));
msg3.setInformativeText(QString::fromUtf8(result));
msg3.exec();
}
#ifndef OAUTH_H
#define OAUTH_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QMessageAuthenticationCode>
#include <QCryptographicHash>
#include <QDateTime>
#include <QUrl>
#include <QUrlQuery>
#include <QMessageBox>
#include <QDesktopServices>
#include <QDebug>
class oauth : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(oauth)
Q_PROPERTY(QString post WRITE postTweet)
Q_PROPERTY(QString regAct READ regAccount)
Q_PROPERTY(QString postPin WRITE postPincode)
Q_PROPERTY(QString user READ userInfo NOTIFY userChanged)
public:
explicit oauth(QObject *parent = 0);
QString postTweet(const QString& str);
QString regAccount();
QString postPincode(const QString& pin);
QString userInfo();
signals:
void userChanged();
private slots:
void replyFinished(QNetworkReply*);
void oauthreqFinished(QNetworkReply*);
void oauthFinished(QNetworkReply*);
private:
QNetworkAccessManager* manager;
QNetworkAccessManager* oauth_manager;
QNetworkAccessManager* oauthpin_manager;
QString consumer_key;
QString consumer_secret;
QString oauth_token;
QString oauth_token_secret;
QString oauth_verifier;
QString access_token;
QString access_token_secret;
QString request_token_url;
QString authorize_url;
QString access_token_url;
QString update_url;
QString screen_name;
QString tweet;
};
#endif // OAUTH_H
TEMPLATE = app
QT += qml quick widgets network
SOURCES += main.cpp \
oauth.cpp
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)
HEADERS += \
oauth.h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment