논문을 서보하고 있다고 응답으로 꾸짖어주는 bot를 만들었다(AWS Lambda + CloudWatch Events)

수행한 작업: 게시 논문의 진행 관리를 위한 TwitterBot 만들기




htps : // 라고 해서 r. 코 m/나오키_마에지마/s타츠 s/1061196481762222080
  • 논문을 쓰려면 논문을 쓰는 시간만을 만들어야 한다.
  • 그래서 논문을 쓸 예정인 날에 논문 드래프트 관리용 GitHub 리모트 리포지토리에 커밋이 없었을 때 리플라이로 꾸짖어 오는 Twitter의 Bot을 만들었다.
  • 매주 월·화·목(금요일은 역시 놀고 싶었다)을 절대론 문서하는 날로 한다. 이 날에 커밋이 없으면 화난 사양.
  • 공공의 눈에 접하는 Twitter로 bot를 만드는 편이, Slackbot등 보다 효과적이라고 생각했다.

  • 개발에 사용한 것: Python3.6, AWS Lambda, AWS CloudWatch Events
  • TwitterDevelopersAccount나 GitHub의 액세스 토큰 등은 취득한 전제로 쓰고 있습니다.

  • 파일 구성


    twitter_bot
    ├── config.yml
    ├── lambda_function.py
    └── requirements.txt
    

    이 밖에 나중에 파이썬 패키지가 설치된다.

    requirements.txt


  • 필요한 Python 패키지는 다음과 같습니다.
  • git_lambda는 Lambda에서 git을 움직이는 용입니다. git의 바이너리가 바인드되어 있고, PATH도 통과시켜주는 스그레모노. 스크래치로 실장하는 것은 귀찮았기 때문에…(감사).


  • requirements.txt
    requests_oauthlib==1.0.0
    GitPython==2.1.11
    git_lambda==1.1.3
    PyYAML==3.13
    

    다양한 설정을위한 yaml 파일 (config.yml)


  • 자격 증명 및 수신자 지정을 외부화합니다.
  • 꾸짖는 것만으로는 너무 많기 때문에 칭찬하는 문장도 준비

  • config.yml
    keys:
        twitter: 
            consumer_key: "XXXXXXXXXXXXXXXXXXX"
            consumer_secret: "XXXXXXXXXXXXXXXXXXX"
            access_token: "XXXXXXXXXXXXXXXXXXX"
            access_secret: "XXXXXXXXXXXXXXXXXXX"
        github:
            repository: "https://username:[email protected]/username/repository.git"
    
    config:
        twitter:
            user: "@twitter_user"
            alert_text: #サボった時のお叱り
                - "論文を書け、まだ間に合う。"
                - "論文を書きなさ~い!!"
                - "論文を進めれば、不安は消える。"
                - "明日やろうはバカ野郎だ。"
            praise_text: #サボってなかった時の褒め
                - "論文を書いて、えらーい!!"
                - "論文を書いたので救われた。"
                - "いいね、この調子!!明日はもっと書ける!!"
                - "がんばった!!投稿まであと少し!!"
    

    스크립트 (lambda_function.py)



    lambda_function.py
    import git_lambda
    git_lambda.setup() #lambdaからgitを使えるように設定しておく
    
    from git import Repo, RemoteProgress
    import yaml
    import os
    import random
    from datetime import datetime, timedelta, timezone 
    from requests_oauthlib import OAuth1Session
    
    def lambda_handler(event, context):
    
        #各種パラメータの設定
        TEMP_DIR = '/tmp/git_test_' + str(datetime.now().timestamp()) #git init用の一時フォルダ。lambdaでは/tmp以下でしか書き込みができない
        JST = timezone(timedelta(hours=+9),'JST') #日本時間に設定
        TODAY_DATE = datetime.now(JST).date() #現在の月日を取得
        UPDATE_URL = 'https://api.twitter.com/1.1/statuses/update.json' #Twitter投稿用
    
        #設定ファイルを読み込む
        with open('./config.yml','r') as f:
            keys = yaml.load(f)
    
        #Twitterの認証情報
        consumer_key = keys['keys']['twitter']['consumer_key']
        consumer_secret = keys['keys']['twitter']['consumer_secret']
        access_token = keys['keys']['twitter']['access_token']
        access_secret = keys['keys']['twitter']['access_secret']
    
        #gitリモートリポジトリからfetchする
        os.makedirs(TEMP_DIR, exist_ok=True)
        repo = Repo.init(TEMP_DIR)
        origin = repo.create_remote('origin',keys['keys']['github']['repository'])
        origin.fetch()
        commits = repo.iter_commits('origin/master')
    
        #最新のコミットから順に読まれていくので、今日のコミットでなくなるまで詳細を取得していく
        today_insertions = 0
        today_deletions = 0
        today_commit_count = 0
        for commit in commits:
            commit_date = datetime.fromtimestamp(commit.committed_date,JST).date()
            if(commit_date == TODAY_DATE):
                commit_stats = commit.stats.total
                today_insertions += commit_stats['insertions']
                today_deletions += commit_stats['deletions']
                today_commit_count += 1
            else:
                break
    
        #ツイートを部品ごとに生成していく
        header_text = "\n".join([keys['config']['twitter']['user'], #リプライ先の指定
        TODAY_DATE.strftime("%Y/%m/%d")]) #日付
    
        result_text = "\n".join(["コミット数:" + str(today_commit_count),
        "追加した行:" + str(today_insertions),
        "削除した行:" + str(today_deletions)])
    
        if(today_commit_count == 0):
            #サボってた場合のテキスト
            comment_text = random.choice(keys['config']['twitter']['alert_text'])
        else:
            #頑張って論文を書いた場合のテキスト
            comment_text = random.choice(keys['config']['twitter']['praise_text'])
    
        text = "\n".join([header_text,result_text,comment_text])
    
        #TwitterAPI経由で実際にツイートを行う
        params = {"status": text}
        twitter = OAuth1Session(consumer_key, consumer_secret, access_token, access_secret)
        req = twitter.post(UPDATE_URL, params = params)
        return "Tweet OK"
    

    패키지 당 zip으로 굳힌다


    pip install -r requirements.txt -t .
    zip -r twitter_bot.zip ./*
    
  • 이렇게 만든 zip 파일을 Lambda에 업로드합니다.
  • 15MB 정도의 zip 파일을 할 수 있어야합니다


  • Lambda 콘솔에서 테스트


  • 적절한 테스트 이벤트를 설정하고 Lambda 콘솔에서 테스트합니다.

    실제로 트윗되었습니다.
  • 개발 환경에서 다음으로 이동할 수 있어야합니다.

    main.py
    from lambda_function import lambda_handler
    lambda_handler(None,None)
    

    CloudWatch Events에서 정기 실행 설정


  • 대상을 이전 Lambda 함수로 설정.
  • 일본 시간의 매주 월화목의 23:59(UTC 14:59)에 기동하도록(듯이), CloudWatchEvents 스케줄러에 이하의 cron 식을 기술.
  • 59 14 ? * MON,TUE,THU *
    

    참고


  • htps : // 기주 b. 코 m / b 곤 g 돈 / 기 t_ ぁ
  • htps //w w. 케탄쵸. 네 t/엔 try/2017/12/13/003000
  • h tps : // 기 tpy 텐. Red d. cs. 이오/엔/s타 bぇ/
  • htps : // 이 m / 속눈썹 6 / ms / 5511c5631에 7 아 54550f7f
  • 좋은 웹페이지 즐겨찾기