Edited at

LINEBOT SDK GOを使って月曜日のたわわBOTを作った。

More than 1 year has passed since last update.

この記事はGo (その2) Advent Calendar 2016の8日目の記事です。

皆さんは普段Messengerツールとして何を利用しているでしょうか。

仕事ならSlackやChatwork。プライベートならFacebook Messengerなどいろいろと種類があります。

その中でも日本ではLINEが多いのではないでしょうか。

日本ではLINEの月間アクティブ率が96.6%になったという記事もあります。

http://gaiax-socialmedialab.jp/post-30833/

自分もプライベートではLINEを利用しています。

そして、そのLINEではAPIを利用し、BOTを作成することができます。

既にいくつかの事例もあるようです。

http://blog.minato.jp.net/entry/linebot

この記事では、GoでLINEのBOTを書いたという事例を紹介したいと思います。



what is monday on tawawa?

で、まず月曜日のたわわって何なのという話からですが、


「月曜朝の社畜諸兄にたわわをお届けします」として、2015年2月23日から毎週月曜日にTwitterに投稿されているWeb漫画。「たわわ」とは胸が大きい、つまり巨乳を指し、憂鬱な月曜日に巨乳の女の子のイラスト・漫画を投稿することで、社畜の皆さんを少しでも楽にしようと言うもの。


月曜日のたわわとは



という感じのものです。

Botとしてはこんな感じになっています。

チャットにたわわをおくれと投稿すると、月曜日のたわわのテキストと画像URLを返すようになっています。


情報の収集方法

記事を作る際にどうやってURLを取得するかと考えたのですが、

ここはオーソドックスにTwitter APIを使って取得しようと決めました。

ここではanacondaというライブラリを使用しました。

package twitter

import (
"github.com/teitei-tk/tawawa-bot/config"

"github.com/ChimeraCoder/anaconda"
)

type Client struct {
APIClient *anaconda.TwitterApi
Config config.Twitter
}

func NewClient() (Client, error) {
var client Client

conf, err := config.InitTwitter()
if err != nil {
return client, err
}

anaconda.SetConsumerKey(conf.ConsumerKey)
anaconda.SetConsumerSecret(conf.ConsumerSecret)
api := anaconda.NewTwitterApi(conf.AccessToken, conf.AccessTokenSecret)

client.APIClient = api
client.Config = conf

return client, nil
}

とTwitterClientを作成し、APIを叩きます。

func FetchAllTawawaTweets(client Client, param RequestParametor) (filterdTweets []anaconda.Tweet, err error) {

var maxRequestTweetID int64
var sinceID int64
var tweestCount int
var tweets []anaconda.Tweet

for {
if maxRequestTweetID != 0 {
param.MaxID = maxRequestTweetID
}

res, err := getOwnerTimelineFromTwitter(client, param)
tweestCount = tweestCount + len(res.Tweets)
if err != nil {
return tweets, err
}

filterdRes := FilterTawawaTweets(res)
for _, t := range filterdRes.Tweets {
if maxRequestTweetID == 0 || maxRequestTweetID > t.Id {
maxRequestTweetID = t.Id
}

if sinceID == 0 || t.Id > sinceID {
sinceID = t.Id
}

tweets = append(tweets, t)
}

if maxRequestTweetID == sinceTweetID || tweestCount >= 3200 {
break
}
}

var showTweetRequestCount = 0
var requestTweetID = maxRequestTweetID
for {
resTweet, err := showFromOwnerTweet(requestTweetID, client)
if err != nil {
return tweets, err
}

tweets = append(tweets, resTweet)

requestTweetID = resTweet.InReplyToStatusID
showTweetRequestCount = showTweetRequestCount + 1
if showTweetRequestCount >= 100 || resTweet.Id == sinceTweetID {
break
}
}

return tweets, nil
}

この処理でやっていることは、

まず、投稿者である比村奇石さんのHomeTimelineを取得します。

その際に正規表現でTextを抽出し、フィルタリングを書けます。

が、Hometimelineだけでは全てのURLを取得出来ません。そこで、投稿しているTweetに注目しました。

投稿しているTweetはin_reply_to_statusIDを含んでおり、それを利用することで全ての内容を遡ることが出来ます。

なので、最後のTweetに含まれているin_reply_to_status_idを使い、最初に投稿した内容までを遡っています。

しかし、毎回ユーザーからメッセージが来る度にTwitterAPIを叩くのではすぐにRateLimitが来ます。

なので取得したあとは、RedisにCacheとしてJSON形式で保存をしました。

// Get Tawawa Owner Timeline it's use Cache

func GetAllTawawaTweets(client Client, param RequestParametor) (res UserTimelineResponse, err error) {
res = UserTimelineResponse{}

redisClient := config.InitRedis()
val, err := redisClient.Get(TwitterResponseCacheKey).Result()
if val != "" {
err = json.Unmarshal([]byte(val), &res)
if err != nil {
return res, err
}
return res, err
}

result, err := FetchAllTawawaTweets(client, param)
if err != nil {
return res, err
}
res.Tweets = result

bytes, err := json.Marshal(res)
if err != nil {
return res, err
}

err = redisClient.Set(TwitterResponseCacheKey, string(bytes), time.Duration(time.Millisecond*ResponseCacheExpiredAt)).Err()
if err != nil {
return res, err
}

return res, err
}


所感

最初プライベート用にBOTを作りたいなと思って練習とネタがてら書いてみました。

Goはチュートリアル以外触ったことがなく、今回始めてちゃんと作りましたが、

書いていて面白い言語でした。やはり型は偉大だった。

今回は一部の人以外、正直実用性が薄いBotでしたが、他にもLineBOTでやれることはあると思います。

今後は自分用のLINEBOTを作りたいなと思っています。

例えば、弊社のfreeeを利用し家計簿をつけて、そのAPIを利用し1日の終わりに家計簿を通知したり、

GoogleCalendarの内容を集計し、1日の始まりに通知をするなど用途はいろいろあるはずです。

この記事で少しでも興味を持ってもらえたなら幸いです。

最後にソースコードを置いておくので、興味があればご確認ください。

https://github.com/teitei-tk/tawawa-bot