電電のブログ

電電生だったひとのぼやき

褒めたもんについて(技術編)

はいどうもでんでんです。

今回の記事は備忘録に近いものなのでぱぱっと書いていきます。

僕がプログラミングやり始めてからつくったものはlifegameとかQ tableを使った迷路探索とか何ですけど
そこからtwitter botを作って何かやりたいなと思って褒めたもんを作りました。

この褒めたもんなんですが内容としては

  • フォローするとフォローし返してくれる
  • フォローワーのツイートを時間ごとに読んである単語に対して反応してリプライしてくれる

というのが主な機能です。

こんな感じで褒めてくれます

前までは一個一個メソッドにして管理してたんですが、せっかくオブジェクト指向について理解してきたのでリファクタリングして整理しました。

githubの方に随時最新版あげているのでコードだけ見たいって方はそちら見てください。

#encoding utf-8
import tweepy

#親ディレクトリにあるアカウント情報へのパス
import sys,os
pardir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(pardir)

#account情報をaccount.pyからロード
from account import account #load account
import meta_manuscript

class Hometamon():
    def __init__(self):
        auth = account.Initialize()
        self.api = tweepy.API(auth, wait_on_rate_limit=True)
        self.twitter_id = account.id()

    #read tweets
    def classify(self):
        since = None
        classify_list = ["褒めて","ほめて","讃えて","たたえて","えらい"]
        transform_command = ["変身"]
        exclusion_list = ["bot","ビジネス","副業","公式"]

        public_tweets = self.api.home_timeline(count=50,since_id=since)

        for tweet in public_tweets:
            user_name = tweet.user.name#HN
            screen_name = tweet.user.screen_name

            for i in range(len(exclusion)):
                if exclusion_list[i] in user_name:
                    print("not reply")
                else:
                    user_name = user_name.split("@")
                    for i in range(len(classify_list)):
                        if classify_list[i] in tweet.text:
                            if tweet.favorited == False:
                                print("test:承認")
                                #reply
                                self.reply(user_name[0],screen_name,tweet.id,tweet.text)
                                #favorite
                                self.api.create_favorite(tweet.id)
                            else:
                                print("you already replyed it!")

                    for i in range(len(transform_command)):
                        if transform_command[i] in tweet.text:
                            if tweet.favorited == False:
                                print("test: 変身")
                                #transform
                                self.transform()
                                self.api.create_favorite(tweet.id)

    #返事をする
    def reply(self,user_name,screen_name,tweet_id,tweet_text):
        num = random.randint(1,tweet.max_num())
        num_padded = '{0:03d}'.format(num) #ゼロパディング:0で3桁左詰する。 example 1→001

        reply = "@"+screen_name+"\n "+user_name+tweet.manus(num-1)
        self.api.update_status(status=reply, in_reply_to_status_id=tweet_id)#status
        print("{0}のツイート:{1} に{2}と応援しました!".format(user_name,tweet_text,reply))

    #フォロバする
    def followback(self):
        #最近のフォロワーからその人のtweetやid情報取得
        # followers=api.followers_ids(screen_name=twitter_id)#全てのフォロワーidを取得
        # friends=api.friends_ids(twitter_id)#フォローしている人のidを取得
        followers = self.api.followers_ids(self.twitter_id)
        friends = self.api.friends_ids(twitter_id)

        follow_back = list(set(followers)-set(friends))#list フォロバすべき
        print("list_followback,count:",len(follow_back))

        for i in range(min(len(followback),10)):
            try:
                self.api.create_friendship(followback[i])
                print("success follow!"+str(followback[i]))
            except tweepy.error.Tweeperror:
                print("error")

    def tweet(self):
        status = "順調だもん!"
        self.api.update_status(status=status)

    def transform(self):
        pass

def main():
    hometamon = Hometamon()
    hometamon.classify()
    hometamon.followback()

if __name__ == "__main__":
    main()

まあこんな感じです。

一個一個説明していきます。

#encoding utf-8

import tweepy

#親ディレクトリにあるアカウント情報へのパス
import sys,os
pardir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(pardir)

#account情報をaccount.pyからロード
from account import account #load account
import meta_manuscript

最初のこの部分は

ライブラリを導入しています。使用ライブラリは今の所tweepyだけですが、これから先mecabとpytorch導入してどうにかしたいと思っています。

またaccountはtwitterAPIを使用するためのAUTH認証情報を読み込んでいます。具体的には以下のようになっています。

#encoding:utf-8

import tweepy

def Initialize():
    auth = tweepy.OAuthHandler(consumer_key="随時入力")
    auth.set_access_token("随時入力")#access_token,token_secret


    return auth

def id():
    twitter_id="随時入力"

    return twitter_id

次にmeta_manuscriptなんですが、以下のようなプログラムになっています。

#encoding:utf-8
class Manuscript():
    def __init__(self):
        self.tweet=[]
        #1~
        self.tweet.append("仕事終わらせてえらいもん!!")
        self.tweet.append("よく頑張りました!!!")
        self.tweet.append("満点!")
        self.tweet.append("いつも最高です。")
        self.tweet.append("とても優秀だもん!")
        self.tweet.append("できる人は違うもん")
        self.tweet.append("頑張り屋さんです")
        self.tweet.append("すごい!\nとてもすごい!!")
        self.tweet.append("すばらしい!")
        self.tweet.append("最高!!仕事人!!!")
        self.tweet.append("行動力の化身!!!!")
        self.tweet.append("今日も頑張ってます")
        self.tweet.append("今日の成果も素晴らしい!!")
        self.tweet.append("わんだふる!!!")
        self.tweet.append("素晴らしい成果だもん!!")
        self.tweet.append("素晴らしい出来栄えです")
        self.tweet.append("仕事を頑張る姿が素敵もん!!")
        self.tweet.append("大好きだもん")
        self.tweet.append("今日もお疲れ様だもん")

    def manus(self,num=0):
        return self.tweet[num]

    def max_num(self):
        return len(self.tweet)

この部分を増やすことで褒めたもんの返事のレパートリーを増やすことができます。

さて、Hometamonのクラス部分について説明していくと

class Hometamon():
    def __init__(self):
        auth = account.Initialize()
        self.api = tweepy.API(auth, wait_on_rate_limit=True)
        self.twitter_id = account.id()

この部分でHometamonというクラスに変数として、APIを渡しています。

次に各メソッドについて

classify

 #read tweets
    def classify(self):
        since = None
        classify_list = ["褒めて","ほめて","讃えて","たたえて","えらい"]
        transform_command = ["変身"]
        exclusion_list = ["bot","ビジネス","副業","公式"]

        public_tweets = self.api.home_timeline(count=50,since_id=since)

        for tweet in public_tweets:
            user_name = tweet.user.name#HN
            screen_name = tweet.user.screen_name

            for i in range(len(exclusion)):
                if exclusion_list[i] in user_name:
                    print("not reply")
                else:
                    user_name = user_name.split("@")
                    for i in range(len(classify_list)):
                        if classify_list[i] in tweet.text:
                            if tweet.favorited == False:
                                print("test:承認")
                                #reply
                                self.reply(user_name[0],screen_name,tweet.id,tweet.text)
                                #favorite
                                self.api.create_favorite(tweet.id)
                            else:
                                print("you already replyed it!")

                    for i in range(len(transform_command)):
                        if transform_command[i] in tweet.text:
                            if tweet.favorited == False:
                                print("test: 変身")
                                #transform
                                self.transform()
                                self.api.create_favorite(tweet.id)

classify methodはフォローしている人のつぶやきデータを取得して返事をするかどうか決めています。

返事をするツイートに関しては現在は反応する単語をリスト形式であらかじめ決めており、これに対して逐一反応しています。

(「えらい」にかんしては単純に褒める時と「すごい」という意味で使われるえらいが見分けれないのでこの部分を形態素解析機械学習で何とかできないか考え中です。)

返事をするツイートに対してはreplyメソッドに投げて返事をしていきます。

reply

#返事をする
    def reply(self,user_name,screen_name,tweet_id,tweet_text):
        num = random.randint(1,tweet.max_num())
        num_padded = '{0:03d}'.format(num) #ゼロパディング:0で3桁左詰する。 example 1→001

        reply = "@"+screen_name+"\n "+user_name+tweet.manus(num-1)
        self.api.update_status(status=reply, in_reply_to_status_id=tweet_id)#status
        print("{0}のツイート:{1} に{2}と応援しました!".format(user_name,tweet_text,reply))

reply では引数で与えられたツイートとそのツイートをした人に対して返事をします。

返事の内容はmeta_manuscriptからランダムに選んでいます.

followback

#フォロバする
    def followback(self):
        #最近のフォロワーからその人のtweetやid情報取得
        # followers=api.followers_ids(screen_name=twitter_id)#全てのフォロワーidを取得
        # friends=api.friends_ids(twitter_id)#フォローしている人のidを取得
        followers = self.api.followers_ids(self.twitter_id)
        friends = self.api.friends_ids(twitter_id)

        follow_back = list(set(followers)-set(friends))#list フォロバすべき
        print("list_followback,count:",len(follow_back))

        for i in range(min(len(followback),10)):
            try:
                self.api.create_friendship(followback[i])
                print("success follow!"+str(followback[i]))
            except tweepy.error.Tweeperror:
                print("error")

この部分ではフォローバックを行います。

自分のフォロワーとフレンド(相互フォロワー)をそれぞれsetにして引き算することでまだフォローバックしていない人たちを探します。

鍵垢に対してフォローをするとエラーが許可されずにエラーかえってくるのでtryの部分で調節しています

tweet

transform

def tweet(self):
        status = "順調だもん!"
        self.api.update_status(status=status)

    def transform(self):
        pass

tweet部分はそのままでツイートしたい言葉をあらかじめ入れておけばツイートしてくれる部分です

transform部分は作成したはいいですがどういう変身をするかまだ未定です。(いいアイデアあったら教えてください)

def main():
    hometamon = Hometamon()
    hometamon.classify()
    hometamon.followback()

if __name__ == "__main__":
    main()

最後の部分は実行部です

現在はAWSで運用しているのであとはAWS用にちょっと包んでやれば使えます。

ささっと書いて見ましたが褒めたもんの中身はこんな感じです。

ではでは