Current section
Files
Jump to
Current section
Files
lib/notioner.ex
defmodule Notioner do
@moduledoc """
Notion API https://developers.notion.com/reference/intro
"""
alias Notioner.ReqClient
def all_projects(db_id \\ :runner_projects) do
Notioner.Database.query(db_id)
|> get_results()
|> Enum.map(fn m ->
page_id = get_in(m, ["id"])
title_content =
get_in(m, ["properties", "Project name", "title", Access.at(0), "text", "content"])
{title_content, page_id}
end)
# require "Project name" unique as title!
|> Map.new()
end
@doc """
Query tasks as notion-pages
"""
def query_tasks(task_name_part, opts \\ []) do
db_id = opts[:db_id] || :runner_tasks
page_size = opts[:page_size] || 10
req_body = %{
filter: %{
property: "Task name",
title: %{
contains: task_name_part
}
},
page_size: page_size
}
Notioner.Database.query(db_id, req_body)
|> get_results()
|> Enum.map(fn m ->
page_id = get_in(m, ["id"])
title_content =
get_in(m, ["properties", "Task name", "title", Access.at(0), "text", "content"])
{page_id, title_content}
end)
end
def set_task_projects(page_id, project_ids) when is_list(project_ids) do
page_id = Notioner.Page.get_page_id(page_id)
properties = %{
"Project" => %{
"relation" => project_ids |> Enum.map(fn id -> %{id: id} end)
}
}
req_patch!("/pages/#{page_id}", json: %{properties: properties})
end
@doc """
iex>
Notioner.set_task_project_names :test_task, ["Plan"]
"""
def set_task_project_names(page_id, project_names, projects \\ all_projects())
when is_list(project_names) and is_map(projects) do
project_ids = projects |> Map.take(project_names) |> Map.values()
set_task_projects(page_id, project_ids)
end
@doc """
todo
- how to find all parents?
"""
def get_parents(obj_id, type \\ :page)
def get_parents(page_id, :page) do
get_parent(%{"type" => "page_id", "page_id" => page_id})
end
def get_parents(db_id, :db) do
get_parent(%{"type" => "database_id", "database_id" => db_id})
end
def get_parent(%{"type" => "database_id", "database_id" => db_id}) do
Notioner.Database.get(db_id)
|> match_parent()
|> Map.fetch!("parent")
end
def get_parent(%{"type" => "page_id", "page_id" => page_id}) do
Notioner.Page.get(page_id)
|> match_parent()
|> Map.fetch!("parent")
end
# this is top case, the end!
def get_parent(%{"type" => "workspace", "workspace" => true}), do: nil
@doc """
Friendly handle not found
"""
def match_parent(%{
"code" => "object_not_found",
"message" => msg,
# "message" => "Could not find page with ID: 628fe830-b331-479b-98d1-d21c4b45a529. Make sure the relevant pages and databases are shared with your integration.",
"object" => "error",
# "request_id" => "6b64f59f-f3a6-421e-b5a4-9efaaeeb974b",
"status" => 404
}) do
raise "#{msg}, open page with link: https://www.notion.so/shareupme/<obj-id> and grant connection!"
end
def match_parent(obj), do: obj
## HTTP Request
def req_get!(path, opts \\ []),
do: ReqClient.get!(path, Keyword.merge(default_opts(), opts))
def req_post!(path, opts \\ []),
do: ReqClient.post!(path, Keyword.merge(default_opts(), opts))
def req_patch!(path, opts \\ []),
do: ReqClient.patch!(path, Keyword.merge(default_opts(), opts))
def get_results(resp) when is_map(resp) do
resp
|> Map.get("results", [])
end
def default_opts() do
Application.get_env(:notioner, :notion_req_options, [])
end
end