shibatch's journey

日々考えていることをつらつら書くだけです

推し界隈の誕生日を通知してくれるbotをAWS Lambda + Pythonでつくった話

この記事はGMOペパボエンジニア Advent Calendar 2021の7日目の記事です。 昨日はRyo Nakamine (@r_nakamine) | Twitter さんの Goを用いてTCPソケット通信を学ぶでした! TCPの通信、メタルの時代からk8sに至るまで、ず〜っと使える知識なので私も整理して学んでいきたいです…!!


何をやったか

さて今日は最近やっている業務の話を書こうかなーとおも思ったのですが、ちょっとすぐに出せそうにないので(社のテックブログにしたい…)趣向を変えて、ちょっと前につくったTwitter botを紹介します。

何をするbotかというと、1日に1回、推し界隈(プリキュア)のキャラクターの誕生日まで何日かを教えてくれるbotです。こんな感じ。

あと、誕生日10分前に煽りのツイートをして、

当日はちゃんと祝ってくれます🎉

これをAWS Lambda + AWS EventBridge + Pythonで作った話をします。

なんで作ったか(読み飛ばしていい部分)

みなさまプリキュアってご存知ですかね…日曜朝8時30分から放映している戦うヒロインのアニメです。2004年から始まって17年やってる長寿アニメですね。で、17年やっているけれどもほぼ毎年シリーズが変わるので違うキャラが出てくるのです。その数ざっと70人ほど。

このプリキュア界隈、各キャラに固定ファンがいて、誕生日を盛大に祝ったり、この誕生日に向けてイラストを作ったりする人がけっこういるのです。私は固定のファンはないんですが、傍目からみてこの誕生日をカウントするbotはまぁまぁ需要があるのではー!?と思って作ることにしました。

作ったものの概要

技術的には簡単シンプルで、1日に1回、AWS EventBridgeでcronでLambdaでTwitter APIを叩いてツイートするだけです!

f:id:shibatch:20211207225656p:plain
ちょー簡単な図

なお、さきほど紹介したときにあった通り、このbotは3つの機能で成り立ってます。

  • 誕生日までの日数をカウントしてツイートする機能
  • 誕生日の10分前にツイートする機能
  • 誕生日にツイートする機能

今回はざっくり大まかにどういうことをやるのかを紹介します。

最初にやること

最初にやることは

で、これがなかなかめんどくさいです…コロコロ申請画面も変更されたりして一筋縄ではいかないんですよね…いろいろな方が紹介しているので省きます。

EventBridge

EventBridgeではさきほど言った3つの機能をそれぞれを定義してやります。cronで別々のタイミングで起動するようにしていますね。設定はUTCなのでそこは考慮した時刻で設定します。

f:id:shibatch:20211207230313p:plain
EventBridge

また、EventBridgeでは「入力」というものを定義できるので、ここで何の機能を呼び出すか定義します。

f:id:shibatch:20211207231140p:plain
event

EventBridgeでやることはこれだけです。

Lambda

さてLambdaですが、Lambdaではいちばん初めにLambda_function.py という名前のファイルが叩かれるので、この名前のファイルにコードを書いていきます。

import config, json, tweepy, time
from datetime import datetime, date
import birthdaylist
from operator import attrgetter
import sys
from dateutil.relativedelta import relativedelta


def lambda_handler(event, context):
    today = datetime.date(datetime.today() + relativedelta(hours=9))

    if event["event"] == 'howmanydays':
        howmanydays(today)
    elif event["event"] == 'isitbirthday':
        isitbirthday(today)
    elif event["event"] == 'tenminafterbirthday':
        tenminafterbirthday(today)

まず今日は何日なのかをJSTで取得した後に、どの機能を使うかを選んでますね。EventBridgeで渡された値で起動する処理を分けてます。今回はいちばんキモの「誕生日までの日数をカウントしてツイートする機能」をみてみます。

これですね

def howmanydays(today):
    text = str(today.year) + '年' + str(today.month) + '月' + str(today.day) + '日\n'
    i = 0
    for num1 in range(len(birthdaylist.precurelist)): # precurelistを上から1行ずつ評価する
        if today > date(today.year,birthdaylist.precurelist[num1].month,birthdaylist.precurelist[num1].day): # 今年の誕生日を過ぎているか
            year = today.year + 1
        else:
            year = today.year

        later = (date(year,birthdaylist.precurelist[num1].month,birthdaylist.precurelist[num1].day) - today).days # 誕生日までの日数を割り出し
    
        if 0 < later < 31: #誕生日が30日以内の人を抜き出す
            newdata = birthdaylist.Precure_later(later,birthdaylist.precurelist[num1].month,birthdaylist.precurelist[num1].day,birthdaylist.precurelist[num1].name,birthdaylist.precurelist[num1].precurename)
            birthdaylist.precurelist_new.append(newdata)
            i = i + 1
        else:
            continue

    if 0 < len(birthdaylist.precurelist_new):
        tweet_taisho = sorted(birthdaylist.precurelist_new, key=attrgetter('later'))
    
    for num2 in range(len(tweet_taisho)):
        
        if 0 < tweet_taisho[num2].later < 4:
            text = text + '❤️<200d>🔥'
        elif 3 < tweet_taisho[num2].later < 15:
            text = text + '💛️'
        else:
            text = text + '💚'

        text = text + str(tweet_taisho[num2].name) + '/' + str(tweet_taisho[num2].precurename)  + 'の誕生日(' + str(tweet_taisho[num2].month) + '/' + str(tweet_taisho[num2].day) + ')まであと' + str(tweet_taisho[num2].later) + '日\n'

        if 2 == num2 % 3 or num2 + 1 == len(tweet_taisho):
            tweet(text)
            text = str(today.year) + '年' + str(today.month) + '月' + str(today.day) + '日\n'

コメントにちまちま書いていますが、precurelistという別のファイルを読んでいます。 これには各キャラの誕生日が1行に1キャラずつ書いてあるんですが、

  • 1行ずつ評価して今日から誕生日までの日数を割り出す
  • 30日以内だったら別のリストに格納
  • 誕生日から近い順にソートする

ということをやってます。

あとは体裁をととのえてツイート!

tweepyというライブラリを使っています。この手のライブラリではおそらくだいぶメジャーなものです。

def tweet(text: str):
    auth = tweepy.OAuthHandler(config.API_KEY, config.API_SECRET)
    auth.set_access_token(config.ACCESS_TOKEN, config.ACCESS_TOKEN_SECRET)
    api = tweepy.API(auth)
    api.update_status(text)
    print(text)

これで毎日通知してくれます。ぱちぱちぱち。

Lambdaを使うメリット

世の中には簡単にTwitterBotを作るサービスがあったりします。いちばん有名どころだとtwittbot になります。なぜわざわざこのようなサービスを使わず、Lambdaを使うのかというとちゃんとメリットがあります。

安定性がばつぐんによい

Lambdaですがほんっとうに落ちません!簡単な処理しかしていないから、というのも大きいと思いますが「あれ?ツイートしてないな?」ということがまったくないのです。

だいたい無料でできる

Lambdaは公式に以下の説明があるんですが、

AWS Lambda の無料利用枠には、1 か月あたり 100 万件の無料リクエストと、1 か月あたり 40 万 GB-s のコンピューティングタイムが含まれており、x86 および Graviton2 プロセッサの両方を搭載した機能を利用できます。

正直趣味でやるぶんには十分すぎるほどの無料枠があります。使いきれません。

まとめ

Lamba でTwitter botを作る方法をざっくり具体例で紹介しました。わりと簡単にできますし、安定性も抜群、しかも普通に使う分には無料です。

あと、そこそこ需要のあるbotだとほぼ自動でいいねをもらえて承認欲求が満たされます(?)

それは冗談だとしても、なかなかいろいろ使い道のある方法だと思います。自分専用にToDoを通知してくれるbotとか、アイディアはいろいろ湧いてきますね!

個人的にはこの手のbotは需要があると手応えがあるので、別界隈への横展開も考えています。ラブライブなど。いちばんめんどくさいのはTwitter APIの申請です…やるだけなんですけどね。

明日は mafさんです!よろしくお願いしますー!