class NotionAPI::Core

the initial methods available to an instantiated Cloent object are defined

Attributes

active_user_header[R]
options[R]
token_v2[R]
type_whitelist[R]
clean_id[R]
cookies[R]
headers[R]

Public Class Methods

new(token_v2, active_user_header) click to toggle source
# File lib/notion_api/core.rb, line 19
def initialize(token_v2, active_user_header)
  @@token_v2 = token_v2
  @@active_user_header = active_user_header
end

Public Instance Methods

children(url_or_id = @id) click to toggle source
# File lib/notion_api/core.rb, line 45
def children(url_or_id = @id)
  # ! retrieve the children of a block. If the block has no children, return []. If it does, return the instantiated class objects associated with each child.
  # ! url_or_id -> the block ID or URL : ``str``

  children_ids = children_ids(url_or_id)
  if children_ids.empty?
    []
  else
    children_class_instances = []
    children_ids.each { |child| children_class_instances.push(get(child)) }
    children_class_instances
  end
end
children_ids(url_or_id = @id) click to toggle source
# File lib/notion_api/core.rb, line 59
def children_ids(url_or_id = @id)
  # ! retrieve the children IDs of a block.
  # ! url_or_id -> the block ID or URL : ``str``
  clean_id = extract_id(url_or_id)
  request_body = {
    pageId: clean_id,
    chunkNumber: 0,
    limit: 100,
    verticalColumns: false,
  }
  jsonified_record_response = get_all_block_info(request_body)

  # if no content, returns empty list
  jsonified_record_response["block"][clean_id]["value"]["content"] || []
end
extract_id(url_or_id) click to toggle source
# File lib/notion_api/core.rb, line 75
def extract_id(url_or_id)
  # ! parse and clean the URL or ID object provided.
  # ! url_or_id -> the block ID or URL : ``str``
  http_or_https = url_or_id.match(/^(http|https)/) # true if http or https in url_or_id...
  collection_view_match = url_or_id.match(/(\?v=)/)

  if (url_or_id.length == 36) && ((url_or_id.split("-").length == 5) && !http_or_https)
    # passes if url_or_id is perfectly formatted already...
    url_or_id
  elsif (http_or_https && (url_or_id.split("-").last.length == 32)) || (!http_or_https && (url_or_id.length == 32)) || (collection_view_match)
    # passes if either:
    # 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
    # 2. a URL is not passed and the ID length is 32 [aka unformatted]
    pattern = [8, 13, 18, 23]
    if collection_view_match
      id_without_view = url_or_id.split("?")[0]
      clean_id = id_without_view.split("/").last
      pattern.each { |index| clean_id.insert(index, "-") }
      clean_id
    else
      id = url_or_id.split("-").last
      pattern.each { |index| id.insert(index, "-") }
      id
    end
  else
    raise ArgumentError, "Expected a Notion page URL or a page ID. Please consult the documentation for further information."
  end
end
get_page(url_or_id) click to toggle source
# File lib/notion_api/core.rb, line 24
def get_page(url_or_id)
  # ! retrieve a Notion Page Block and return its instantiated class object.
  # ! url_or_id -> the block ID or URL : ``str``
  clean_id = extract_id(url_or_id)

  request_body = {
    pageId: clean_id,
    chunkNumber: 0,
    limit: 100,
    verticalColumns: false,
  }
  jsonified_record_response = get_all_block_info(request_body)

  block_type = extract_type(clean_id, jsonified_record_response)
  block_parent_id = extract_parent_id(clean_id, jsonified_record_response)

  raise ArgumentError, "the URL or ID passed to the get_page method must be that of a Page Block." if !["collection_view_page", "page"].include?(block_type)

  get_instantiated_instance_for(block_type, clean_id, block_parent_id, jsonified_record_response)
end

Private Instance Methods

extract_collection_data(collection_id, view_id) click to toggle source
# File lib/notion_api/core.rb, line 289
def extract_collection_data(collection_id, view_id)
  # ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
  # ! collection_id -> the collection ID : ``str``
  # ! view_id -> the view ID : ``str``
  cookies = Core.options["cookies"]
  headers = Core.options["headers"]

  query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, "")

  request_url = URLS[:GET_COLLECTION]
  response = HTTParty.post(
    request_url,
    body: query_collection_hash.to_json,
    cookies: cookies,
    headers: headers,
  )
  response["recordMap"]
end
extract_collection_id(clean_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 226
def extract_collection_id(clean_id, jsonified_record_response)
  # ! extract the collection ID
  # ! clean_id -> the block ID or URL cleaned : ``str``
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
  jsonified_record_response["block"][clean_id]["value"]["collection_id"]
end
extract_collection_schema(collection_id, view_id, response = {}) click to toggle source
if (url_or_id.length == 36) && ((url_or_id.split("-").length == 5) && !http_or_https)
  # passes if url_or_id is perfectly formatted already...
  url_or_id
elsif (http_or_https && (url_or_id.split("-").last.length == 32)) || (!http_or_https && (url_or_id.length == 32)) || (collection_view_match)
  # passes if either:
  # 1. a URL is passed as url_or_id and the ID at the end is 32 characters long or
  # 2. a URL is not passed and the ID length is 32 [aka unformatted]
  pattern = [8, 13, 18, 23]
  if collection_view_match
    id_without_view = url_or_id.split("?")[0]
    clean_id = id_without_view.split("/").last
    pattern.each { |index| clean_id.insert(index, "-") }
    clean_id
  else
    id = url_or_id.split("-").last
    pattern.each { |index| id.insert(index, "-") }
    id
  end
else
  raise ArgumentError, "Expected a Notion page URL or a page ID. Please consult the documentation for further information."
end

end

# File lib/notion_api/core.rb, line 266
def extract_collection_schema(collection_id, view_id, response = {})
  # ! retrieve the collection scehma. Useful for 'building' the backbone for a table.
  # ! collection_id -> the collection ID : ``str``
  # ! view_id -> the view ID : ``str``
  cookies = Core.options["cookies"]
  headers = Core.options["headers"]

  if response.empty?
    query_collection_hash = Utils::CollectionViewComponents.query_collection(collection_id, view_id, "")

    request_url = URLS[:GET_COLLECTION]
    response = HTTParty.post(
      request_url,
      body: query_collection_hash.to_json,
      cookies: cookies,
      headers: headers,
    )
    response["recordMap"]["collection"][collection_id]["value"]["schema"]
  else
    response["collection"][collection_id]["value"]["schema"]
  end
end
extract_collection_title(_clean_id, collection_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 199
def extract_collection_title(_clean_id, collection_id, jsonified_record_response)
  # ! extract title from core JSON Notion response object.
  # ! clean_id -> the cleaned block ID: ``str``
  # ! collection_id -> the collection ID: ``str``
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
  jsonified_record_response["collection"][collection_id]["value"]["name"].flatten.join if jsonified_record_response["collection"] and jsonified_record_response["collection"][collection_id]["value"]["name"]
end
extract_collection_view_page_information(page_meta = {}) click to toggle source
# File lib/notion_api/core.rb, line 320
def extract_collection_view_page_information(page_meta = {})
  # ! helper method for extracting information about a Collection View page block
  # ! page_meta -> hash containing data points useful for the extraction of a page blocks information.
  # !           This should include clean_id, jsonified_record_response, and parent_id
  clean_id = page_meta.fetch(:clean_id)
  jsonified_record_response = page_meta.fetch(:jsonified_record_response)
  block_parent_id = page_meta.fetch(:parent_id)

  collection_id = extract_collection_id(clean_id, jsonified_record_response)
  block_title = extract_collection_title(clean_id, collection_id, jsonified_record_response)
  view_id = extract_view_ids(clean_id, jsonified_record_response)[0]
  schema = extract_collection_schema(collection_id, view_id, jsonified_record_response)
  column_names = NotionAPI::CollectionView.extract_collection_view_column_names(schema)

  collection_view_page = CollectionViewPage.new(clean_id, block_title, block_parent_id, collection_id, view_id)
  collection_view_page.instance_variable_set(:@column_names, column_names)
  CollectionView.class_eval { attr_reader :column_names }
  collection_view_page
end
extract_page_information(page_meta = {}) click to toggle source
# File lib/notion_api/core.rb, line 308
def extract_page_information(page_meta = {})
  # ! helper method for extracting information about a page block
  # ! page_meta -> hash containing data points useful for the extraction of a page blocks information.
  # !           This should include clean_id, jsonified_record_response, and parent_id
  clean_id = page_meta.fetch(:clean_id)
  jsonified_record_response = page_meta.fetch(:jsonified_record_response)
  block_parent_id = page_meta.fetch(:parent_id)

  block_title = extract_title(clean_id, jsonified_record_response)
  PageBlock.new(clean_id, block_title, block_parent_id)
end
extract_parent_id(clean_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 219
def extract_parent_id(clean_id, jsonified_record_response)
  # ! extract parent ID from core JSON response object.
  # ! clean_id -> the block ID or URL cleaned : ``str``
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
  jsonified_record_response.empty? || jsonified_record_response["block"].empty? ? {} : jsonified_record_response["block"][clean_id]["value"]["parent_id"]
end
extract_title(clean_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 184
def extract_title(clean_id, jsonified_record_response)
  # ! extract title from core JSON Notion response object.
  # ! clean_id -> the cleaned block ID: ``str``
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
  filter_nil_blocks = filter_nil_blocks(jsonified_record_response)
  if filter_nil_blocks.nil? || filter_nil_blocks[clean_id].nil? || filter_nil_blocks[clean_id]["value"]["properties"].nil?
    nil
  else
    # titles for images are called source, while titles for text-based blocks are called title, so lets dynamically grab it
    # https://stackoverflow.com/questions/23765996/get-all-keys-from-ruby-hash/23766007
    title_value = filter_nil_blocks[clean_id]["value"]["properties"].keys[0]
    Core.type_whitelist.include?(filter_nil_blocks[clean_id]["value"]["type"]) ? nil : jsonified_record_response["block"][clean_id]["value"]["properties"][title_value].flatten[0]
  end
end
extract_type(clean_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 207
def extract_type(clean_id, jsonified_record_response)
  # ! extract type from core JSON response object.
  # ! clean_id -> the block ID or URL cleaned : ``str``
  # ! jsonified_record_response -> parsed JSON representation of a notion response object : ``Json``
  filter_nil_blocks = filter_nil_blocks(jsonified_record_response)
  if filter_nil_blocks.nil?
    nil
  else
    filter_nil_blocks[clean_id]["value"]["type"]
  end
end
extract_view_ids(clean_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 233
def extract_view_ids(clean_id, jsonified_record_response)
  jsonified_record_response["block"][clean_id]["value"]["view_ids"] || []
end
filter_nil_blocks(jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 178
def filter_nil_blocks(jsonified_record_response)
  # ! removes any blocks that are empty [i.e. have no title / content]
  # ! jsonified_record_responses -> parsed JSON representation of a notion response object : ``Json``
  jsonified_record_response.empty? || jsonified_record_response["block"].empty? ? nil : jsonified_record_response["block"]
end
get_all_block_info(body, i = 0) click to toggle source
# File lib/notion_api/core.rb, line 147
def get_all_block_info(body, i = 0)
  # ! retrieves all info pertaining to a block Id.
  # ! clean_id -> the block ID or URL cleaned : ``str``
  Core.options["cookies"][:token_v2] = @@token_v2
  Core.options["headers"]["x-notion-active-user-header"] = @@active_user_header
  cookies = Core.options["cookies"]
  headers = Core.options["headers"]
  request_url = URLS[:GET_BLOCK]

  response = HTTParty.post(
    request_url,
    body: body.to_json,
    cookies: cookies,
    headers: headers,
  )

  jsonified_record_response = JSON.parse(response.body)["recordMap"]
  response_invalid = (!jsonified_record_response || jsonified_record_response.empty? || jsonified_record_response["block"].empty?)

  if i < 10 && response_invalid
    i = i + 1
    return get_all_block_info(body, i)
  else
    if i == 10 && response_invalid
      raise InvalidClientInstantiationError, "Attempted to retrieve block 10 times and received an empty response each time. Please make sure you have a valid token_v2 value set. If you do, then try setting the 'active_user_header' variable as well."
    else
      return jsonified_record_response
    end
  end
end
get_block_props_and_format(clean_id, block_title) click to toggle source
# File lib/notion_api/core.rb, line 130
def get_block_props_and_format(clean_id, block_title)
  request_body = {
    pageId: clean_id,
    chunkNumber: 0,
    limit: 100,
    verticalColumns: false,
  }
  jsonified_record_response = get_all_block_info(request_body)

  properties = jsonified_record_response["block"][clean_id]["value"]["properties"]
  formats = jsonified_record_response["block"][clean_id]["value"]["format"]
  return {
           :properties => properties,
           :format => formats,
         }
end
get_instantiated_instance_for(block_type, clean_id, parent_id, jsonified_record_response) click to toggle source
# File lib/notion_api/core.rb, line 340
def get_instantiated_instance_for(block_type, clean_id, parent_id, jsonified_record_response)
  case block_type
  when "page" then extract_page_information(clean_id: clean_id, parent_id: parent_id, jsonified_record_response: jsonified_record_response)
  when "collection_view_page" then extract_collection_view_page_information(clean_id: clean_id, parent_id: parent_id, jsonified_record_response: jsonified_record_response)
  end
end
get_last_page_block_id(url_or_id) click to toggle source
# File lib/notion_api/core.rb, line 124
def get_last_page_block_id(url_or_id)
  # ! retrieve and return the last child ID of a block.
  # ! url_or_id -> the block ID or URL : ``str``
  children_ids(url_or_id).empty? ? [] : children_ids(url_or_id)[-1]
end
get_notion_id(body) click to toggle source
# File lib/notion_api/core.rb, line 106
def get_notion_id(body)
  # ! retrieves a users ID from the headers of a Notion response object.
  # ! body -> the body to send in the request : ``Hash``
  Core.options["cookies"][:token_v2] = @@token_v2
  Core.options["headers"]["x-notion-active-user-header"] = @@active_user_header
  cookies = Core.options["cookies"]
  headers = Core.options["headers"]
  request_url = URLS[:GET_BLOCK]

  response = HTTParty.post(
    request_url,
    body: body.to_json,
    cookies: cookies,
    headers: headers,
  )
  response.headers["x-notion-user-id"]
end