[2ff88f42] Finalize SuperOffice Connector: Centralized Config, Added Position/Role Mapping Logic, and Discovery Tools
This commit is contained in:
@@ -1,89 +1,82 @@
|
||||
# connector-superoffice/discover_fields.py (Standalone & Robust)
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
from dotenv import load_dotenv
|
||||
from superoffice_client import SuperOfficeClient
|
||||
import logging
|
||||
|
||||
# Load environment variables
|
||||
load_dotenv(override=True)
|
||||
# Setup Logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger("discovery")
|
||||
|
||||
# Configuration
|
||||
SO_ENV = os.getenv("SO_ENVIRONMENT", "sod") # sod, stage, online
|
||||
SO_CLIENT_ID = os.getenv("SO_CLIENT_ID") or os.getenv("SO_SOD")
|
||||
SO_CLIENT_SECRET = os.getenv("SO_CLIENT_SECRET")
|
||||
# SO_REDIRECT_URI often required for validation even in refresh flow
|
||||
SO_REDIRECT_URI = os.getenv("SO_REDIRECT_URI", "http://localhost")
|
||||
SO_REFRESH_TOKEN = os.getenv("SO_REFRESH_TOKEN")
|
||||
def discover():
|
||||
print("🔍 Starting SuperOffice Discovery Tool...")
|
||||
|
||||
client = SuperOfficeClient()
|
||||
if not client.access_token:
|
||||
print("❌ Auth failed. Check .env")
|
||||
return
|
||||
|
||||
def get_access_token():
|
||||
"""Refreshes the access token using the refresh token."""
|
||||
url = f"https://{SO_ENV}.superoffice.com/login/common/oauth/tokens"
|
||||
data = {
|
||||
"grant_type": "refresh_token",
|
||||
"client_id": SO_CLIENT_ID,
|
||||
"client_secret": SO_CLIENT_SECRET,
|
||||
"refresh_token": SO_REFRESH_TOKEN,
|
||||
"redirect_uri": SO_REDIRECT_URI
|
||||
}
|
||||
# 1. Discover UDFs (User Defined Fields)
|
||||
print("\n--- 1. User Defined Fields (UDFs) ---")
|
||||
|
||||
print(f"DEBUG: Refreshing token at {url} for Client ID {SO_CLIENT_ID[:5]}...")
|
||||
|
||||
response = requests.post(url, data=data)
|
||||
if response.status_code == 200:
|
||||
print("✅ Access Token refreshed.")
|
||||
return response.json().get("access_token")
|
||||
else:
|
||||
print(f"❌ Error getting token: {response.text}")
|
||||
return None
|
||||
|
||||
def discover_udfs(base_url, token, entity="Contact"):
|
||||
"""
|
||||
Fetches the UDF layout for a specific entity.
|
||||
entity: 'Contact' (Firma) or 'Person'
|
||||
"""
|
||||
endpoint = "Contact" if entity == "Contact" else "Person"
|
||||
url = f"{base_url}/api/v1/{endpoint}?$top=1&$select=userDefinedFields"
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Accept": "application/json"
|
||||
}
|
||||
|
||||
print(f"\n--- DISCOVERING UDFS FOR: {entity} ---")
|
||||
# Contact UDFs
|
||||
try:
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data['value']:
|
||||
item = data['value'][0]
|
||||
udfs = item.get('userDefinedFields', {})
|
||||
|
||||
print(f"Found {len(udfs)} UDFs on this record.")
|
||||
|
||||
# Filter logic: Show interesting fields
|
||||
relevant_udfs = {k: v for k, v in udfs.items() if "marketing" in k.lower() or "robotic" in k.lower() or "challenge" in k.lower() or "ai" in k.lower()}
|
||||
|
||||
if relevant_udfs:
|
||||
print("✅ FOUND RELEVANT FIELDS (ProgId : Value):")
|
||||
print(json.dumps(relevant_udfs, indent=2))
|
||||
else:
|
||||
print("⚠️ No fields matching 'marketing/robotic/ai' found.")
|
||||
print("First 5 UDFs for context:")
|
||||
print(json.dumps(list(udfs.keys())[:5], indent=2))
|
||||
print("Fetching a sample Contact to inspect UDFs...")
|
||||
contacts = client.search("Contact?$top=1")
|
||||
if contacts:
|
||||
# Inspect keys of first result
|
||||
first_contact = contacts[0]
|
||||
# Try to find ID
|
||||
c_id = first_contact.get('ContactId') or first_contact.get('PrimaryKey')
|
||||
|
||||
if c_id:
|
||||
c = client.get_contact(c_id)
|
||||
udfs = c.get("UserDefinedFields", {})
|
||||
print(f"Found {len(udfs)} UDFs on Contact {c_id}:")
|
||||
for k, v in udfs.items():
|
||||
print(f" - Key (ProgId): {k} | Value: {v}")
|
||||
else:
|
||||
print("No records found to inspect.")
|
||||
print(f"⚠️ Could not find ID in search result: {first_contact.keys()}")
|
||||
else:
|
||||
print(f"Error {response.status_code}: {response.text}")
|
||||
print("⚠️ No contacts found. Cannot inspect Contact UDFs.")
|
||||
|
||||
print("\nFetching a sample Person to inspect UDFs...")
|
||||
persons = client.search("Person?$top=1")
|
||||
if persons:
|
||||
first_person = persons[0]
|
||||
p_id = first_person.get('PersonId') or first_person.get('PrimaryKey')
|
||||
|
||||
if p_id:
|
||||
p = client.get_person(p_id)
|
||||
udfs = p.get("UserDefinedFields", {})
|
||||
print(f"Found {len(udfs)} UDFs on Person {p_id}:")
|
||||
for k, v in udfs.items():
|
||||
print(f" - Key (ProgId): {k} | Value: {v}")
|
||||
else:
|
||||
print(f"⚠️ Could not find ID in search result: {first_person.keys()}")
|
||||
|
||||
else:
|
||||
print("⚠️ No persons found. Cannot inspect Person UDFs.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Request failed: {e}")
|
||||
print(f"❌ Error inspecting UDFs: {e}")
|
||||
|
||||
# 2. Discover Lists (MDO Providers)
|
||||
print("\n--- 2. MDO Lists (Positions, Business/Industry) ---")
|
||||
|
||||
lists_to_check = ["position", "business"]
|
||||
|
||||
for list_name in lists_to_check:
|
||||
print(f"\nChecking List: '{list_name}'...")
|
||||
try:
|
||||
# Endpoint: GET /List/{list_name}/Items
|
||||
items = client._get(f"List/{list_name}/Items")
|
||||
if items:
|
||||
print(f"Found {len(items)} items in '{list_name}':")
|
||||
for item in items:
|
||||
print(f" - ID: {item['Id']} | Name: '{item['Name']}'")
|
||||
else:
|
||||
print(f" (List '{list_name}' is empty or not accessible)")
|
||||
except Exception as e:
|
||||
print(f" ❌ Failed to fetch list '{list_name}': {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
token = get_access_token()
|
||||
if token:
|
||||
# Hardcoded Base URL for Cust55774 (Fix: Use app-sod as per README)
|
||||
base_url = "https://app-sod.superoffice.com/Cust55774"
|
||||
|
||||
discover_udfs(base_url, token, "Person")
|
||||
discover_udfs(base_url, token, "Contact")
|
||||
else:
|
||||
print("Could not get Access Token. Check .env")
|
||||
discover()
|
||||
|
||||
Reference in New Issue
Block a user