【Python】特定のハッシュタグが付いたツイートを自動的にTrelloのカードに追加

##はじめに
###背景
初めまして、桃熊猫(@momopanda_jp )です。
私はTwitterでやりたいことを結構書くのですが、TLで流れて忘れてしまうので、
ツイートしたら自動的にTrelloのカードに追加できたら便利そうだなと思い、
コーディングすることにしました。

今回はTwitterのデータの操作に便利なライブラリ「tweepy」を使ってみようと思います。
詳しくはこちら→[tweepy](https://kurozumi.github.io/tweepy/)

###対象
・Twitter API未取得の方
・Trello API未取得の方
・Google Cloud Platform(GCP)未登録の方
・やりたいことなどをリスト化したい方
・ツイートはするけど、Trelloに一々追加するのが面倒な方

###環境
Windows10 Home
Python3.7
VSCode
Chrome

#目次
######1．Twitter API・Trello APIの取得
　1-1. Twitter API取得
　1-2. Trello API取得
######2．ツイートの取得
######3．Trelloへのカード追加
　3-1. Trelloのボード・リストのIDを取得
　3-2．カードの名前をツイート内容にして追加
　3-3. 同じ内容のツイートは追加しないようにする
######4．GCPの登録・自動化




#1．Twitter API・Trello APIの取得
####1-1. Twitter API取得
[Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ　※2019年8月時点の情報](https://qiita.com/kngsym2018/items/2524d21455aac111cdee)を
参考に取得しました。


####1-2．Trello API取得
[PythonでTrelloのタスクを取得する](https://miyabikno-jobs.com/python-api-trello/)の「【準備】TrelloのAPIトークンとシークレットを取得する」を参考に、
キー・トークンを取得しました。



#2．ツイートの取得
####2-1．tweepyのインストール

```command:コマンド
pip install tweepy
```

####2-2. ツイートの取得・整形

```python:Python
import tweepy

#Twitter API
#各キーを取得
consumer_key = 'xxxxxxxxxxxxxxxxx'
consumer_secret = 'xxxxxxxxxxxxxxxxxxx'
access_token = 'xxxxxxxxx-xxxxxxxxxxxxxx'
access_token_secret = 'xxxxxxxxxxxxxxxxxx'
    
#認証情報を設定    
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_token, access_token_secret)

#APIインスタンスの作成
api = tweepy.API(auth)

#自分のハッシュタグが付いた最新のツイートの内容を一つずつ出力
#qは出力したいワード（今回はハッシュタグ）を指定
#screen_nameは出力したいアカウントのID
#result_type='recent'で最新のツイートを指定
#itemsの引数で一回で出力できるツイート数を指定できる
for tweet in tweepy.Cursor(api.search, q = '#○○○○', screen_name = 'xxxxxxxxxx', result_type = 'recent').items(1):
    wish = tweet.text.replace('\\n', '').replace('RT @xxxxxxxxxx: ', '').replace('#○○○○', '').replace('\n','')
```

参考：[Pythonで特定のキーワードが付与されたツイート収集する方法](https://qiita.com/myaun/items/f13320f7451928e68e0d)
　　　[tweepyレファレンス](https://kurozumi.github.io/tweepy/index.html)


#3．Trelloへのカード追加
###3-1. Trelloのボード・リストのIDを取得
Trelloの情報がJSON形式なので、見やすいように[jq](https://stedolan.github.io/jq/)をインストールして、PATHを通します。
PATHの通し方は[Windows で環境変数 PATH をいじる方法のまとめ](https://qiita.com/sta/items/6d29da0dc7069ffaae60)を参考にさせてもらいました。
curlしたいURLは[Trello(Get Boards that Member belongs to)](https://developer.atlassian.com/cloud/trello/rest/api-group-members/#api-members-id-boards-get)の例を参考にしてください。

追加したいボードのIDを以下のように取得します。

```command:コマンド
curl "https://trello.com/1/members/{userID}/boards?key={Key}&token={token}&fields=name" | jq
```
出力結果はこのように表示されます。

```command:コマンド(結果)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   117  100   117    0     0    117      0  0:00:01 --:--:--  0:00:01   207
[
  {
    "name": "To do list",
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx"
  },
  {
    "name": "やりたいこと",
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx"
  }
]
```



追加したいリストのIDも以下で取得できます。

```command:コマンド
curl "https://trello.com/1/boards/{BoardID}/lists?key={key}&token={token}&fields=name" | jq
```
```command:コマンド(結果)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   319  100   319    0     0    319      0  0:00:01 --:--:--  0:00:01   600
[
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "未着手"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "勉強すること"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "作業中"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "完了"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "合格"
  },
  {
    "id": "xxxxxxxxxxxxxxxxxxxxxxxx",
    "name": "中止"
  }
]
```


###3-2. カードの名前をツイート内容にして追加
```python:Python
import tweepy
from trello import TrelloApi

# Trello API
# Key Token
#trello = TrelloApi('キー', 'トークン')
key = 'xxxxxxxxxxxxxx'
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
trello = TrelloApi(key, token)
    
# List ID　ボードIDから調べたリストID
listid = 'xxxxxxxxxxxxxxxxxxxxxx'

#自分のハッシュタグが付いたツイートを一つずつ出力
for tweet in tweepy.Cursor(api.search, q = '#○○○○', screen_name = 'xxxxxxxxxx', result_type = 'recent').items(1):
        wish = tweet.text.replace('\\n', '').replace('RT @xxxxxxxxxx: ', '').replace('#○○○○', '').replace('\n','')

        # Card Name
        cardname = wish #特定のハッシュタグ付きのツイート内容
        
        # Card Description
        #desc = '新しいタスクの内容です。1行目n新しいタスクの内容です。2行目n新しいタスクの内容です。3行目n'
        desc = ''
        card = trello.cards.new(cardname, listid, desc)
```
###3-3．同じ内容のツイートは追加しないようにする
```python:Python
import tweepy
import json
from trello import TrelloApi
import requests


# Trello API
# Key Token
#trello = TrelloApi('キー', 'トークン')
key = 'xxxxxxxxxxxxxxxxxxxx'
token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
trello = TrelloApi(key, token)
    
# List ID　ボードIDから調べたリストID
listid = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' 
    

#既にあるカードの確認
url = "https://trello.com/1/lists/" + listid + "/cards"
query = {'key': key, 'token': token, 'fields': 'name'}
r = requests.get(url, params = query)
data = r.json()
    
name_list = []
    
for x in range(len(data)):
    name = data[x]['name'].replace('\n','')
    name_list.append(name)


#自分のハッシュタグが付いたツイートを一つずつ出力
for tweet in tweepy.Cursor(api.search, q = '#○○○○', screen_name = 'xxxxxxxxxxx', result_type = 'recent').items(1):
     wish = tweet.text.replace('\\n', '').replace('RT @xxxxxxxxxxx: ', '').replace('#○○○○', '').replace('\n','')
        
     #カードが重複しないように設定
     if wish not in name_list:
         # Card Name
         cardname = wish #カードの名前を特定のハッシュタグ付きのツイート内容にする
        
         # Card Description
         #desc = '新しいタスクの内容です。1行目n新しいタスクの内容です。2行目n新しいタスクの内容です。3行目n'
         desc = ''

         card = trello.cards.new(cardname, listid, desc)

        else:
            break

```

参考：[【30分で動かすシリーズ】TrelloにAPIを使ってカードの起票や取得をしてみる](http://blog.serverworks.co.jp/tech/2016/05/16/trello-api/)
　　　[Trello(Create a new card)](https://developer.atlassian.com/cloud/trello/rest/api-group-cards/)

#4．GCPの登録・自動化
まず[Google Cloud Platform](https://cloud.google.com/getting-started?hl=ja)を登録しましょう。


[サーバーレス ＋ Pythonで定期的にスクレイピングを行う方法](https://gammasoft.jp/blog/schdule-running-python-script-by-serverless/)を参考に、登録から作ったジョブの実行まで進めていきます。


順番は以下の通りです。
・GCP登録
・GCPでプロジェクト作成
・Cloud Functionsの作成
　　　・関数の作成
　　　・ソースコードの作成
　　　・関数のテスト
・Cloud Schedulerの作成
　　　・ジョブの実行




関数の作成時に、私はランタイムを**Python3.7**にして、
ソースコードの入力時に**main.py**、**requirement.txt**は以下のように書きました。
mainの引数の**event**、**context**は関数に含まれていなくても、書いておかないと実行できないので注意しましょう。

```python:main.py
import tweepy
import json
from trello import TrelloApi
import requests

def main(event, context):
    #Twitter API
    #各キーを取得
    consumer_key = 'xxxxxxxxxxxx'
    consumer_secret = 'xxxxxxxxxxxxxxx'
    access_token = 'xxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxx'
    access_token_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    
    #認証情報を設定
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)

    #APIインスタンスの作成
    api = tweepy.API(auth)

    # Trello API
    # Key Token
    #trello = TrelloApi('キー', 'トークン')
    key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    trello = TrelloApi(key, token)
    
    # List ID　　　上記で調べたボードIDから調べたリストID
    listid = 'xxxxxxxxxxxxxxxxxx'
    

    #既にあるカードの確認
    url = "https://trello.com/1/lists/" + listid + "/cards"
    query = {'key': key, 'token': token, 'fields': 'name'}
    r = requests.get(url, params = query)
    data = r.json()
    name_list = []
    
    for x in range(len(data)):
        name = data[x]['name'].replace('\n','')
        name_list.append(name)


    #自分のハッシュタグが付いたツイートを一つずつ出力
    for tweet in tweepy.Cursor(api.search, q = '#○○○○', screen_name = 'xxxxxxxxxxx', result_type = 'recent').items(1):
        wish = tweet.text.replace('\\n', '').replace('RT @xxxxxxxxxxx: ', '').replace('#○○○○', '').replace('\n','')
        
        #カードが重複しないように設定
        if wish not in name_list:
            # Card Name
            cardname = wish #特定のハッシュタグ付きのツイート内容
        
            # Card Description
            #desc = '新しいタスクの内容です。1行目n新しいタスクの内容です。2行目n新しいタスクの内容です。3行目n'
            desc = ''
            card = trello.cards.new(cardname, listid, desc)
        else:
            break

```


```requirement.txt
# Function dependencies, for example:
# package>=version
tweepy>=3.8.0
trello>=0.9.4
requests>=2.23.0
```

今回、Cloud Schedulerでは、1分ごとに関数が実行されるように設定しました。
ツイートを沢山する方は、出力するツイート数を増やしたりして調整してください。

参考：[Cloud Function](https://cloud.google.com/functions/docs/how-to?hl=ja)
　　　[Cloud Scheduler](https://cloud.google.com/scheduler/docs/quickstart?hl=ja)


以上になります。閲覧ありがとうございました！