注意: ここは作業メモ、大した情報は無いですょ。
準備
今回、ElectronからTwitterにツイートするにはどうしたらいいのかなぁと色々と試して、
なんとかツイートするに至ったので、作業メモを残しておきます。
今回Electronとの連携ってことで、数あるTwitterモジュールのうちどれがいいのかよくわかんなかったんですが、
"ElectronでのOAuth" という記事が非常にまんまだったので、マネさせていただいてnode-twitter-apiというモジュールで作成することにしました。
で、例によって例のごとく、アプリ自体をTwitterに登録しないといけないので、まずはおとなしく Twitter Application Management にて登録を行なわないと駄目ですが、
私は このとき に作成したのがあるので、今回はそちらを使い回してテストをしてます。
ElectronでOauthするところまで
コード的には、前述の "Electronでアプリケーションを作ってみよう" という記事を参考させていただいて、以下のようなコードになりました。
今回は、consumer keyとかは環境変数からもらうようにしてます。
event.preventDefault();
でダミーで入れたgoogle先生のサイトに飛ばないようにしているのとか、
urlからmatch使ってアクセストークン切り出している辺りが肝でしょうか。
参考サイトをほぼほぼそのままなんですが。
// for Electron
const electron = require('electron');
// for node-twitter-api
const twitterAPI = require('node-twitter-api');
const twitter = new twitterAPI({
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callback: 'https://www.google.co.jp/',
});
var twitter_accessToken;
var twitter_accessTokenSecret;
electron.app.on('ready', function () {
const mainWindow = new electron.BrowserWindow({width:800, height: 600,
webPreferences: {webSecurity: false}});
twitter.getRequestToken(function (error, requestToken, requestTokenSecret, results) {
var url = twitter.getAuthUrl(requestToken);
mainWindow.webContents.on('will-navigate', function (event, url) {
var matched;
if (matched = url.match(/\?oauth_token=([^&]*)&oauth_verifier=([^&]*)/)) {
twitter.getAccessToken(requestToken, requestTokenSecret, matched[2], function (error, accessToken, accessTokenSecret, results) {
twitter_accessToken = accessToken;
twitter_accessTokenSecret = accessTokenSecret;
twitter.verifyCredentials(twitter_accessToken, twitter_accessTokenSecret, {}, function (error, data, respons) {
mainWindow.loadURL('file://' + __dirname + '/html/index.html');
});
});
}
event.preventDefault();
});
mainWindow.loadURL(url);
});
});
<!DOCTYPE xhtml>
<xhtml>
<head></head>
<body>
<h1>test</h1>
</body>
</xhtml>
これを
% ../node_modules/electron-prebuilt/dist/electron app.js
な感じで実行すると、
といった感じで認証画面が表示されるようになりました。
で、 twitter.getAccessToken()
に渡してるコールバック関数の中で、無事にアクセストークンが取得できるようになりました。
Electronのremoteオブジェクトを使ってツイートする
で、アクセストークンを取得をしたは良いのですが、これを使ってレンダラ側で入力したテキストでツイートするにはどうしたら良いのかと調べていたところ、
Electronのremoteオブジェクトを使えばいけそうな感じでした。
こちらについては、 "Electronでアプリケーションを作ってみよう" という記事を参考にさせていただきました。
あ、偶然にもアクセストークン取るところで参考にさせていただいた方の投稿ですね……。
ちゅーことで、まずはindex.htmlを以下のように修正。
<!DOCTYPE xhtml>
<xhtml>
<head></head>
<body>
<h1>test</h1>
<script type="text/javascript" src="tweet.js"></script>
<form name="test">
<textarea id="data"></textarea>
<input type="button" value="tweet" onclick="tweet()" />
</form>
</body>
</xhtml>
そして、まぁ、別に分けなくてもよかったんですが、tweet.jsというファイルを以下のようにしてindex.htmlと同じディレクトリに置きました。
const app = require('electron').remote.require('./app');
function tweet() {
app.tweet(document.forms["test"].elements["data"].value);
}
肝はremote使ってるところくらいでしょうか。
で、これで呼び出す tweet()
を、 app.js にて以下のように追加で定義しました。
exports.tweet = function(data) {
console.log("tweet!");
twitter.statuses("update", {status: data},
twitter_accessToken,
twitter_accessTokenSecret,
function(error, data, response) {
if (error) {
console.log(error);
} else {
console.log(data);
}
});
}
これを実行すると、先程もうアプリは認証してるので、Twitterの画面から自動で以下の殺風景な画面に遷移して、
適当な文字打ちこんでtweetボタンを押すと、見事にツイートすることができてました。
肝心のアプリ側は、画面遷移もなくターミナルにベロっとログを吐き出すだけですし、タイトルバーも「アプリケーション認証」のまんまですね……。
まぁ、これでなにかおもしろいもの作れないかなぁ、と。