チラシ裏日記上等!!新館

Webアプリケーションエンジニアの雑記帳。映画とかアニメとかの記事も書きます。

golangでtwitterクライアントを作ってます

これは Go4 Advent Calendar 2017 - Qiita 6日目の記事です。

最近仕事で golang を書くことが増えました。やっていくうちに自分でも何か作ってみたくなり、最近自分のためのtwitterクライアントをちまちまと作っています。どうでもいい話ですが、自分で何かを作ろうと思ったら大体Twitter関連です。Twitter好きなんですよね。

今回はそのつくたものの紹介と、利用したライブラリについてつらつらと書いていきます。

作ったもの

作ったものは tt という Twitter クライアントです。

github.com

go get して go install でインストールできます。インストールしたら ttrc.json というファイルを$HOME に設定を書いて配置しておくと利用することができます。

{
  "CONSUMER_KEY":"",
  "CONSUMER_SECRET":"",
  "ACCESS_TOKEN":"",
  "ACCESS_SECRET":""
}

機能としてはまだ大したことはできないのですが、自分のタイムラインを見ることと、ツイートすること、返信することができます。

tt timeline とうつと、

$ tt timeline
Tue Dec 05 14:41:00 +0000 2017  938055612587417605      @hogehoge  ほげほげ
Tue Dec 05 14:41:00 +0000 2017  938055609814880257      @fugafuga       ふがふが
Tue Dec 05 14:40:59 +0000 2017  938055604844740608      @foo  ふー
Tue Dec 05 14:40:58 +0000 2017  938055603246710786      @bar        RT @baz: ばず

のようにタイムラインが出力されます。文字列だけなので、仕事中に利用してもおそらくバレません(待て。あと、神絵師なんかをフォローしているとTwitterを開いた瞬間に肌色率が高いイラストが開陳されて心臓に悪いことが多いと思います。このツールはコマンドラインツールなので後ろを気にする必要なくTwitterを楽しめます。

出力されるテキストはタブ区切りなので cut コマンドを使ってよしなにテキストを加工できます。peco なんかを使うといい感じに加工したものを利用したりできます。自分はメンションのリストを peco に食わせてメンションを返すスクリプトを作ったりしました。

メンションリストから選択してメンションを返すスクリプトを以下のような感じで .zprofile に書きました。

function tt-reply(){
    set $(tt timeline -m | peco | cut -f2 -f3)
    id=${1}
    name=${2}
    BUFFER="tt tweet -m ${id} '${name}'"
    CURSOR=$#BUFFER

}
zle -N tt-reply

bindkey '^tm' tt-reply

ちょっとわかりづらいですが以下のようにメンションを選択し、リプライするためのコマンドの雛形を作ったりしました。

f:id:Tomato-360:20171205235130p:plain

利用したライブラリ等

利用した代表的なライブリは以下です。

cobraコマンドラインツールを作るためのフレームワーク

cobraはgoでコマンドラインツールを作る際よくお世話になるライブラリですね。サブコマンドを作るのがかなり楽でオプションサポートしているので作るのがとても楽です。

まずルートコマンドを以下のように作って

var RootCmd = &cobra.Command{
    Use:           "コマンド名",
    Short:         "コマンドの詳細"
}

サブコマンドを作成し

cmd := &cobra.Command{
    Use:   "サブコマンド",
    Short: "サブコマンド解説",
    Run: func(cmd *cobra.Command, args []string) {
        //処理内容
    },
}

サブコマンドを追加していくだけでいろいろな機能を作成できます。

RootCmd.AddCommand(
    subCmdOne(),
    subCmdTwo(),
)

オプションも Flags を使って作成することが可能です。

flags := cmd.Flags()
flags.IntVarP(&timelineParams.Count, "count", "c", 20, "Set tweet count")
flags.Int64VarP(&timelineParams.SinceID, "since-id", "S", 0, "Set since tweet id")
flags.Int64VarP(&timelineParams.MaxID, "max-id", "M", 0, "Set max tweet id")
flags.BoolVarP(&timelineParams.Reply, "mention", "m", false, "show mention timeline")

それぞれの型のオプションを作成し、初期値とともにセットもできます。同時にそのオプションが何なのかの說明を入れることができるのが割りと親切でいいところだと思いました。

go-twitterTwitterAPIのラッパー〜

go-twittertwitterAPIを叩くためのAPIラッパーで、同じ機能を持つライブラリとしてはanacondaがあります。

go-twitterはoath1ライブラリを使用して以下のようにクライアントを作ります。

config := oauth1.NewConfig(consumerKey, consumerSecret)
token := oauth1.NewToken(accessToken, accessSecret)

httpClient := config.Client(oauth1.NoContext, token)
client := twitter.NewClient(httpClient)

この clientclient.Timelines.HomeTimeline(homeTimelineParams) のように利用するとホームタイムラインが得られます。

anacondaの場合は、

anaconda.SetConsumerKey(consumerKey)
anaconda.SetConsumerSecret(consumerSecret)
api := anaconda.NewTwitterApi(accessToken, accessSecret)

のように短く書くことができます。

apiの利用は、

api.GetHomeTimeline のように利用するとホームタイムラインが得られます。

anacondaのほうがシンプルに求めるものが得られる感じがします。それとanacondaのほうがAPIを網羅しています。go-twitterではlistのAPIが抜けていたので個人的にちょっと残念に思うところです。

tt ははじめに実装したgo-twitterで実装しているのですが、anacondaに乗り換えるか、go-twitterにプルリクを送るかしてlistのAPIを利用したいと思っています。

color 〜ターミナル上に出力する文字列に色を付けるライブラリ〜

colorはターミナルで出力する文字列に色を付けることができます。

使い方もかんたんで、

green := color.New(color.FgGreen).SprintFunc()
green('hogehoge')

でターミナル上に緑色の文字列を出力することができます。

tt だと以下のような感じで色分けして出力しています。

f:id:Tomato-360:20171206002207p:plain

ターミナルで利用するアプリケーションには必須なライブラリですね。

viper 〜設定を読み込むためのライブラリ〜

viperはcobraと同じ方が作った設定を読み込むためのライブラリです。サポートする形式は JSON TOML YAML と主要な所は読み込めるようになっています。

使い方は簡単に書くと、

// ファイル名を設定(拡張子はなくて良い
viper.SetConfigName("ttrc")
// 探しに行くディレクトリを設定
viper.AddConfigPath("./")
viper.AddConfigPath("$HOME/")

// 読み込む
err := viper.ReadInConfig()
if err != nil {
    panic(fmt.Errorf("Fatal error config file: %s \n", err))
}

// 読み込んだ設定を取り出す
viper.GetString("CONSUMER_KEY")

のような感じでできます。ttでは CONSUMER_KEY などの読み込みに利用しています。

感想

趣味と実益を兼ねて golangtwitter クライアントを作って見ました。gorutine とか gRPC とか golang を使う上で魅力となるものは一切使っていないのですが、久しぶりの静的型付け言語だったのでコンパイラでチェックされるという安心感のもと楽しく開発を行うことができました。

何と言っても cobra が優秀すぎます。コマンドラインツール界 の Rails といっても過言ではないと個人的には思っています。

ある程度 Twitter クライアントを作りきったら Webアプリケーションもなにか作ってみようかと考えています。Rails ほどかんたんにはいかないと思いますが、挑戦しがいのある分野だと思っております。