Files
Brancheneinstufung2/import_competitors_to_notion.py
Floke e1d115e0ba feat(notion): Implement relational Competitive Radar import
- Added import_relational_radar.py for bidirectional database structure in Notion.
- Added refresh_references.py to populate analysis data with grounded facts via scraping.
- Updated documentation for Competitive Radar v2.0.
2026-01-11 11:57:43 +00:00

201 lines
6.8 KiB
Python

import json
import os
import requests
import sys
# Configuration
JSON_FILE = 'analysis_robo-planet.de.json'
TOKEN_FILE = 'notion_token.txt'
# Root Page ID from notion_integration.md
PARENT_PAGE_ID = "2e088f42-8544-8024-8289-deb383da3818"
DB_TITLE = "Competitive Radar 🎯"
def load_json_data(filepath):
try:
with open(filepath, 'r') as f:
return json.load(f)
except Exception as e:
print(f"Error loading JSON: {e}")
sys.exit(1)
def load_notion_token(filepath):
try:
with open(filepath, 'r') as f:
return f.read().strip()
except Exception as e:
print(f"Error loading token: {e}")
sys.exit(1)
def create_competitor_database(token, parent_page_id):
url = "https://api.notion.com/v1/databases"
headers = {
"Authorization": f"Bearer {token}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
payload = {
"parent": {"type": "page_id", "page_id": parent_page_id},
"title": [{"type": "text", "text": {"content": DB_TITLE}}],
"properties": {
"Competitor Name": {"title": {}},
"Website": {"url": {}},
"Target Industries": {"multi_select": {}},
"USPs / Differentiators": {"rich_text": {}},
"Silver Bullet": {"rich_text": {}},
"Landmines": {"rich_text": {}},
"Strengths vs Weaknesses": {"rich_text": {}},
"Portfolio": {"rich_text": {}},
"Known References": {"rich_text": {}}
}
}
print(f"Creating database '{DB_TITLE}'...")
response = requests.post(url, headers=headers, json=payload)
if response.status_code != 200:
print(f"Error creating database: {response.status_code}")
print(response.text)
sys.exit(1)
db_data = response.json()
print(f"Database created successfully! ID: {db_data['id']}")
return db_data['id']
def format_list_as_bullets(items):
"""Converts a python list of strings into a Notion rich_text text block with bullets."""
if not items:
return ""
text_content = ""
for item in items:
text_content += f"{item}\n"
return text_content.strip()
def get_competitor_data(data, comp_name):
"""Aggregates data from different sections of the JSON for a single competitor."""
# Init structure
comp_data = {
"name": comp_name,
"url": "",
"industries": [],
"differentiators": [],
"portfolio": [],
"silver_bullet": "",
"landmines": [],
"strengths_weaknesses": [],
"references": []
}
# 1. Basic Info & Portfolio (from 'analyses')
for analysis in data.get('analyses', []):
c = analysis.get('competitor', {})
if c.get('name') == comp_name:
comp_data['url'] = c.get('url', '')
comp_data['industries'] = analysis.get('target_industries', [])
comp_data['differentiators'] = analysis.get('differentiators', [])
# Format Portfolio
for prod in analysis.get('portfolio', []):
p_name = prod.get('product', '')
p_purpose = prod.get('purpose', '')
comp_data['portfolio'].append(f"{p_name}: {p_purpose}")
break
# 2. Battlecards
for card in data.get('battlecards', []):
if card.get('competitor_name') == comp_name:
comp_data['silver_bullet'] = card.get('silver_bullet', '')
comp_data['landmines'] = card.get('landmine_questions', [])
comp_data['strengths_weaknesses'] = card.get('strengths_vs_weaknesses', [])
break
# 3. References
for ref_entry in data.get('reference_analysis', []):
if ref_entry.get('competitor_name') == comp_name:
for ref in ref_entry.get('references', []):
r_name = ref.get('name', 'Unknown')
r_ind = ref.get('industry', '')
entry = r_name
if r_ind:
entry += f" ({r_ind})"
comp_data['references'].append(entry)
break
return comp_data
def add_competitor_entry(token, db_id, c_data):
url = "https://api.notion.com/v1/pages"
headers = {
"Authorization": f"Bearer {token}",
"Notion-Version": "2022-06-28",
"Content-Type": "application/json"
}
# Prepare properties
props = {
"Competitor Name": {"title": [{"text": {"content": c_data['name']}}]},
"USPs / Differentiators": {"rich_text": [{"text": {"content": format_list_as_bullets(c_data['differentiators'])}}]},
"Silver Bullet": {"rich_text": [{"text": {"content": c_data['silver_bullet']}}]},
"Landmines": {"rich_text": [{"text": {"content": format_list_as_bullets(c_data['landmines'])}}]},
"Strengths vs Weaknesses": {"rich_text": [{"text": {"content": format_list_as_bullets(c_data['strengths_weaknesses'])}}]},
"Portfolio": {"rich_text": [{"text": {"content": format_list_as_bullets(c_data['portfolio'])}}]},
"Known References": {"rich_text": [{"text": {"content": format_list_as_bullets(c_data['references'])}}]}
}
if c_data['url']:
props["Website"] = {"url": c_data['url']}
# Multi-select for industries
# Note: Notion options are auto-created, but we must ensure no commas or weird chars break it
ms_options = []
for ind in c_data['industries']:
# Simple cleanup
clean_ind = ind.replace(',', '')
ms_options.append({"name": clean_ind})
props["Target Industries"] = {"multi_select": ms_options}
payload = {
"parent": {"database_id": db_id},
"properties": props
}
try:
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
print(f" - Added: {c_data['name']}")
except requests.exceptions.HTTPError as e:
print(f" - Failed to add {c_data['name']}: {e}")
# print(response.text)
def main():
token = load_notion_token(TOKEN_FILE)
data = load_json_data(JSON_FILE)
# 1. Create DB
db_id = create_competitor_database(token, PARENT_PAGE_ID)
# 2. Collect List of Competitors
# We use the shortlist or candidates list to drive the iteration
competitor_list = data.get('competitors_shortlist', [])
if not competitor_list:
competitor_list = data.get('competitor_candidates', [])
print(f"Importing {len(competitor_list)} competitors...")
for comp in competitor_list:
c_name = comp.get('name')
if not c_name: continue
# Aggregate Data
c_data = get_competitor_data(data, c_name)
# Push to Notion
add_competitor_entry(token, db_id, c_data)
print("Import complete.")
if __name__ == "__main__":
main()