4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub ActionsでGitHubの日報をXに自動投稿する方法

Last updated at Posted at 2024-10-07

はじめに

皆さま初めまして。
HapinessChainというオンラインスクールで奮闘中のKeiと申します。

ここでは学習した内容をメンターに日報として報告していますが、
成果をXにも投稿したく今まではGithub上にある日報を手動でコピーしてポストしていました。

大した労力ではないですが、毎日となると案外手間なので、
GitHubプッシュ時にコミットした内容を自動的にポストするようにしました。

実際にやってみるとそこまで難しくなく実装できたので、
今回はGitHub Actionsを利用してポストを自動投稿するやり方を紹介します。

環境構築と実装については以下の記事を参考にさせて頂いております。

X Developer Portalの登録

X Developer Portalは、開発者がXのAPIを利用してアプリケーションを構築するためのプラットフォームになります。

まずはX Developer Portalにプロジェクトとアプリケーションを登録します。

  1. 右上の開発者ポータルを押下します
  2. Xにログインしていない場合はログインしてください
  3. 画面下のSign up for Free Accountを選びます
  4. Describe all of your use cases of Twitter’s data and API欄に使用用途を英語で記載し、Submitを押下してください。内容で精査されることは基本的にありません

画面左側のProject & AppsにプロジェクトとAPIが作成されていると思います。

iScreen Shoter - Google Chrome - 241008111514.jpg

認証設定

デフォルトではXへの書き込み権限がないためまずは認証設定を行います。

  1. 遷移していない場合は開発者ポータル画面に遷移します
  2. 左側のメニューより[Project & Apps] > [xxxxxxAccountName]を選択し、APIの管理画面に遷移します
  3. 画面中央のUser authentication settingsの[Set up]を押下します
  4. App permissionsRead and writeをまたはRead and write and Direct Messageを選択します。ReadだとXにポストできません
  5. Type of Appの欄ですが今回はWebアプリなのでWeb App Automated App or Botを選択します
  6. App infoCallback URIWebsite URL欄はOAuth認証が必要な場合において設定します。必須項目ではありますが、今回は特に使用しないので自分のXアカウントのURLを指定してください
  7. 内容に問題なければSaveを押下してください

iScreen Shoter - Google Chrome - 241008105351.jpg

これでXへの書き込み権限が付与されます。

APIキーの取得

Xへの連携用のキーを取得します。
今回は以下の5つのAPIキーを使用します。

  • Consumer API Key
  • Consumer API Secret
  • Bearer Token
  • Access Token
  • Access Token Secret
  1. 左側のメニューより[Project & Apps] > [xxxxxxAccountName]を選択し、APIの管理画面に遷移します
  2. 画面上部のタブよりKeys and tokensを選択します
  3. 以下の項目においてgenerateを押下し、APIキーを取得してください。紛失時は再度生成する必要があるため、しっかりとメモしておいてください
    • API Key and Secret
    • Bearer Token
    • Access Token and Secret

iScreen Shoter - Google Chrome - 241008110744.jpg

キー取得後の画面になります。初回実行時はgenerateとなっているので、押下して取得します。
注意点はAccess Token and Secretの赤枠欄がRead WriteまたはRead Write and Direct Messageとなっている事を確認してください。
認証設定の節でも説明しましたが、ReadとなっているとXにポストできません。
なっていない場合はもう一度認証設定の節を確認して設定してください。
なお、設定後はキーの再生成が必要になります。

Githubリポジトリの作成

作成していない場合はGitHubリポジトリを新規作成してローカル環境にクローンします。

なおリポジトリ作成後にPersonal Access Tokensを設定してコミットできるようにしておきます。

権限内容についてですが、
ActionsWorkflowsはワークフローを作成するのでRead and writeとしてください。
またSecretsから環境変数を読み込むのでSecretsReadとしてください。

GitHubに環境変数を設定

後述するGitHubActionsのスクリプトからAPIキーを読みませるために環境変数を設定します。
GitHubリポジトリの管理画面を表示し、以下の画像を参考に設定してください。

  • TWITTER_ACCESS_TOKEN
  • TWITTER_ACCESS_TOKEN_SECRET
  • TWITTER_BEARER_TOKEN
  • TWITTER_CONSUMER_KEY
  • TWITTER_CONSUMER_SECRET

iScreen Shoter - Google Chrome - 241008023625.jpg

スクリプトファイルの作成

Github Acitonsで実行するスクリプトファイルを作成します。
今回はpythonで作成しtweetpyというX APIを使用して連携します。
作成したスクリプトをローカルリポジトリの直下に配置してください。

今回の仕様として、リポジトリ内にYYYY/MM/DD.mdという日報が存在し、
Githubプッシュ時にファイル名の日付が最新の日報をXにポストします。

tweet.py
import tweepy
import os
import glob
from datetime import datetime

# Twitter APIのキーとトークンを環境変数から取得
ck = os.environ['TWITTER_CONSUMER_KEY']
cs = os.environ['TWITTER_CONSUMER_SECRET']
bt = os.environ['TWITTER_BEARER_TOKEN']
at = os.environ['TWITTER_ACCESS_TOKEN']
ats = os.environ['TWITTER_ACCESS_TOKEN_SECRET']

# Twitter APIのクライアントを初期化
client = tweepy.Client(
    bearer_token=bt,
    consumer_key=ck,
    consumer_secret=cs,
    access_token=at,
    access_token_secret=ats
)

# 最新の.mdファイルを取得
def get_latest_markdown_file():
    # サブフォルダ内のすべての.mdファイルを再帰的に取得
    markdown_files = glob.glob('**/*.md', recursive=True)
    
    if not markdown_files:
        return None

    latest_file = None
    latest_date = None

    for file in markdown_files:
        # ディレクトリ名とファイル名から日付を取得
        # 例: 2024/09/20.md から "2024-09-20" を抽出
        path_parts = file.split('/')
        if len(path_parts) >= 3:
            date_str = f"{path_parts[-3]}-{path_parts[-2]}-{path_parts[-1][:-3]}"  # YYYY-MM-DD
            try:
                date = datetime.strptime(date_str, "%Y-%m-%d")
            except ValueError:
                continue  # 日付が無効な場合はスキップ

            # 最新の日付を更新
            if latest_date is None or date > latest_date:
                latest_date = date
                latest_file = file

    return latest_file

# ツイート内容を取得
latest_md_file = get_latest_markdown_file()

if latest_md_file:
    with open(latest_md_file, 'r', encoding='utf-8') as file:
        content = file.read()

    # ツイート内容をトリミング
    if len(content) > 264:
        content = content[:261] + '...'  # トリミングして「...」を追加

    # ハッシュタグを追加
    hashtags = "#今日の積み上げ"
    tweet_content = f"{content}\n\n{hashtags}"

    # ツイートを投稿
    try:
        client.create_tweet(text=tweet_content)
        print('Tweet sent successfully!')
    except tweepy.errors.Forbidden as e:
        print('Error posting tweet: Forbidden', e)
    except Exception as e:
        print('Error posting tweet:', e)
else:
    print('No markdown files found.')

ワークフロー定義の作成

Github Actionsで実行するワークフローファイルを作成します。
クローンしたローカルリポジトリ内に.github/workflowsディレクトリを作成して
.ymlファイルを作成してください。
今回は便宜上tweet.ymlとしておきます。

GitHubプッシュ時にGitHub Actionsのトリガーが起動するように設定しているので、
ワークフローファイルとスクリプトを配置するだけで実行されるようになります。

tweet.yml
# ワークフローの名称。
name: Create X Post

# トリガーの指定。GitHubにプッシュされた時に実行する
on: 
  push:
    branches:
      - main

# ワークフローの作成。pythonのバージョンは実行環境に応じて変更してください。
jobs:
  tweet:
    runs-on: ubuntu-latest
    environment: X_Automation
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      # X API(tweepy)を使用して連携を実施します
      - name: Install dependencies
        run: |
          pip install tweepy

      # 実行ファイルと環境変数の読み込み
      - name: Post article
        env:
          TWITTER_CONSUMER_KEY: ${{ secrets.TWITTER_CONSUMER_KEY }}
          TWITTER_CONSUMER_SECRET: ${{ secrets.TWITTER_CONSUMER_SECRET }}
          TWITTER_BEARER_TOKEN: ${{ secrets.TWITTER_BEARER_TOKEN }}
          TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
          TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
        run: python tweet.py

最終的な構成は以下になります。
iScreen Shoter - Cursor - 241008105804.jpg

Github Actionsのログを確認

問題無ければプッシュ時にポストされていると思います。
Xにポストされているか確認しましょう。

もしされていない場合はGitHubアクション内でエラーが発生していると思うので、
GitHubのリポジトリ管理画面よりActionsタブを押下してエラー内容を確認してください。

iScreen Shoter - Google Chrome - 241008112207.jpg

参考程度に筆者が沼ったのは以下でした。

  • 環境変数のキーと値に誤りがある
  • 認証設定でread and writeになっていない
  • 認証設定変更語にトークンの再取得をしていない

上記が正しく設定できていないと、
X ポスト時に権限エラーで403 Forbiddenが表示されていると思います。

iScreen Shoter - Google Chrome - 241008110229.jpg

おわりに

GitHub Actionsを利用してコミット内容をXにポストする方法を紹介させて頂きました。
非常に簡単で色々応用ができそうですね。
定期的に学習して更に便利な使い方を模索していきたいと思います。

4
3
0

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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?