LoginSignup
0
1

More than 1 year has passed since last update.

GitHub Actions を使って Qiita のviews 数を Slack に通知するアクションを python で作った

Last updated at Posted at 2021-06-05

JavaScript や TypeScript で作られたアクションは割とよく見るのですが、 Python で作られた Actions は見ないので(そもそも Python で書く必要がない?)今回は Python を使って Action コードを作ってみたいと思います。

動作環境

Actions は Docker コンテナのアクションまたは JavaScript アクションの2種類あります。Python で書くために今回は Docker コンテナのアクションを採用します。 Docker コンテナで Python が実行できるようにベースイメージには Python を設定します。

ディレクトリ構成

Python コードは src ディレクトリ配下に置き Docker のCOPY コマンドでコンテナ内にコピーさせます。action.ymlは GitHub Actions のメタデータファイルです。
https://docs.github.com/ja/actions/creating-actions/creating-a-docker-container-action#creating-an-action-metadata-file

.
├── Dockerfile
├── action.yml
├── entrypoint.sh
└── src
    ├── main.py
    ├── qiita.py
    ├── requirements.txt
    └── slack.py
action.yml
name: 'Slack Notify'
description: 'You can notify slack of GitHub Actions.'
runs:
  using: 'docker'
  image: 'Dockerfile'

モジュール

slackに通知するためのコードで sdk を使用できるようにするために、slack-sdkモジュールをインストールします。

requirements.txt
slack-sdk==3.5.1

ビュー数の取得

Qiita 記事のビュー数を取得するコードを書いていきます。ビュー数を取得するためには個別記事を取得する必要があります。そのためにまずは記事一覧取得APIを実行して一覧を取得し、取得したデータから個別記事のIDを抜き出して個別記事取得APIを叩きビュー数を取得します。qiita api のトークンは環境変数設定して取得できるようにします。

qiita.py
import urllib.request
import json
import os

def sendRequest(url):
    req = urllib.request.Request(url)
    req.headers = {
        'Authorization': 'Bearer ' + os.environ['TOKEN']
    }
    with urllib.request.urlopen(req) as response:
        decode = json.loads(response.read().decode('utf-8'))
    return decode

def getIds(url):
    decode = sendRequest(url)
    ids = []
    for s in range(len(decode)):
        ids.append(decode[s]['id'])
    return ids

def getViews(ids):
    originUrl = 'https://qiita.com/api/v2/items/'
    views = []
    for s in range(len(ids)):
        url = originUrl + ids[s]
        decode = sendRequest(url)
        views.append({
            "title": decode['title'],
            "views": decode['page_views_count']
        })

    return views

def views():
    url = 'https://qiita.com/api/v2/users/kiyo27/items?page=1&per_page=20'
    ids = getIds(url)
    return getViews(ids) 

slack に通知

slack から sdk が提供されているのでそれを使用します。webhook url は環境変数に設定しておきます。

slack.py
import os
from slack_sdk.webhook import WebhookClient

def notify(views):
    url = os.environ['WEBHOOK']
    webhook = WebhookClient(url)

    blocks = []
    for s in range(len(views)):
        title = views[s]['title']
        viewCount = views[s]['views']
        text = title + "\n:star::star::star::star: "
        text = text + str(viewCount) + "views"
        blocks.append({
            "type": "section",
            "text": {
                "type": "mrkdwn",
                "text": text
            }
        })

    response = webhook.send(text="fallback", blocks=blocks)

コンテナ作成

ベースイメージに python を設定して、qiita の view 数を取得するコードと slack に通知するコードをCOPYコマンドコンテナ内に取り込みます。コンテナ起動時に実行されるブートコードとしてentrypoint.shを設定しておきます。

Dockerfile
FROM python:3.9.5-slim-buster

COPY src /usr/app
COPY entrypoint.sh /entrypoint.sh

RUN pip install -r /usr/app/requirements.txt \
    && chmod +x /*.sh

ENTRYPOINT ["/entrypoint.sh"]

entrypoint.shの中身。main.py を実行しています。

entrypoint.sh
#!/usr/bin/env bash

python /usr/app/main.py

main.pyの中身。コマンドラインから実行されたとき、 run メソッドを呼び出します。 run メソッドでは qiita の個別記事の view 数を取得し、取得結果を slack に通知するロジックにしています。

main.ph
import qiita
import slack


def run():
    views = qiita.views()
    slack.notify(views)

if __name__ == "__main__":
    run()

Actions で実行

作成したアクションを実行するために、 Actions の workflow を作成します。usesに先ほど作成したアクションを指定します。サンプルアクションはこちらで GitHub に上がっています。 Qiita API トークンと Slack Webhook URL はコード内では環境変数から取得しているので、 workflow 構文でenvを使用して環境変数を設定しています。環境変数として設定する値は、GitHub の シークレットを利用して設定しておきます。設定の仕方は下のリンクから確認できます。あとはこの workflow ファイルを GitHub にプッシュすればアクションが実行されて slack に qiita の 個別記事ごとの views 数が記載された状態で通知がきます。

workflow.yml
on: [push]

jobs:
  slack_notify:
    runs-on: ubuntu-latest
    name: A job to send a message to slack
    steps:
    - name: Slack notification
      id: slack
      uses: kiyo27/action-slack-notify@main
      env:
        TOKEN: ${{ secrets.TOKEN }}
        WEBHOOK: ${{ secrets.WEBHOOK }}

Desktop-screenshot.png

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1