カレンダーデータのデータベースへの一括登録 (Notion API 編): Notion 解説(18)

はじめに

Notion API のパブリックベータが使えるようになりました。そしたら、以前作ったカレンダーデータのデータベースへの一括登録方法 (ics → Excel → Notion): Notion 解説(14) - hkob’s blogを改良することで、直接 ics から Notion に一括登録できます。ということで、早速作りました。

準備

Integrations の登録

Setting & Members の下の方にIntegrations が用意されています。開くとこんな画面になります。すでに私は登録しているので、「Input tasks」というのが出ています。

f:id:hkob:20210514170532p:plain
Integrations

Integration を登録するには、下にある「Develop your own integrations」のページからアクセスできます。

リンクに飛ぶとこんな感じになっています。先ほどの Input tasks が登録されています。

f:id:hkob:20210514170615p:plain
My integrations

登録するべき情報はタスク名、アイコンイメージとどの Notion に接続するかだけです。特に問題ないと思います。

f:id:hkob:20210514170712p:plain
Create a new integration

作成するとこんな画面が表示されます。「Internal Inregration Token」の Show をクリックするとかなり長いトークンが出てくるので、これをコピーして取っておきます。

f:id:hkob:20210514170821p:plain
Input tasks

Notion の Share の設定

実際に登録したいデータベースの Share を設定します。私の場合にはタスクというテーブルなので、それを開きます。Linked Database になっている「↗︎タスク」の部分をクリックすればよいです。

f:id:hkob:20210514170342p:plain
タスクデータベース

先ほど作成した Input tasks の Integration を Invite します。Invite するとこんな感じで表示されます。

f:id:hkob:20210514170933p:plain
Input tasks を Invite

さらに、Database の ID を取得します。上の画面の「Copy link」をクリックして適当なエディタに貼り付けます。リンク名のうち、https://www.notion.so/の後ろから始まり、?vまでにある16進数(0-9までの数字とa-fまでの文字で書かれた文字列)をコピーして取っておきます。

ics2notion.rb の作成

Rubist なので、ics2tsv.rb を下に ics2notion.rb というプログラムを作成します。properties の下の「タスク名」と「日付」の部分は自分のテーブルの属性名に読み替えてください。ics2tsv で print していた部分を API 呼び出しにしただけです。API は Notion API のサンプルからいただきました。少しハマったところというと、日付のところは何もしないと GMT になってしまったので、後ろに「+09:00」を足した部分くらいですね。アクセス制限は1秒あたり3アクセスくらいらしいんですが、念のため1秒に1件の登録にしています。

#! /usr/bin/env ruby

require "net/http"
require "uri"
require "json"
require "date"

MY_NOTION_TOKEN="この部分にIntegration Token を書きます。"
DATABASE_ID="この部分にDatabase ID を書きます"

def send_notion(title, datetime)
  uri = URI.parse("https://api.notion.com/v1/pages")
  request = Net::HTTP::Post.new(uri)
  request.content_type = "application/json"
  request["Authorization"] = "Bearer #{MY_NOTION_TOKEN}"
  request["Notion-Version"] = "2021-05-13"
  request.body = JSON.dump({
    "parent" => {
      "database_id" => "#{DATABASE_ID}"
    },
    "properties" => {
      "タスク名" => {
        "title" => [
          {
            "text" => {
              "content" => "#{title}"
            }
          }
        ]
      },
      "日付" => {
        "type" => "date",
        "date" => {
          "start" => "#{datetime}"
        }
      }
    }
  })

  # デバッグ用動いたら消す
  # p request.body

  response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
    http.request(request)
  end

  code = response.code
  print "#{title}\t#{datetime}...#{code}\n"
  unless code == "200"
    # エラーの時だけエラーを表示する
    print "Error!\n#{response.body}\n"
  end
  # API 制限のため、あまり早く実行しない(最大3access/1秒らしい)
  sleep 1
end

if ARGV.length == 0
  print "Usage: ics2notion ics-file"
  exit
else
  datetime = nil
  summary = nil
  summary_hash = Hash.new 0
  print "タスク名\t日付\n"
  open(ARGV.first, "rt") do |f|
    while line = f.gets
      case line
      when /^BEGIN:VEVENT.*/
        start = nil
        summary = nil
      when /^DTSTART.*(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})/
        datetime = "#{$1}-#{$2}-#{$3} #{$4}:#{$5}+09:00"
      when /^SUMMARY:(.*)/
        summary = $1
        summary_hash[$1] += 1
      when /^END:VEVENT/
        num = " #{summary_hash[summary]}"
        send_notion("#{summary}#{num == ' 1' ? '' : num}", datetime)
      end
    end
  end
end

実行例

サンプルで今日の16:40 に一つイベントを作成した ics を用意しました。「デバッグ表示あり」の部分にコメントを付ける前の結果です。動いているかどうか心配だったので、request データも表示されています。ちゃんと登録されているか見るために、ics2tsv.rb と同じタブ区切り表示は残しています。また、表示の後ろにレスポンスコードを表示しています。200 となっていれば成功で何も表示しませんが、それ以外の数字の時には response.body もエラー表示するようにしています。

./ics2notion.rb a.ics
タスク名        日付
"{\"parent\":{\"database_id\":\"2395e3ffb55e4a8abc1ba426243776e3\"},\"properties\":{\"タスク名\":{\"title\":[{\"text\":{\"content\":\"テストイベント\"}}]},\"日付\":{\"type\":\"date\",\"date\":{\"start\":\"2021-05-14 16:40+09:00\"}}}}"
テストイベント  2021-05-14 16:40+09:00...200

Notion 見てみるとちゃんと入っています。素晴らしいですね。

f:id:hkob:20210514173141p:plain
登録されたデータ

おわりに

API ができるといろいろと夢が広がりますね。もう少し何ができるかを考えていきます。


はてなブログに書いた Notion 記事一覧