LoginSignup
0
0

爆速BrainDump:GAS編

Posted at

はじめに

最近、評判の高いNotionを導入し、個人的な情報やタスクを管理し始めました。
移動時間にはXを使って技術情報をチェックしたり、週末にやりたいことを思いついたら、Notionのデータベースにメモを残しています。
しかし、スマートフォンからNotionのデータベースに情報を入力しようとすると、クリック回数が多く(特にURLを入力する際には、クリックが多くなってしまいます)、利便性に欠けると感じました。
そこで、爆速(できれば1クリックで完了するような)でデータベースにメモを残せるような仕組みを構築したので、3回に分けて紹介していきます。

  1. Notion / Notion API
  2. Google Apps Script ← 今回
  3. iPhone ショートカット

アーキテクチャ構成

アーキテクチャ図.png

実装

Google Apps Script(GAS)でAPIを公開し、そのAPIにリクエストすることでNotion Databaseにレコードを追加するための設定を行います。

要約

  • WebアプリとしてAPIを公開する
  • API内でレコードのデータを補完する
    • URLを渡された場合、リンク先のタイトルを取得する
    • 時間はNotion APIをコールするときの時間を自動で付与する

A. GASプロジェクトを作成

①任意の場所にGASプロジェクトを作成する
 ここでは「爆速BrainDump」フォルダを作成し、その中に作成した。

gasプロジェクト作成.png

②注意喚起のポップアップが出た場合は、「スクリプトを作成」を押下

gasプロジェクト作成_承認.png

③GASプロジェクトの名前を任意の名前に変更する
 ここでは「爆速BrainDumpスクリプト」とした。

GASプロジェクト名前変更前.png

GASプロジェクト名前変更後.png

B. コーディング

コード.gsファイルの中を以下のように書き換える
※最初に書かれているfuncion myFunction() { }は使用しないので削除してOK。
※コード量の削減のためにログ出力等は省略しています。

function doPost(e) {
   const record = createRecord(JSON.parse(e.postData.contents));
   send2Notion(record);

   const output = ContentService.createTextOutput(JSON.stringify({ result: 'OK' }));
   output.setMimeType(ContentService.MimeType.JSON);
   return output;
}

function createRecord(body) {
   const isUrl = (str) => {
       return (str.startsWith('https://') || str.startsWith('http://'));
   }

   let title = '';
   let url = null;

   if (isUrl(body.message)) {
       url = body.message;
       
       const html = UrlFetchApp.fetch(url).getContentText('UTF-8');
       const titleStartString = '<title>';
       const titleStartNum = html.indexOf(titleStartString) + titleStartString.length;
       const titleEndNum = html.indexOf('</title>');
       
       title = html.substring(titleStartNum, titleEndNum);
   } else {
       title = body.message;
   }
   
   const record = {
       title: title,
       url: url,
       date: Utilities.formatDate(new Date(), 'JST', 'yyyy-MM-dd')
   };
   
   return record;
}

function send2Notion(record) {
   const createHeader = () => {
       const notionVersion = PropertiesService.getScriptProperties().getProperty('NOTION_VERSION');
       const notionApiKey = PropertiesService.getScriptProperties().getProperty('NOTION_API_KEY');
       
       return {
           'Accept': 'application/json',
           'Authorization': `Bearer ${notionApiKey}`,
           'Notion-Version': `${notionVersion}`,
           'Content-Type': 'application/json'
       };
   }

   const notionDatabaseId = PropertiesService.getScriptProperties().getProperty('NOTION_DATABASE_ID');
   const url = 'https://api.notion.com/v1/pages';
   
   const payload = {
       'parent': { 'type': 'database_id', 'database_id': notionDatabaseId },
       'properties': {
           'Title': {
               'type': 'title',
               'title': [{ 'type': 'text', 'text': { 'content': record.title } }]
           },
           'URL': {
               'url': record.url
           },
           'Date': {
               'type': 'date',
               'date': { 'start': record.date }
           }
       }
   };
   const option = {
       'method': 'POST',
       'headers': createHeader(),
       'payload': JSON.stringify(payload),
       'muteHttpExceptions': true,
   };
   UrlFetchApp.fetch(url, option);
}

doPost()関数

Webアプリとしてデプロイした際、POSTメソッドでリクエストしたときにinvokeされる関数です。
POSTメソッドのリクエストボディは、e.postData.contentsで取得できます。

この関数では、主に以下の3つの処理をしています。

  1. createRecord()関数を使用して、Notionに保存するレコードを作成
  2. send2Notion()関数を使用して、1で作成したレコードをNotionに送信
  3. 正常終了のhtmlを作成して、クライアントへ返却

createRecord()関数

クライアントからのリクエストボディからNotionのデータベースに登録するレコードを作成する関数です。

この関数では、主に以下のつの処理をしています。

  1. messageプロパティの値に応じて以下の処理をする
    • URLの場合
      title: サイトにアクセスして取得したサイトのタイトル
      url: messageプロパティの値
    • URLでない場合
      title: messageプロパティの値
      url: null
  2. dateに現在の時刻を入れる

messageがURLでない場合、urlにはnullを設定しないとNotion APIでエラーになる

send2Notion()関数

Notion APIをコールして、Notionのデータベースにレコードを登録する関数です。
前回の記事で動作確認した際のNotion API仕様に則り、データをリクエストします。

C. スクリプトプロパティの設定

Bのソースコードの中でPropertiesService.getScriptProperties().getProperty('xxx');と記述している箇所があります。
これは、GASプロジェクトのスクリプトプロパティから値を取得しています。
スクリプトプロパティに入れることで、再デプロイせずにレコードを追加するデータベースを変更することができます。

①プロジェクトの設定を開く

スクリプトプロパティに追加.png

②スクリプトプロパティにプロパティと値を設定
 「スクリプトプロパティを追加」を押下し、
 ・NOTION_VERSION: 公式リファレンスに記載されている最新のVersion
 ・NOTION_API_KEY: インテグレーションのシークレット
 ・NOTION_DATABASE_ID: レコードを追加するデータベースのデータベースID

スクリプトプロパティを設定完了.png

D. デプロイ

ここまでで準備が完了したので、デプロイしてAPIを使用できるようにします。

①右上にある「デプロイ」ボタンから「新しいデプロイ」を押下

デプロイ開始.png

②デプロイ用の画面が表示されたら、「ウェブアプリ」を選択

デプロイ種類選択.png

③デプロイの詳細画面が開くので、アクセスできるユーザーを「全員」に設定して「デプロイ」ボタンを押下

デプロイ.png

デプロイ完了後、URLさえ知っていれば誰でもアクセスできるので、URLの取り扱いには充分に注意してください。

④「アクセスを承認」ボタンを押下
 UrlFetchApp.fetch()関数を使用するので、アクセスを承認する必要があります。

デプロイ承認.png

⑤爆速BrainDumpスクリプトを実行するGoogleアカウントを選択

スクリプトを実行するアカウントを選択.png

⑥全員に公開するので警告が表示されますが、承認を続けるので、「Advanced」を押下

安全じゃない確認.png

⑦「Go to 爆速BrainDumpスクリプト(unsafe)」を押下

安全じゃない警告を無理やり突破.png

⑧「Allow」を押下

GASスクリプトに許可を付与.png

⑨デプロイが完了したので、ウェブアプリのURLをコピーして、完了を押下

デプロイ完了.png

動作確認

GAS API仕様

URL

エンドポイント:WebアプリのURL
メソッド:POST

Body

{
    "message": "${message}" // ${message}: メモするデータ
}

テストデータをリクエストする

API仕様の各変数に以下の値を設定して、リクエストする。

URLをリクエストする場合

変数名
message 'https://qiita.com'

メモをリクエストする場合

変数名
message 'test'

リクエストする際に注意すること

GASのWebアプリのPOSTメソッドは、GCP側でGETメソッドにリダイレクトされます。
そのため、リクエストする際に少し注意が必要です。
ここでは、curlを使用する場合のリクエスト例を示します。

curl -d ${message} -L ${url}

結果

リクエストした内容でデータベースにレコードが登録されていることを確認する。

動作確認結果_GAS.png

参考

GASのWebアプリ仕様

curlでのGASのWebアプリでのPOSTの仕方

0
0
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
0
0