forestec

勉強した内容をつらつらと備忘録として記していきます。

PythonでQiitaの新着記事を取得してSlackへ連携してみる

QiitaAPIで自分がフォローしているタグが付いた記事を最新10件取得して、
それをさらにSlackへ連携するツールを作成してみました。

前提

Pythonは3.7.1を使用しています。
Python環境構築については特に触れません。
・Slack APIの作成部分についても触れません。
・ソースはgithubにも上がっています。 github.com

フォローしているタグ一覧を取得

まずはQiitaAPIから自身がフォローしているタグの一覧を取得します。
以下のURLで取得出来ます。

http://qiita.com/api/v2/users/[Qiitaアカウント]/following_tags?page=1

コードは以下です。

import requests

# Qiitaアカウント
qiita_user = ''

# 自分がfollowしているタグの一覧を取得
url = 'http://qiita.com/api/v2/users/' + qiita_user + '/following_tags'
params = {'page': '1'}
following_tags = requests.get(url, params=params).json()

following_tagsに取得結果が入っています。
中身はこんな感じです。

[
 {
  'followers_count': 2106,
  'icon_url': ,
  'id': 'React',
  'items_count': 1999
 }
]

4つフィールドが取得出来ましたが、今回使用するのは「id」のみです。
これがタグ名になっています。

Qiita新着記事を取得

次はQiitaAPIを使用して新着記事を取得する部分です。
以下のURLで取得出来ます。

http://qiita.com/api/v2/items?page=1&per_page=10

これで新着記事が10件取得出来ます。
「per_page」の件数を変更すると取得件数が変わります。

import requests

# QiitaAPIを使用して新着記事を10件取得
url = 'http://qiita.com/api/v2/items'
params = {'page': '1', 'per_page': '10'}
new_articles = requests.get(url, params=params).json()

new_articlesに取得結果が入っています。
中身はこんな感じです。

[
 {
  'rendered_body': ,
  'coediting': ,
  'comments_count': ,
  'created_at': ,
  'group': ,
  'id': ,
  'likes_count': ,
  'private': ,
  'reactions_count': ,
  'tags': [
   {
    'name': 'Python',
    'versions': []
   }
  ],
  'title': ,
  'updated_at' : ,
  'url': ,
  'user': {
   'description': ,
   'facebook_id': ,
   'followees_count': ,
   'followers_count': ,
   'github_login_name': ,
   'id': ,
   'items_count': ,
   'linkedin_id': ,
   'location': ,
   'name': ,
   'organization': ,
   'permanent_id': ,
   'profile_image_url': ,
   'twitter_screen_name': ,
   'website_url': 
  },
  'page_views_count': 
 }
]

例によってほとんどの項目は使用しません。。。

ひとまずこれでフォローしているタグの一覧と新着記事の取得が出来ました。

記事の絞り込み

では次にフォローしているタグが含まれる記事のみに絞り込みます。
絞り込みは記事の取得時のURLでクエリパラメーターを追加してあげることで可能です。

http://qiita.com/api/v2/items?page=1&per_page=10&query=[ここに条件を指定]

先程取得してきたタグの一覧を条件に含める部分のソースは以下になります。

# 自分がfollowしているタグの一覧を取得
url = 'http://qiita.com/api/v2/users/' + qiita_user + '/following_tags'
params = {'page': '1'}
following_tags = requests.get(url, params=params).json()

# フォローしているタグを記事取得時の検索で使用出来るようにする
# 記事取得時のqueryにtag:[タグ名]でそのタグが含まれる記事を取得出来るので、
# フォローしているタグのいずれかを含むものを取得出来るようにORでつなげていく
query = ''
for i in range(len(following_tags)):
    query = query + 'tag:' + following_tags[i]['id'] + " OR "

# QiitaAPIを使用してフォローしているタグを含む新着記事を10件取得
url = 'http://qiita.com/api/v2/items'
params = {'page': '1', 'per_page': '10', 'query': query.rstrip(' OR ')}
new_articles = requests.get(url, params=params).json()

タグが含まれているかの条件はtag:[タグ名]で可能です。
検索時の条件をORで繋げて指定することが出来ます。

ここまでで自分がフォローしているタグを含む新着記事10件を取得することが可能になりました。

Slackへ送信

次はSlackへ取得した記事を送信する部分です。
10件分の記事を送信するので、
1回分の送信をスレッド化してメッセージが長くならないようにしてみます。

まずは最初にスレッドタイトルの送信部分です。

# slack送信用のHeader
headers = {
    'Content-Type' : 'application/json; charset=utf-8',
    'Authorization' : 'Bearer ' + slack_token
}

# slackへ送信(スレッドタイトル)
web_hook_url = "https://slack.com/api/chat.postMessage"
res = requests.post(web_hook_url, data = json.dumps({
    'channel': slack_channel,  # チャンネル
    'attachments': [{ 'title' : 'Qiita新着投稿' }],  # 通知内容
}), headers = headers)

「Qiita新着投稿」というattachmentsだけを送信するシンプルなものになっています。
headerに「Content-Type」と「Authorization」を指定しています。
「slack_token」にはSlackAPIのトークンを発行したものを指定しています。
「slack_channel」には投稿するチャンネルを指定しています。

次にスレッド化して記事を送信します。
先程送信したスレッドタイトルのレスポンスから「ts」を取得します。
それを記事送信時に「thread_ts」にセットすることで紐付けることが可能。
コードは以下です。

# slackへ送信(スレッドタイトルに紐付けて記事をスレッド化)
# スレッドタイトルを送信した際のレスポンスの'ts'を'thread_ts'にセットすることで紐付けしている
requests.post(web_hook_url, data = json.dumps({
    'channel': slack_channel,  # チャンネル
    'attachments': attachments,  # 通知内容
    'thread_ts' : res.json()['ts'],  # スレッドタイトルの'ts'
}), headers = headers)

「attachements」には取得した記事を入れています。
生成のロジックは以下です。

# 取得した記事を1つずつattachmentに詰めていく
attachments = []
for i in range(len(new_articles)):
    # 記事のタグを取得
    tags = 'タグ:'
    for tag in new_articles[i]['tags']:
        tags = tags + '[' + tag['name'] + ']'

    # 投稿した記事をattachmentに追加
    attachments.append(
        {
            'title' : '<' + new_articles[i]['url'] + '|' + new_articles[i]['title'] + '>',  # タイトルと記事のリンク
            'text' : tags,  # 記事のタグ
            'author_name' : new_articles[i]['user']['id'],  # 投稿者名
            'author_link' : 'https://qiita.com/' + new_articles[i]['user']['id'],  # 投稿者のQiitaページへのリンク
            'author_icon' : new_articles[i]['user']['profile_image_url'],  # 投稿者のQiitaアイコン
            'footer' :  new_articles[i]['updated_at']  # 記事の投稿時間
        }
    )

記事自体はセットせず、記事タイトルとリンクなどを送信しています。
これで全て完成です。
実際にslackへ送信すると以下のようになります。
スクリーンショット 2018-11-25 0.01.48.png
ちゃんとスレッド化されています。
スレッドを開くと以下のような感じです。
スクリーンショット 2018-11-25 0.03.41.png
見やすく表示させることが出来ました。