📒

Scrapboxの作成ページ一覧をSlackに送信するChrome拡張をつくった

2022/05/09に公開

https://zenn.dev/yuji/articles/f1bfd18364a0e2

GW明け直ぐに仕事モードに持ってけそうにないので、リハビリがてらに執筆しています。
今回初めてChrome拡張を作成しました。最近触り始めたLambdaの学習を兼ねています。

https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack

今回作成したChrome拡張について

チームでScrapboxを利用しているのですが、週次で作成したページのサマリを取りたいといった時など、自分が作ったページ一覧を取得したい時に使えるChrome拡張になっています。

主な仕様は、Scrapboxページ上で、Chrome拡張ボタンをクリックすると、Slackに直近自分が作成したページ一覧を送信してくれるChrome拡張になります。

▼アーキテクチャ図
architecture diagram

事前準備

Scrapbox APIについて

今回Slackに送信するデータは、自分が作成したScrapboxページを対象にしています。
以下のScrapbox APIを利用します。

プロジェクト内のページ情報

プロジェクトのページ一覧を取得します。作成日が新しいものが欲しいため、sortcreatedを指定しています。(全ページ数が多ければ、limitを指定した方がいいかもしれません。今回500がデフォで設定されるようになっています。)

  • /api/pages/:projectname?sort=created

https://scrapbox.io/scrapboxlab/api%2Fpages%2F:projectname

自分のuser情報

自分が作成したページのみ取得するために、フィルター条件となるユーザーIDを取得します。

  • /api/users/me

https://scrapbox.io/scrapboxlab/api%2Fusers%2Fme

SlackチャンネルにIncoming Webhookの導入

Slackに送信するために、Slackアプリを利用します。
送信先のチャンネルにIncoming Webhookを追加してWebhook URLを生成しておきます。

https://ajikeltd.slack.com/apps/A0F7XDUAZ--incoming-webhook-?tab=more_info

Lambda関数の作成

Slackへの送信はLambdaから実施します。

Lambdaのスクリプトも一応貼っておきます。気になる方だけご覧ください。
const HTTPS = require('https');

const sendSlack = (message, url) => {
  var options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    }
  };
  
  var req = HTTPS.request(url, options, (res) => {
    if (res.statusCode === 200) {
      console.log("OK:" + res.statusCode);
    } else {
      console.log("Status Error:" + res.statusCode);
    }
  });
  
  req.on('error', (e) => {
    console.error(e);
  });
  
  req.write(message);

  req.end();
};

/**
*   event.body.url : webhook url
*   event.body.page : ページ一覧
**/
exports.handler = (event, context, callback) => {
  const body = JSON.parse(event.body)
  const page = body.page
  const url = body.url
  let data = ''
  
  
  page.map(v => {
    data += `- <https://scrapbox.io/{プロジェクト名を入力してください}/${v.title}>\n`
  })
  var raw = JSON.stringify({
    "username": "Scrapbox_to_Slack",
    "text": data,
    "icon_emoji": ":postbox:"
  });

  sendSlack(raw, url);

  // CORS対応
  callback(null, {
    "statusCode": 200,
    headers: {
      "Access-Control-Allow-Headers" : "Content-Type",
      "Access-Control-Allow-Origin": "https://scrapbox.io",
      "Access-Control-Allow-Methods": "OPTIONS,POST,GET"
    },
    "body": JSON.stringify(raw)
  });
};

API Gatewayの作成

LambdaのトリガーとなるAPI Gatewayを作成します。Chrome拡張からAPIエンドポイントにリクエストしてLambdaを実行します。

Chrome拡張の作成

いよいよ本題です。
Chrome拡張を作成していきます。

サンプル用のフォーマットファイルが配布されていましたので、このファイルをベースに作成していきます。
https://developer.chrome.com/docs/extensions/mv3/getstarted/

ファイルの構成

構成と利用しているファイルの用途は以下のような感じです。

ファイル名 利用用途
background.js 常に事項される処理。拡張の実行条件処理を記述。
chrome-icon-144.png 拡張のアイコン
content.js 拡張が実行された時のメイン処理
manifest.json 設定ファイル
options.html 拡張機能のオプションページ(送信先URLや検索対象のページ数上限を設定させる)
options.js 拡張機能のオプションページ上の処理

Chrome拡張の設定 manifest.json

manifest.jsonファイルは、さまざまな設定を記述します。Chrome拡張の名前や説明、利用バージョンなどを記述します。利用するChrome拡張関数は事前にこのファイルで、宣言しておく必要があります。

https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack/blob/main/manifest.json

https://developer.chrome.com/docs/extensions/mv3/manifest/

Chrome拡張の設定ページの作成 options_page

Chrome拡張の設定ページとして、options.htmlを作成しました。
manifest.jsonoptions_pageプロパティに作成したoptions.htmlを設定することで、拡張設定オプションページとして拡張画面から開くことができます。

今回は、通知先のSlack Webhook url、Scrapboxのプロジェクト名と検索対象のページ数上限、Lambdaを実行するAPI Gatewayのエンドポイントを設定できるようにしました。
https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack/blob/main/options.html

ここで、設定した情報は、chrome.storageAPI経由で保存しておきます。
manifest.jsonpermissionsプロパティにstorageを設定して、保存用の処理を行うoptions.jsを用意します。
https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack/blob/main/options.js

Chrome拡張のメイン処理 content.js

Chrome拡張が実行された際の処理を記述しています。
content.jsファイルを用意して、Scrapbox APIでページ一覧を取得して、対象のユーザーIDでフィルターをしたページ一覧をAPI Gateway経由でPOSTします。

https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack/blob/main/content.js

Chrome拡張の発火条件

manifest.jsonには、backgroudプロパティというものがあり、実行に関わらず処理を行わせることができます。

こちらに拡張アイコンがクリックされた時に実行させる処理の呼び出しと、Scrapboxページ上でのみ拡張を実行できるようにしていきます。
manifest.jsonbackgroundプロパティに対象のbackgroud.jsファイルを設定して処理を記述していきます。
https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack/blob/main/background.js

https://developer.chrome.com/blog/mv3-actions/

上記の設定で、動作的には正しく動くようになりましたが、Scrapboxページ上でない時もアイコンの色がついたままでした、、なんでだろ、、。(background使っとるからかな、、)

さいごに

以上で、Scrapboxの作成ページをSlackに送信するChrome拡張が完成しました!

ScrapboxのUserScriptで今回の処理を実現できればよかったのですが、サードパティーAPIを実行できないようになっていたため、Chrome拡張でAPI Gateway経由でSlackAPIを実行させることで要件を実現させました。

今回作成したChrome拡張は、一部加工してGitHubに公開しておりますので、全ソースを確認したい方は是非ご覧ください。
https://github.com/mineyuji/Chrome-Extensions-Scrapbox-AWS-Slack

Discussion