Chrome拡張機能 Notion Tweaks を作ったときの備忘録
概要
Notionをより便利に使うためのChrome拡張機能「Notion Tweaks」を作りました。この記事はその際の備忘録です。
↓公開先
↓紹介記事
Manifest V3
permissions
V2ではmanifest.json
のpermissions
にtabs
やURLを一緒に書いていましたが,V3では以下のように分けて書くことになりました.
{
...
"host_permissions": [
"https://script.google.com/",
"https://script.googleusercontent.com/",
"https://api.notion.com/"
],
"permissions": [
"tabs",
"storage"
],
...
}
このhost_permissions
の内容は,ユーザーがChrome拡張機能を追加するときに以下のように表示されます.ただし,「詳細」ボタンを押さないと対象サイトは表示されません.ユーザーに不安を与えたくない場合は,Web Store 申請時の説明欄に書いておくと良いと思います.
"https://script.googleusercontent.com/"
はGASを使うときにリダイレクトが行われるために書きました.
参考: Migrating to Manifest V3 - Chrome Developers
開発時の自動リロード
コードを変更して保存したときに自動リロードする部分については,以前Chrome拡張機能「Amazing Searcher」を作成したときのものをそのまま利用しました.
キーボードショートカットを追加する
"global": true
で,ブラウザにフォーカスが無い時でも有効になります.
{
...
"commands": {
"feature_name": {
"suggested_key": {
"default": "Ctrl+Shift+1"
},
"description": "hogehooogeeee",
"global": true
}
},
...
}
あとはchrome.commands.onCommand.addListener
に書くだけです.
chrome.commands.onCommand.addListener(function(command) {
if (command == "feature_name") {
console.log("Heke!");
}
});
参考:
Google Apps Scriptを実行する
Chrome拡張とGASを連携させる例(改) - Qiita を参考に実装しました.
デプロイのURLは「デプロイをテスト」の方,つまりhttps://script.google.com/macros/s/hoge/dev
のように末尾がdevになっているものでも実行できます.
chrome.storage.local
のラッパー
chrome.storage.local
を使うときに,JSONに直したりパースするのを何回も忘れたり,awaitを使いたかったため,書いてみました.TypeScript使い始めたばかりであるため,今後書き直すかもしれません.
await getStorage("hoge")
と書けばstorageから取得できるため楽でした.
export const getStorage = (key: string) => new Promise(resolve => {
chrome.storage.local.get(key, (data: any) => {
if (typeof data[key] === "undefined") {
resolve(null);
return;
}
resolve(JSON.parse(data[key]));
return;
});
});
interface storageType {
[key: string]: any;
}
export const setStorage = (key: string, value: any) => new Promise(resolve => {
const setObj: storageType = {[key]: JSON.stringify(value)}
chrome.storage.local.set(setObj, () => {
resolve(true);
});
});
export const clearStorage = () => new Promise(resolve => {
chrome.storage.local.clear(() => resolve(true));
});
参考: 非同期処理 — 仕事ですぐに使えるTypeScript ドキュメント
Chrome拡張機能でnpmのライブラリが読み込まれないトラブル
webpackの設定で,
module.exports = {
...
optimization: {
splitChunks: {
name: 'chunk',
chunks(chunk) {
return chunk.name !== 'background';
},
}
},
...
}
のようにchunk.js
としてバンドルしているのに,manifest.json
にchunk.js
を書くのを忘れていたことが原因でした.
以下のように,content_scripts
のjs
などでは複数のファイルが指定できます.
{
...
"content_scripts": [
{
"matches": ["<https://www.notion.so/*>"],
"css": ["content.css"],
"js": ["content.js", "chunk.js"]
}
],
...
}
VivaldiでのChrome拡張機能開発
以前はパッケージ化されていないChrome拡張機能をVivaldiに読み込ませてService Workerを使おうとすると, An unknown error occurred when fetching the script.
や Service worker registration failed
といったエラー出ていましたが,現在(4.3.2439.44以降)では解決しました.
この問題でVivaldiでの Chrome拡張機能の開発 や GitHubからcloneして自分でビルドした拡張機能を動かすこと を諦めていた方は,トライしてみてはどうでしょうか.
Notion API
integration
NotionのAPIで扱いたいページは,画面右上からintegrationを許可する必要があります.複数のページを扱っていると許可したつもりになってしまうので注意です(時間を溶かしました).
データベースへのアイテムの追加
Update databaseはデータベースそのもののタイトルやプロパティのUpdateです.
データベースにアイテムを追加するためにはCreate a pageを使います.
ドキュメントにも,
Creates a new page in the specified database or as a child of an existing page.
と書いてあるのに読み飛ばしてしまい,時間を溶かしちゃいました.
最後に
初めてReactやTypeScriptを使ってみましたが,公式ドキュメントがわかりやすくて使いやすかったです.また,オプションページについてはMUIとReact Hook Formを使ってすぐに作成することができたため,この記事で書くことはありません(ドキュメントもわかりやすかったです).
リンクのまとめです.
- Zennのスクラップに書いたメモ: Chrome拡張機能 notion-tweaks 作成日記
- Zennに書いた紹介編の記事: Notionをさらに便利にするChrome拡張機能 Notion Tweaks を作った
- GitHubのリポジトリ: eetann/notion-tweaks
- Chrome Web Storeの公開先: Notion Tweaks - Chrome ウェブストア
Discussion