【Python】初めてTwitter botを作ってみる【salary separate bot】

# 注意！！
この記事はPython学習を始めてみたいただの学生が自分で調べてbotを作ってみたいだけだけどそれだけじゃ物足りない感があったので惰性で書いている記事ですのでお気をつけをば。
完成するまでは途中経過を載せていく予定です。忙しいので定期的に更新するのは難しいと思います。

# 作ってみたいもの
>さ、さすがに最近の金遣いの荒さがやばい、、、！！！！
>
>>じゃあTwitterアカウントにメンションして今月の給料を送信したら今月いくらまで使っていいか教えてもらえば節約もできるし最近チャレンジしてみたかったPythonの勉強もさわりだけでもできるのでは！？！？！？天才かも！！！！！！！

ということで早速やってみたいと思います。
# 事前準備
まずbotを作る前に取得しておかなければいけないものや色々の準備、確認をいろいろしちゃいます。
## Twitter APIを取得する
とりあえず調べた感じTwitter APIなるものを取得してPythonでTwitterを操作できるようにしなければいけないらしい。

まずTwitterの[デベロッパーサイト][develop]にアクセス

[develop]:https://developer.twitter.com/en/apps/

>このサイト調べるといろいろなUIの画像が出てくるので結構頻繁にデザインが変わってるぽい

アクセスすると
![スクリーンショット 2022-07-21 122436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/6a5edbb0-055a-b1a0-b530-f3d1ca601a30.png)
こんな感じな画面が出てきた。Create an Appをクリック。

アカウント名とメールアドレスはTwitterアカウントに設定されているのが先に入力されているはずなのでその下の設定をしてLet's do thisをクリック。

![スクリーンショット 2022-07-21 122544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/abc1d4cb-1147-4d6b-a440-fd55f8a11ffc.png)

クリックしたらこんな感じで利用規約の確認みたいなのが出てくるので一応さらっと読み飛ばしてチェックボックスをクリックしてsubmitをクリック。
![スクリーンショット 2022-07-21 144732.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/27e82e9a-24b7-7a14-96d3-93df728d21b8.png)
**注意**
このタイミングでTwitterアカウントに携帯電話番号が紐づけられてないと以下のような警告が出て先に進めません
~~これが分かってなくて30分くらい闘ってた~~
![スクリーンショット 2022-07-21 144415.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/9e6fd466-bc9c-f152-40c9-abb29ecfdc16.png)

submitをクリックしたらいろいろコピーできるのが出てきたあと、Gmailの認証などがあったと思いますが、その時のスクリーンショットがないためいい感じにDeveloper PortalのDashbordページまで頑張って進んでください。
(いろいろコピーできるやつは後からコピーするやつを使うのでこのタイミングではコピーしなくて大丈夫です)

Dashboardページまで行けたら左側のタスクバーにあるProjects & Appsから新しいプロジェクトを作成。名前はいい感じにそれっぽいのにしました。
![スクリーンショット 2022-07-21 220224.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/34b21199-e796-5195-1ec9-44cf16dc6bde.png)

settingsの隣にあるKeys and tokens→Set up→OAuth 1.0a→Read and writeを選択し、Call back URLとWebsite URLに自分のTwitterアカウントのプロフィールページのURLを入力しSaveをクリック。
(ここら辺画像なくてすみません！！)

![スクリーンショット 2022-07-22 011936.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/fd656aa9-420a-b510-dce8-2f41a6c86cc8.png)
そしてこのタイミングでAPI Key,API Key Secret,Access Token,とAccess Token SecretをRegenerateし、他の場所にメモしておきます。（一番最初に出てきたAPI KeyはRead and writeのチェックボックスにチェックが入っていないので使うことができない）
これでTwitter APIの取得は完了です。

## 試しにツイートしてみる
先にPowerShellでtweepyとpprintが必要そうなのでインストール
~~~
    pip install tweepy
    pip install pprintpp
~~~

その後VSCodeなりエディタで以下のコードを入力

~~~python:test.py
    import tweepy

    ck = 'API Key'
    cs = 'API Key Secret'
    at = 'Access Token'
    ats = 'Access Token Secret'

    client = tweepy.Client(consumer_key=ck,consumer_secret=cs,access_token=at,access_token_secret=ats)

    client.create_tweet(text="テスト")

~~~
このコードを実行してみると
![スクリーンショット 2022-07-22 015503.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/a88b6b6c-2605-539c-9cdf-bd8d33fa7dd8.png)
こうなります。下の段を見てわかるようにsalary separate botからツイートされていることがわかります。
~~ネーミングセンスのなさは気にしないで！！！~~

# 情報を整理
まずやりたいことを改めて書いていきたいと思います。
1. いつも使っているアカウントから給料計算botにメンションして給料を送信
2. 給料計算botがツイート内容をリアルタイムで取得、10000円食費、残りの20%貯金、残りの80%を自由に使っていいこととし ~~(自分に甘すぎない？)~~ 、計算し元ツイートにリプライを送信

という形になります。

おそらく必要になってくるのが
- リアルタイムでずっと動いてくれるサーバー(面倒くさくなったら家にある壊れかけのデスクトップをつけっぱにしてるかも)
- 元ツイートからXXXXX円で届く情報から数学文字だけ取り出しそこから10000円をマイナスし、20%、80%に分けてそれをリプするプログラム

の2つだと思われます。

# プログラムを組んでみる
まず実際に出来上がったコードがこちらです

~~~python:salary_separate_bot.py
from http import client
from unittest import result
import tweepy
from pprint import pprint
import re
from key import bt, ck, cs, at, ats

#クライアント関数
client = tweepy.Client(bearer_token=bt,consumer_key=ck,consumer_secret=cs,access_token=at,access_token_secret=ats)

auth = tweepy.OAuthHandler(ck, cs)
auth.set_access_token(at, ats)

api = tweepy.API(auth)

#必要情報
tmp = 'https://twitter.com/普段使いのTwitterユーザー名/status/'
search = "@kyuryokesanbot"
tweet_max = "10"

#関数
def SearchTweets(search,tweet_max):
    #直近のツイート取得
    tweets = client.search_recent_tweets(query = search,max_results = tweet_max)
    
    #取得したデータ加工
    results = []
    tweets_deta = tweets.data
    
    
    #tweet検索結果取得
    if tweets_deta != None:
        for tweet in tweets_deta:
            obj = {}
            obj["tweet_id"] = tweet.id
            obj["text"] = tweet.text
            results.append(obj)
            
    else:
        results.append('')
        
    
    #出力結果
    return results[0]

#関数実行・出力
pprint(SearchTweets(search,tweet_max))


#関数の結果を変換・数学文字以外を削除
s = str(SearchTweets(search,tweet_max))
result = re.findall(r"\d+",s)
    
#idと給料に分ける
id = str(result[0])
salary = int(result[1])

#数値計算
save = salary*0.2
S = salary*0.8
tukatteiiyo = S-10000

#小数点丸めて代入
saveR = round(save)
tukatteiiyoR = round(tukatteiiyo)

#ツイートする
client.create_tweet(text='給料 : {}\n貯金 : {}\n使っていいよ : {}\n食費 : 10000\n{}{}'.format(salary,saveR,tukatteiiyoR,tmp,id))

~~~
実行するとこんな感じになります
![スクリーンショット 2022-08-29 042306.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/9c711611-a8e2-314d-6668-55e3c881dc71.jpeg)
ぱっと見であれ？ってなるところがあるかもしれませんが安心してください、後で詫びます。

では最初から解説していきます。

まず先ほどのテストツイートで使用したキーを他のkey.pyというファイルに保存しておきます。
~~~python:key.py
bt = 'Bearer Token'
ck = 'API Key'
cs = 'API Key Secret'
at = 'Access Token'
ats = 'Access Token Secret'
~~~

**そこから変数を取得してクライアント関数を定義**
~~~python
#クライアント関数
client = tweepy.Client(bearer_token=bt,consumer_key=ck,consumer_secret=cs,access_token=at,access_token_secret=ats)

auth = tweepy.OAuthHandler(ck, cs)
auth.set_access_token(at, ats)

api = tweepy.API(auth)
~~~

**必要情報を入力**
ここのURLは後で出てきますが普段使いのユーザー名の場所は、自分のTwitterのユーザー名から@を抜いたものにしてください(e.g. @kyuryokesanbotの場合、kyuryokesanbot)
~~~python
#必要情報
tmp = 'https://twitter.com/普段使いのTwitterユーザー名/status/'
search = "@kyuryokesanbot"
tweet_max = "10"
~~~

**関数**
関数部分は参照のどれかの~~ほぼパクリ~~なのでそのサイトを見てもらえた方がいいと思います。
ほぼ唯一変えた場所はサーチの最低回数が10回で、returnが配列で10個分返ってきてたので一番最後のツイート分のresults[0]だけ返すようにしたくらいです。
~~~python
#関数
def SearchTweets(search,tweet_max):
    #直近のツイート取得
    tweets = client.search_recent_tweets(query = search,max_results = tweet_max)
    
    #取得したデータ加工
    results = []
    tweets_deta = tweets.data
    
    
    #tweet検索結果取得
    if tweets_deta != None:
        for tweet in tweets_deta:
            obj = {}
            obj["tweet_id"] = tweet.id
            obj["text"] = tweet.text
            results.append(obj)
            
    else:
        results.append('')
        
    
    #出力結果
    return results[0]
~~~
\
**とりあえず関数実行してみてツイートが取得できてるか確認する**
~~~python
pprint(SearchTweets(search,tweet_max))
~~~
{'text': '@kyuryokesanbot 55000円', 'tweet_id': @@@@@@@@@@@@@}
↑こんな感じで出てくるので(@の部分は固有の数)、ここから文字を消して数字のみを残すようにします

\
**出力結果から数学文字以外を削除**
~~~python
#関数の結果を変換・数学文字以外を削除
s = str(SearchTweets(search,tweet_max))
result = re.findall(r"\d+",s)
~~~
\
**代入**
このあとこの二つの数字を使う時にidが文字列、給料が整数型であってくれた方が楽なので変換して代入します
~~~python
#idと給料に分ける
id = str(result[0])
salary = int(result[1])
~~~
\
**数値計算**
数値計算はまぁ簡単ですね。ここはプログラミングのさわりのさわりだけでも触ったことがあったらできると思います
~~あと変数名は悩みに悩みまくった結果大変なことになってます~~
~~~python
#数値計算
save = salary*0.2
S = salary*0.8
tukatteiiyo = S-10000
~~~
\
**小数点以下を削除**
お金を表すときに小数点以下の数字があるのはなんか気持ち悪いな、ということで小数点丸めて代入
~~~python
#小数点丸めて代入
saveR = round(save)
tukatteiiyoR = round(tukatteiiyo)
~~~

## ここでお知らせ
ここでお知らせというか余談というかお詫びというか言い訳をば
>うーん、TLから情報を取得して処理まではできるけどリプで返信のやり方がいろんなサイト見ても見つからんな……(リプで返信の方法だけで2週間+テスト期間突入)
>
>>…………ハッ！！！！！！！！！！(閃き)
>>ここでクソツイッタラー天才再臨
>
>引用RTならいけるでおい！！！！！！

ということで当初のリプで返信から引用RTに手段を変更することに決定いたしました

ここで引用リツイートの仕組みを解説していきます
普段はここを押して引用RTしていると思いますが
![スクリーンショット 2022-09-02 041206.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/0d62fa33-5721-59d9-8366-50e4a4eb7c3e.png)
実はこれ、
https://twitter.com/普段使いのTwitterユーザー名/status/@@@@@@@(引用元固有のツイートid) 
みたいなURLをツイートの一番下に入れれば引用リツイートになるんです！！！
![スクリーンショット 2022-09-02 044408.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/4e2c4c61-1b90-f5f3-24c8-fc7036fbac82.png)
![スクリーンショット 2022-09-02 045115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501465/e33ca3b1-7015-4d60-d107-44c708ac298e.png)
~~ツイートしてる時間は見ないで~~
関数を実行し、idをコピペしてテストツイートしてみたらいけたのでこの方向性で決定

閑話休題

最後にツイート部分です
一番最初のテストツイートをベースに、いい感じにします。tmp+idがURLの部分です
~~~python
#ツイートする
client.create_tweet(text='給料 : {}\n貯金 : {}\n使っていいよ : {}\n食費 : 10000\n{}{}'.format(salary,saveR,tukatteiiyoR,tmp,id))
~~~

# まとめ
いかがでしたか？
ここでとりあえあずのプログラムは完成とします。次の記事でメンションされたら引用RTされるようにしたいと思います。夏休み中には頑張りたい！！！！！

基本的にガチねむのときに書いているのでミスがあるかもしれないので気軽に言ってください(AM5:20)

追伸
Twitterとかいうオープンな場所で自分の給料ツイートしてるのワロタ

# 参照
[PythonでTwitter botを作ってみた][Pythonby]

[Pythonby]: https://zenn.dev/shuntatakemoto/articles/00264c2b366612
[tweepy + Twitter API V2でツイート][tweepy1]

[tweepy1]: https://qiita.com/penguinprogrammer/items/b220be0c203eaaad015a
[pythonでtwitter APIを取得する方法【全18枚の図解+例文あり】][twitterapi]

[twitterapi]: https://python-man.club/python_twitter_api/
[Getting started — tweepy 3.5.0 documentation][tweepy2]

[tweepy2]: https://docs.tweepy.org/en/v3.5.0/getting_started.html
[【Python×Twitter】検索ツイートのデータ取得・分析｜APIとtweepy活用による自動運用アプリ開発支援][tweepy3]

[tweepy3]: https://di-acc2.com/system/rpa/9690/

[【Python】文字列から数字だけを取り出す方法][python1]

[python1]: https://niwakomablog.com/python-number-extract/
[Pythonで数字の文字列strを数値int, floatに変換][python2]

[python2]: https://note.nkmk.me/python-str-num-conversion/
[Tweepyで雑にTwitter botを作ってみた][python3]

[python3]: https://qiita.com/tsc343/items/e51f412480ea8bf5619a
[Twitter Botで引用RTをするときにつまづいたメモ][python4]

[python4]:https://qiita.com/addtobasic/items/20ea00891bb8a152ed46