Golangでどこでもtwitterできるbinaryをつくる
2018/02/08 追記
記事中で紹介していたgo-bindataの作者がgithubアカウントを削除し、そのアカウントを別の誰かが取得したそうです。
📢 #GOLANG WARNING
— Francesc @ Madrid (@francesc) 2018年2月7日
go-bindata creator deleted their @github account and someone else created a new account with the same name.
There's no guarantees that the new user has good intentions, so if you're using the repository make sure you verify it first!https://t.co/bOhPYRnFvV
善意でこの行為を行っているとは考えにくいので、go get -u github.com/jteeuwen/go-bindata/...
は行うべきではないです。
記事執筆時点では、有志の方がforkしてくれているので、そちらを参照するのが良さそうです(mattnさんありがとうございます)
ドリコムアドベントカレンダー16日目
この記事はドリコムアドベントカレンダー の16日目です。
前日はgremitoさんの「オレオレDockerfileを作って、サーバーサイドの開発をやっている話。」です。
あなたは誰
先月ドリコム社に中途入社したid:miyachik です。サーバーサイド側のコード書いている人です。
主にRailsを書いて、たまにJavaScriptやGolangをさわったりするぐらい。
twitterの話
みなさんtwitterしてますよね。昼夜問わず変な人がいっぱいいてとても有意義で無意義です。
そして、みなさん(おそらく)エンジニアだと思うので、terminal上でコマンドを叩いたときに、よくわからんエラーを吐いてエラったときの鬱憤をネットの海に叫びたい気持ちが多々あると思います。僕はあります。
gotwi
そんな衝動を解決するために、miyachik/gotwi というものを先日リリースしました。
いわゆるGo製のCLItwitterクライアントなんですが、現状だとつぶやことしかできません。(というかユースケースがそれしかありません)
プログラムを書いていて適当に愚痴りたいときに、ブラウザやクライアントに戻って呟いたりしちゃうと、うっかり変なつぶやきが目に止まって時間を取られてしまったりしまいがちですよね。
そんな人のために求められているのが、このgotwiです。つぶやく機能しかありません。(replyのshowぐらいは実装予定)
terminal上で動作できて、クロスコンパイル可能なのでどこにでもbinaryを配布することができます。
以前も似たようなCLIクライアントをThorを使ってRubyで実装していたのですが、アクセストークンの扱いや、成果物のポータビリティがいまいちだったりで、そのコードを書いたPC上ぐらいでしか使用していませんでした。
ところが、Goで書いたことによってアクセストークンをgo-bindataで埋め込みつつ、任意環境で実行可能なbinaryに吐き出すことが可能になったので、個人持ちのPCから任意のEC2、どこでも簡単に動かすことができます。
今回はその中でも便利だったgo-bindataを使った話をしたいと思います。
go-bindata
go-bindataは、任意のdataをビルドして、dataをbinaryに変換しGoのコードに埋め込みアクセスできるようなgoのソースを生成してくれるライブラリです。
Install
% go get -u github.com/mattn/go-bindata/... % go-bindata -h
で、問題なければgo-bindataコマンドが使えるようになっています。
Build
以下のディレクトリ構成で作業をするとして
├── Makefile ├── README.md ├── main.go ├── settings.local.toml └── settings.sample.toml
このsettings.local.toml
をbuildするbinaryに含めることによってアクセストークンなどの秘匿情報を実行binaryに含めてしまうことができます。
今回はtwitterのAccess Tokenが必要になるので、下記を参考に自分のAccess Tokenを取得するようにしてください。(2017年12月時点)
Access tokens from apps.twitter.com — Twitter Developers
.tomlとは、yamlのような設定記述言語で、yamlより色々とシンプルな点や、Goのサポートが厚いことからよくGo界隈では使われています。
# settings.local.toml
ConsumerKey="YOUR TWITTER_CONSUMER_KEY"
ConsumerSecret="YOUR TWITTER_CONSUMER_SECRET"
AccessToken="YOUR TWITTER_ACCESS_TOKEN"
AccessSecret="YOUR TWITTER_ACCESS_SECRET"
これを
% go-bindata settings.local.toml
とすることで、settings.local.toml
の中身が圧縮してbinaryに変換され、アクセス可能なメソッドの生えているbindata.go
が生成されていると思います。
あとは、以下のように、Asset("#{ファイル名}")
とすることで、binaryに埋め込んだ文字列やその他のリソースを読み込むことが可能です。
func main() { data, err := Asset("settings.local.toml") if err != nil { panic(err) } fmt.Print(string(data)) }
debug時などに注意が必要なのは、data本体はbindata.go
に含まれているので、実行時にbindata.go
を含める必要があります。
% go run main.go bindata.go ConsumerKey="YOUR TWITTER_CONSUMER_KEY" ConsumerSecret="YOUR TWITTER_CONSUMER_SECRET" AccessToken="YOUR TWITTER_ACCESS_TOKEN" AccessSecret="YOUR TWITTER_ACCESS_SECRET"
gotwiでは、このようにしてアクセストークンなどをbinaryに埋め込んでいるので、あとは任意の環境にビルドしたbinaryを、実行したいサーバーに配置することで、どこでも実行することが可能になります。
gotwiのクロスコンパイル
様々な環境で動かすためには、build時に$GOOS,$GOARCHを指定する必要があります。
各環境変数に指定できるものは下記を参考にしてください。
Installing Go from source - The Go Programming Language
指定なしでbuildをした場合は、build時の環境が参照されるようになります。
例えば、Linuxでamd64な環境へのbuildは以下のようになります。
% GOOS=linux GOARCH=arm64 go build main.go bindata.go => 直下に gotwi が生成される % ./gotwi "Hello!" => "Hello!"が投稿
その他にも、build時には任意のオプションをつけられるので、公式のドキュメントを参照すると良いです。
go - The Go Programming Language
注意点
- このbinaryが流出してしまうと、それこそ誰でもアクセストークンの所有者として呟けてしまうので、管理には気をつけてください。
- go-bindataでビルドしたbindata.goの時点では、Goのソースに圧縮されたbyte列が入っているだけなので、ちょっと頑張ればアクセストークンを復号できるんじゃないかと思います(それこそ無圧縮とかにすると簡単に)。なので.gitignoreしましょう。
まとめ
- どこでも実行可能な自分が呟けるbinaryを吐き出せる、gotwiを作りました。
- 使い始めて一ヶ月くらいですが、なかなか快適です。クロスコンパイル可能なbinaryを吐き出せるGoは雑なCLIツールを作るのに非常に良い
- AWS LambdaのGoサポート の話もありますし、Golangは良い
- twitterはほどほどに
明日は hayabusa333 さんの「Elixir環境構築にて暗号化でエラーにならないために」です。