drone.ioを使ってgithub-pagesの更新情報をtwitterに自動投稿する
github pages に新規投稿をプッシュした際、自動的にTwitterに更新情報を投稿できるようにしてみた。
最新記事があるか判別する
- gitの履歴から追加・更新されたものを取得する。
- published:true か判断する
という処理にした。
記事のpublishedのチェックが必要かどうかは、運用の仕方による。
jekyllの標準では
- _posts: 公開記事
- _drafts: 下書き
として使用される前提のようなので、それに従っている場合は必要ないと思う。
ただ、自分の場合は、_drafts を使ってない。_posts に追加 = 投稿&公開 とは限らないので、チェックを入れている。
コードは以下のような感じ
{% highlight ruby %}
def shared_target_post
git_am_files = git -c core.quotepath=false diff-tree --no-commit-id --name-only --diff-filter=AM -r HEAD _posts
.split(/\n/)
git_am_files.each do |file|
post = get_post(file)
if post.published?
return post
end
end
nil
end
{% endhighlight %}
get_postでファイル名からJekyll::Postを取得できるようにしているので、投稿のステータスは簡単に取得できる。
git で追加・更新されたファイルを取得する方法については、前に書いた。
Gitで直前のコミットで追加されたファイルを確認する
これ今気づいたけど、公開済みのモノを修正したファイルも対象になってしまうので、もうちょっと修正が必要っぽい。更新の場合は前回と比較して、publishedが変更されたかどうかを判断しないとマズい。
Twitterに投稿する
twitter というGemがあったのでそれを使用している。
以下の環境変数が設定されていれば、コード内ではtokenの設定がいらない。
TWITTER_CONSUMER_KEY
TWITTER_CONSUMER_SECRET
TWITTER_OAUTH_TOKEN
TWITTER_OAUTH_TOKEN_SECRET
token はさすがにハードコードできないのと、drone.ioとの連携では環境変数を使いたいので、ちょうど良い。
tokenが設定できていれば投稿は簡単にできる。1行だけ。
{% highlight ruby %}
Twitter.update message
{% endhighlight %}
rake タスクを作っておく
ここまでの内容をrake から呼び出しできるようにしておく。
{% highlight ruby %}
require ‘cgi’
require ’twitter'
def get_site
options = Jekyll.configuration({:safe => true})
site = Jekyll::Site.new(options)
end
def get_post(file)
site = get_site
post = Jekyll::Post.new(site, site.source, “”, File.basename(file))
end
def shared_target_post
git_am_files = git diff-tree --no-commit-id --name-only --diff-filter=AM -r HEAD _posts
.split(/\n/)
git_am_files.each do |file|
post = get_post(file)
if post.published?
return post
end
end
nil
end
namespace :share do
desc ‘Check shared post’
task :check do
post = shared_target_post
if post.nil?
puts “no files updated”
next
end
puts post.name
end
desc ‘Share new post to Twitter’
task :twitter do
post = shared_target_post
if post.nil?
puts "no files updated"
next
end
title = post.title
url = "http://kawaken.github.io#{post.url}"
message = %Q(書きました "#{title}" #{url})
Twitter.update message
end
end
{% endhighlight %}
rake share:check
で、更新があるかチェックできるようにした。
rake share:twitter
で投稿できる。
日本語を使ってるせいでURLがすごく長くなるんだけど、その辺はTwitter側で良い感じにやってくれてるらしい。
github pages と drone.io の連携
drone.io からは github pages のリポジトリを対象としたプロジェクトを作って、github からはwebhookでdrone.ioのプロジェクトを起動するように設定しておく。
この辺は前に書いた。drone.ioでjekyllのビルドテストを実行する
drone.io の設定
↑で書いたように、Twitterに投稿するために環境変数が必要なので、プロジェクトの設定画面で、Twitter用の環境変数を設定する。Environment Variables って箇所に設定する。
ビルドスクリプトも修正して、rakeタスクを呼び出すようにしておく。
{% highlight sh %}
bundle install –binstubs
bin/jekyll build –safe –trace
rake share:twitter
{% endhighlight %}
おしまい。後は記事をプッシュしたらOK。
その他
###ページの反映
github pages はリアルタイムで更新されるわけではないらしいので、Twitterに投稿したけど記事がない!ということになる可能性はある。今んとこ、タイムラグは気になったことないけど。
投稿前にページがあるかチェックした方が良いかもしれない。けどそうなると、ページが出来るまで待つのか、次回のビルドに持ち越すのかとか、考え出すとメンドクサイ。
Jekyll::Post
最初は、sedとか呼び出してたけど、drone.ioの環境だと上手く動作しなくなったので、悪戦苦闘しながら何とか取得ができるようになった。ここが一番大変だった。
git と日本語ファイル名
git でファイル名を取得する際に、"-c core.quotepath=false" を入れないと日本語で取得できない。自分の環境では~/.gitconfigとかで設定しているが、drone.io ではその辺りはデフォルト設定になるっぽいので、注意が必要。
この辺の設定がわかんなくて、drone.ioの環境変数とかgit config取得したくて、色々と試してたら、drone.ioでbuildが出来なくなった…。のでサポートにメールしたらしばらくしてビルド出来るようになった。
twitter gem
9月12日頃にドキュメントが更新されていたらしく、tokenを指定するところの環境変数が変わっていた。なので、改めて試してみると全然動かなかった…。
4.8.1
TWITTER_OAUTH_TOKEN
TWITTER_OAUTH_TOKEN_SECRET
5.0.0rc1
TWITTER_ACCESS_TOKEN
TWITTER_ACCESS_TOKEN_SECRET
通常bundleでインストールされるのは4.8.1の方なので、環境変数にはOAUTHの方を使うようにしておかないと上手く動かない。