マルチセレクトをあれこれする ~ イチ(以下)から学ぶNotionAPI×Google Apps Script【Day.4】
こんばんは、ねここです。
久々に数日コードを睨みすぎた影響か疲れ目がひどくて、昨日はごろごろしてました。
今日も復活はしてないのですが、やらない日が続くと惰性で本当に続けなくなるので、今日は無理やり復活です。
Day.3ではフィルタを設定して任意のアイテムを抽出するところまでやりました。
今日は実際に条件に合うアイテムのプロパティ更新をやってみたいと思います。
アイテムのプロパティを更新する流れ
最初はフィルタ条件に合致するアイテムをまとめて更新するのかなぁと漠然と思ってたのですが、Notionの構造上そういう感じではなかったです。
フィルタを設定し、条件に合致するアイテムを抽出する
(Day.3でやったやつ)抽出したアイテムのページIDをまとめる
(配列に格納しておくのがよさそう)更新対象のページを1ページずつ更新していく
このような感じでした。たしかにこのほうがきめ細かく更新掛けることはできそう。
1 はDay.3でやった内容そのままなので、編集しやすいようにフィルタ設定する箇所を動かしたりする程度。
2 は抽出したアイテムからIDをぶっこ抜くだけ。
なので、今回がんばるのは3の箇所になります。
プロパティを更新する方法
エンドポイントはページを指定する
methodは「PATCH」を指定する
どのプロパティをどう更新するのかをJSON形式でまとめて投げる
まとめるとこんな感じですね。
条件検索するときはデータベースに向けて依頼をしましたが、更新するときは、条件に合致しているページに対して更新依頼を掛けることになります。まぁ言われたらそれはそう。
そしてリクエストを投げる際のmethodは「PATCH」を指定します。
一般的にWebサイトを閲覧するときに使われるのはほとんど「GET」で、フォームなどを使って情報を送信するときに「POST」を使うぐらい。
「PATCH」の存在自体は知ってましたが、使う日が来るとは思いませんでした。
// headers情報はまとめた
const headers = {
"Content-type": "application/json",
"Authorization": "Bearer " + NOTION_TOKEN,
"Notion-Version": "2022-06-28",
};
// 指定のページのプロパティを更新する
function patchDB(pageid, content_data) {
url = ENDPOINT + "pages/" + pageid;
// インテグレーションさんにわたす申請書を作る
const OPTIONS = {
"method" : "PATCH",
"headers": headers,
"payload": JSON.stringify(content_data)
};
// インテグレーションさん、申請書を提出いたします。よろしくお願いします。
return UrlFetchApp.fetch(url, OPTIONS);
}
コードとしてまとめるとこんな感じですね。
条件に合致したページが複数ある場合はループを回して、ページごとにこの関数を呼び出すことになります。
(ちなみに前回までheaders情報はここに直接書いてましたが、検索するときと更新するときでそれぞれ指定することになったので、変数でまとめました)
実際にプロパティの更新をやってみる
相変わらずJSON形式の取り扱いが苦手なぼくですが、がんばって組みたいと思います。
APIから更新を掛ける可能性がありそうなプロパティは以下かなと考えています。
テキストや数値
チェックボックス
マルチセレクト
日付
このうちマルチセレクトと日付がたぶん少し難易度が高そうで、逆にこれを攻略できたらテキストや数値、チェックボックスは楽勝かなと思っています(油断)。
ということで、今回はマルチセレクトを更新してみようと思います。
まず「ジャンル」が未設定のアイテムをフィルタで抽出して、「fromAPI」というタグをセットしてみたいと思います。
// 更新対象の抽出するフィルタを設定する
filter = {
"filter": {
"property":"ジャンル",
"multi_select": {
"is_empty": true
}
}
};
抽出条件はこんな感じ。
「ジャンル」プロパティが空白かどうか(is_emptyがtrueか)で検索します。
結果が1件以上あれば、ひとつずつ処理をしていきます。
for(i=0; i<res_parse["results"].length; i++) {
id = res_parse["results"][i]["id"];
update = {
"properties": {
"ジャンル": {
"multi_select": "fromAPI"
}
}
};
patchDB(id, update);
}
1ページずつページIDを採取し、設定するタグをJSON形式で作成して、更新用の関数にそれぞれ渡すと、ページ更新が行われます。
無事に「これはゲームではない。」に[fromAPI]のタグが設置できました。
では次は、すでになにかタグが設定されているところに[fromAPI]を追加してみます。せっかくなので複数タグを設定しているFF14を変えてみましょうか。
// 更新対象の抽出するフィルタを設定する
filter = {
"filter": {
"property":"ジャンル",
"multi_select": {
"contains": "MMORPG"
}
}
};
res = getDBquery(filter);
res_parse = JSON.parse(res);
for(i=0; i<res_parse["results"].length; i++) {
id = res_parse["results"][i]["id"];
update = {
"properties": {
"ジャンル": {
"multi_select": "fromAPI"
}
}
};
patchDB(id, update);
}
[MMORPG]が設定されているアイテムを検索して、先ほどと同じようにタグを更新します。
🤔🤔🤔🤔🤔🤔🤔🤔
「追加する」じゃなくて「更新する」なのだから、そりゃそうです。
抽出したあと、タグ情報もちゃんと拾った上で、付加するタグをくっつけないとダメですね。
for(i=0; i<res_parse["results"].length; i++) {
id = res_parse["results"][i]["id"];
// 抽出データからタグを拾ってtags配列に押し込んでいく
tags = [];
for(j=0; j<res_parse["results"][i]["properties"]["ジャンル"]["multi_select"].length; j++) {
tags.push(res_parse["results"][i]["properties"]["ジャンル"]["multi_select"][j]["name"]);
}
// tags配列の後ろに[fromAPI]をくっつける
tags.push("fromAPI");
// タグの配列をJSON形式に書き換える
tags_strings = [];
for(j=0; j<tags.length; j++) {
tags_strings.push({"name": tags[j]});
}
// タグの更新部分をJSON形式でセットする
update = {
"properties": {
"ジャンル": {
"multi_select": tags_strings
}
}
};
// 更新処理をインテグレーションさんにお願いする
patchDB(id, update);
}
ということで、タグを追加できる形に書き換えました。
全部違う種類の閉じかっこな上に、変数 j すらも閉じかっこに見えて、とても見づらいコードになりましたw
無事、タグの後ろに付加することができました。
最後に、検索結果が複数になる「RPG」タグを検索して、後ろに[fromAPI]タグを付けてみます。
filter = {
"filter": {
"property":"ジャンル",
"multi_select": {
"contains": "RPG"
}
}
};
しっかりと複数個の処理も走りました。よかった。
最後に特定のタグを消す処理もやってみました(個人的には一番使うかもしれないので)。
[RPG]のタグをもつアイテムを抽出し、その[RPG]タグを消してみます。
for(i=0; i<res_parse["results"].length; i++) {
id = res_parse["results"][i]["id"];
tags = [];
for(j=0; j<res_parse["results"][i]["properties"]["ジャンル"]["multi_select"].length; j++) {
// ジャンルタグが[RPG]じゃなかったら配列に突っ込む([RPG]だったら何もしない)
if(res_parse["results"][i]["properties"]["ジャンル"]["multi_select"][j]["name"] != "RPG") {
tags.push(res_parse["results"][i]["properties"]["ジャンル"]["multi_select"][j]["name"]);
}
}
// tags.push("fromAPI"); // 今回はタグの付加はしない
タグを配列に入れる前にチェックし、消す対象の場合は配列に入れない、という処理を足しました。配列に入れないので更新したときにそのタグが消えている、という理屈ですね。
無事に狙ったタグを消すことができました。
これで、マルチセレクト周りはなんとかなりそうな気がします。
というところで、今日はここまで。
次は日付プロパティの操作をいろいろ調べてみようと思います。
たぶんこれがプロパティ操作周りで一番めんどくさい気がします。
今日のカバー画像
昨日からずっとこんな感じで目を休めてました。
ビタミンBを摂取しないとダメかしら。
NEXT