6
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

フォローしているQiitaユーザが作成した記事を1日1回、スラックに通知してみた ~AWS100本ノック~ 13/100

Posted at

はじめに

Qiitaにはユーザのフォロー機能がありますが、フォローしている人が投稿した記事を確認するには、フォロー中のユーザタブで記事を一覧表示して、当日の記事を確認するしか現状なさそうです :cry:

まぁ、それでもいいっちゃいいんですが、せっかくなら日常で使っているコミュニケーションツールに通知してくれた方が良いなーと思い、自動で通知する機能を作ってみました!

スクリーンショット 2024-11-05 153409.png

試してみる

では、さっそく試してみます。
Qiita APIを利用して情報を取得し、Slackに通知します。
※公式のQiita APIリファレンスはこちら

全体像としては以下になります。
フォローしているQiitaユーザの投稿をスラックに通知.drawio.png

Slackの設定

まず、WebhookURL発行のためにSlack Appを作成します。

Slack Appでオリジナルのアプリを作ることで、作業の効率化などが行えます

https://api.slack.com/apps にアクセスし、Create New Appをクリックします。
1.png

From scratchをクリックします。
2.png

アプリの名前を入力し、スラックのワークスペースを選択し、Create AppをクリックすればSlack Appが作られます。簡単ですね :smile:
3.png

次に、Webhookの設定です。
デフォルトだと、WebhookはOffになっているので、Onにします。
4.png

Add New Webhook to Workspaceをクリックするとアクセス許可が求められるので、許可するをクリックします。
5.png

6.png

すると、Webhook URLが払い出されます。こちらをLambdaで利用します。
7.png

ついでに、Basic InformationメニューのDisplay InformationでSlackにメッセージを送る際のアイコンを設定しちゃいましょう :smiley:
Qiitaのキャラクターにしました!
8.png

Lambda関数の作成

次にLambda関数を作成します。
Lambdaって何ですか?って思った方は、こちらの記事で説明していますので、もしよければ見てください!

関数名を入力し、ランタイムを選択して関数の作成をクリックすると、関数が作られます。
※今回はNode.js 20.xのサンプルコードになります

9.png

環境変数に自身のQiitaのuserIdと、先ほどSlackで払い出したWebhookUrlを設定します。

10.png

Lambda関数に以下のコードを記載します。
とりあえず試せればいいやの精神なのでコードの書き方がよくない、とかはご了承ください :bow:

やっていることとしては、

  • 自身のフォローユーザを100件取得 ※100人以上いる場合は、修正が必要です
  • 取得したユーザの投稿記事を、投稿日時の降順で5件ずつ取得 ※1日に5件以上投稿する人はいないはず...
  • 取得した投稿の投稿日時が当日の場合は、WebhookURLに記事のURLなどを送信
index.js
export const handler = async (event) => {
  const now = new Date();
  const today = now.toISOString().split('T')[0];
  const userId = process.env.userId;

  const followedUsers = await fetchfollowedUsers(userId);

  for(const user of followedUsers) {
    const items = await fetchItems(user.id);
    for(const item of items) {
      const createdAt = new Date(items[0].created_at);
      const createdDate = createdAt.toISOString().split('T')[0];
      
      if (createdDate == today) {
        console.log(item);
        await sendItemToSlack(user, item);
      }
    }
  };
};

async function fetchfollowedUsers(userId) {
  const perPage = 100;
  const ENDPOINT = `https://qiita.com/api/v2/users/${userId}/followees?per_page=${perPage}`;
  const REQUEST_TIMEOUT_MS = 5000;

  try {
    const res = await fetch(ENDPOINT, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
    });
    return res.json();
  }
  catch (e) {
      console.error(e);
      return 500;
  }
}

async function fetchItems(userId) {
  const perPage = 1;
  const ENDPOINT = `https://qiita.com/api/v2/users/${userId}/items?per_page=${perPage}`;
  const REQUEST_TIMEOUT_MS = 5000;

  try {
    const res = await fetch(ENDPOINT, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
      signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
    });
    return res.json();
  }
  catch (e) {
      console.error(e);
      return 500;
  }
}


async function sendItemToSlack(user, item) {
  const webhookUrl = process.env.webhookUrl;  
  const slackResponse = await fetch(webhookUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
          text: `${user.id}さんが本日、以下の記事を投稿しました :smiley:  \n ${item.title} \n ${item.url}`
      })
  });
}

EventBridge Schedulerの作成

最後に、Lambdaを定期的に実行するためのEventBridge Schedulerを作成します。
EventBridge Schedulerって何ですか?って思った方は、こちらの記事で説明していますので、もしよければ見てください!

スケジュール名を入力します。
頻度定期的なスケジュールにして、cron式を40 16 * * ? *にします。
これで毎日16:40にLambdaを実行するようになります。
11.png
12.png

ターゲットLambcaInvokeを選択し、先ほど作成したLambda関数を選択します。
後はデフォルト値で設定していけば、作成出来ます。
13.png

実行してみる

では、最後に実行結果を確認してみましょう。時間になるとEventBridge SchedulerがLambda関数を実行し、当日に投稿された記事をSlackにメッセージ送信してくれるはずです!
👇当日の記事が2件あった場合、こんな感じになります

15.png

もっとこうしたらよさそう

今回は1日1回の頻度で、Lambda関数を実行し、Qiita APIから当日に投稿された記事を取得して、スラックに通知しました。
もっとリアルタイムに近い形で取得したいなら、Lambdaを10分に1回などにしたりするのが良さそうです!

実行頻度を上げる場合は、APIドキュメントにある通り認証しているユーザでないと1時間に60回までしかリクエスト出来ないようです。
必要に応じてアクセスキーを発行して利用しましょう!

利用制限
認証している状態ではユーザーごとに1時間に1000回まで、認証していない状態ではIPアドレスごとに1時間に60回までリクエストを受け付けます。

おわりに

とりあえず、ぱっと思いついた方法でフォローしたユーザの当日投稿した記事をスラックに通知する仕組みを作ってみました :smile:
もっといい方法あるなどありましたら、コメント頂けると幸いです :bow:

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?