Agent Skills: Result: "2bf9aec6-2125-80fa-b178-ff9f9872e0f9"

Use when user says 'create Notion task', 'update task status', 'find user', 'my tasks', 'append to Notion page', 'insert block after', 'extract table from Notion'. Tasks DB + block operations + table extraction.

UncategorizedID: tekliner/improvado-agentic-frameworks-and-skills/notion-tasks-operations

Install this agent skill to your local

pnpm dlx add-skill https://github.com/tekliner/improvado-agentic-frameworks-and-skills/tree/HEAD/skills/notion-tasks-operations

Skill Files

Browse the full folder contents for notion-tasks-operations.

Download Skill

Loading file tree…

skills/notion-tasks-operations/SKILL.md

Skill Metadata

Name
notion-tasks-operations
Description
"Use when user says 'create Notion task', 'update task status', 'find user', 'my tasks', 'append to Notion page', 'insert block after', 'extract table from Notion'. Tasks DB + block operations + table extraction."

Notion Tasks Operations = Tasks DB + Block Operations

SELF-HEALING SKILL: If error occurs or new pattern discovered → update skill, increment version, log in SKILL_RELEASE_LOG.md

Core Principle: Manage Improvado Notion tasks (create/query/update) and page blocks (append/insert) via NotionAgent CLI and Python client. Tasks DB only - not for reading arbitrary pages.

Notion Operations Architecture (Continuant - TD):

graph TD
    Skill[Notion Tasks Operations] --> Tasks[Tasks Database]
    Skill --> Blocks[Block Operations]
    Skill --> Users[User Management]

    Tasks --> Create[Create Task]
    Tasks --> Query[Query Tasks]
    Tasks --> Update[Update Status]

    Blocks --> Append[Append to End]
    Blocks --> After[Insert After Block]
    Blocks --> Mermaid[Mermaid Diagrams]

    Users --> Find[Find User]
    Users --> List[List Users]

Task & Block Workflow (Occurrent - LR):

graph LR
    A[User Request] --> B{Task or Block?}
    B -->|Task| C[NotionAgent CLI]
    B -->|Block| D[NotionClient API]

    C --> E[Execute CRUD]
    D --> F{Position?}

    F -->|End| G[append_to_page]
    F -->|After Block| H[append_blocks_after]

    E --> I[Return URL]
    G --> I
    H --> I

Ontological Rule: TD for system structure, LR for operation workflow Primary source: data_sources/notion/notion_client.py, data_sources/notion/notion_cli.py Original session: 2025-01-15 - v1.0.0 Initial Latest update: 2026-02-13 by Mikhail Molchanov - v1.5.0 Customer relation support Release log: See SKILL_RELEASE_LOG.md


CRITICAL: Customer Field (MANDATORY for task creation)

BEFORE calling create_task, you MUST follow this checklist:

  1. ASK the user: "Which customer is this task for?" — even if the title seems obvious
  2. Look up the customer in Customers DB using find_customer_by_name(name)
  3. Pass customer= parameter to create_task() with the exact name the user provided
  4. If the user says "no customer" / "internal task" → skip, but ALWAYS ask first

WHY this is mandatory: Missing Customer field breaks downstream analytics — call taxonomy linking, hierarchy management, and customer reporting all depend on this relation. This was a recurring problem reported by the team.

How it works under the hood:

  • Customer is a relation field in Tasks DB → Customers DB (43a432c058404db8b70aa8974aa984fc)
  • create_task(title="...", customer="T-Mobile") automatically looks up "T-Mobile" in Customers DB and sets the relation
  • Search is two-step: exact title match first, then contains fallback

Example flow:

User: "Create task: MDG Filter alerts by LOB"
Agent: "Which customer is this task for?"
User: "T-Mobile"
Agent: → create_task(title="MDG Filter alerts by LOB", customer="T-Mobile", ...)

When to Use

¶1 USE this skill:

  • Create/update/query Notion tasks (Tasks DB ID: 42bffb6bf5354b828750be69024d374e)
  • Find users, manage task hierarchies
  • Append blocks to pages (Mermaid, callouts, headings)
  • Insert blocks after specific block (using URL anchor)

¶2 DO NOT use:

  • Reading arbitrary Notion pages → use NotionClient.get_block_children() directly
  • Extracting content from documents → use data_sources/notion/notion_client.py

Block Operations (v1.2.0+)

¶1 Append to End:

from data_sources.notion.notion_client import NotionClient
client = NotionClient()
client.append_to_page(page_id, blocks)

¶2 Insert After Specific Block (CRITICAL):

Use after parameter in API. Get block_id from URL anchor:

URL: https://notion.so/page-id#2bf9aec6212580fab178ff9f9872e0f9
                                 └── anchor = block_id (32 chars)

Convert to API format:

anchor = "2bf9aec6212580fab178ff9f9872e0f9"
block_id = f"{anchor[:8]}-{anchor[8:12]}-{anchor[12:16]}-{anchor[16:20]}-{anchor[20:]}"
# Result: "2bf9aec6-2125-80fa-b178-ff9f9872e0f9"

Insert after block:

import requests, os

def append_blocks_after(page_id: str, after_block_id: str, blocks: list) -> dict:
    headers = {
        "Authorization": f"Bearer {os.getenv('NOTION_TOKEN')}",
        "Content-Type": "application/json",
        "Notion-Version": "2022-06-28"
    }
    url = f"https://api.notion.com/v1/blocks/{page_id}/children"
    data = {"children": blocks, "after": after_block_id}  # KEY: 'after' param
    response = requests.patch(url, headers=headers, json=data)
    response.raise_for_status()
    return response.json()

¶3 Mermaid Diagram Block:

block = {
    "type": "code",
    "code": {
        "language": "mermaid",
        "rich_text": [{"type": "text", "text": {"content": "graph LR\n    A-->B"}}],
        "caption": [{"type": "text", "text": {"content": "Pipeline Flow"}}]
    }
}

Notion defaults to Code view. User must toggle to Preview/Split manually.

¶4 Callout with Link:

block = {
    "type": "callout",
    "callout": {
        "rich_text": [
            {"type": "text", "text": {"content": "Source: "}},
            {"type": "text", "text": {"content": "GitHub", "link": {"url": "https://github.com/..."}}}
        ],
        "icon": {"type": "emoji", "emoji": "💻"},
        "color": "gray_background"
    }
}

Table Extraction (v1.4.0)

¶1 Fast CLI extraction:

python scripts/01_extract_table.py "https://notion.so/page#block_id"
python scripts/01_extract_table.py "https://notion.so/page#block_id" --format json
python scripts/01_extract_table.py "https://notion.so/page#block_id" --format csv --quiet

¶2 Formats: markdown (default), json, csv, raw

¶3 How it works:

  • Extracts page_id and block_id from URL
  • If anchor points to toggle/column → searches inside for table
  • Falls back to page-wide table search
  • Outputs clean formatted data

¶4 Python usage:

from data_sources.notion.notion_client import NotionClient

client = NotionClient()
rows = client.get_block_children(table_id)
for row in rows:
    cells = row.get('table_row', {}).get('cells', [])
    values = [''.join([t.get('plain_text', '') for t in cell]) for cell in cells]

Task Operations

¶1 Create Task (with Customer):

python -m data_sources.notion.notion_cli create-task "Title" --assignee daniel_kravtsov --priority High --customer "T-Mobile"
from data_sources.notion.notion_cli import NotionAgent
agent = NotionAgent()
task = agent.create_task(
    title="MDG Filter alerts by LOB",
    assignee="roman_vinogradov",
    status="In Progress",
    priority="High",
    customer="T-Mobile"  # ALWAYS set when task is customer-related
)

¶2 Find Customer by Name:

from data_sources.notion.agent_commands.task_commands import find_customer_by_name
customer_id = find_customer_by_name("T-Mobile")  # Returns page ID or None

¶3 Query Tasks:

tasks = agent.get_tasks(assignee="daniel_kravtsov", status="In Progress", days_back=7)

¶4 Update Status:

agent.update_task_status(page_id="abc123", new_status="Done")

¶5 Find User:

user_id = agent.get_user_id("daniel@improvado.io")  # Works with name, email, or UUID

Environment & Constants

NOTION_TOKEN="secret_..."           # Required
NOTION_YOUR_EMAIL="your@email.com"  # For auto-assignment

Tasks DB: 42bffb6bf5354b828750be69024d374e Customers DB: 43a432c058404db8b70aa8974aa984fc Daniel ID: NOTION_USER_ID Nataliia ID: NOTION_USER_ID_2


Common Patterns

¶1 Clickable Links: Use plain URL or markdown [text](url). No bold/emoji prefix.

¶2 Partial Updates: Don't replace entire description. Target specific block.

¶3 Session Tracking: Add comment with session ID:

client.add_comment_to_page(page_id, f"Session: {session_id}")

Tests

Run tests before/after changes:

python .claude/skills/notion-tasks-operations/tests/01_test_notion_operations.py

Covered:

  • Block ID extraction from URL anchors
  • append_blocks_after() with mocked API
  • Mermaid/Callout/Heading block creation

Related Files

  • data_sources/notion/notion_client.py - Core API client
  • data_sources/notion/notion_cli.py - NotionAgent CLI
  • data_sources/notion/markdown_to_blocks.py - MD → Notion blocks
  • data_sources/notion/agent_commands/task_commands.py - Task CRUD with customer support

SKILL EVOLUTION: Error or new capability? → Fix it, update SKILL_RELEASE_LOG.md, bump version.

Ground Truth: Session 2026-02-13 - v1.5.0 Customer relation support