#!/usr/bin/env python3 """ Wrike Board Discovery Script Discovers all necessary IDs and configuration for a Wrike board/space to configure wrike_monitor.py for a new environment """ import json import requests from typing import Dict, Optional, Any class WrikeBoardDiscovery: """Discover Wrike board configuration""" def __init__(self, api_token: str): self.api_base = "https://www.wrike.com/api/v4" self.api_token = api_token self.headers = { "Authorization": f"Bearer {api_token}", "Content-Type": "application/json" } def make_request(self, endpoint: str) -> Optional[Dict[str, Any]]: """Make a GET request to Wrike API""" url = f"{self.api_base}{endpoint}" try: response = requests.get(url, headers=self.headers, timeout=30) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"❌ API Error: {e}") return None def get_all_spaces(self): """Get all available spaces""" print("\n" + "="*80) print("DISCOVERING SPACES") print("="*80) result = self.make_request("/spaces") if result and "data" in result: spaces = result["data"] print(f"\nFound {len(spaces)} space(s):\n") for space in spaces: print(f" • {space['title']}") print(f" ID: {space['id']}") print(f" Access Type: {space.get('accessType', 'N/A')}") print() return spaces return [] def get_space_by_name(self, space_name: str) -> Optional[str]: """Get space ID by name""" result = self.make_request("/spaces") if result and "data" in result: for space in result["data"]: if space["title"].lower() == space_name.lower(): return space["id"] return None def get_custom_item_types(self, space_id: str): """Get custom item types (like 'Deliverable')""" print("\n" + "="*80) print("DISCOVERING CUSTOM ITEM TYPES") print("="*80) result = self.make_request(f"/spaces/{space_id}/item_types") if result and "data" in result: item_types = result["data"] print(f"\nFound {len(item_types)} custom item type(s):\n") for item_type in item_types: print(f" • {item_type['title']}") print(f" ID: {item_type['id']}") print(f" Type: {item_type.get('type', 'N/A')}") print() return item_types return [] def get_custom_fields(self): """Get all custom fields""" print("\n" + "="*80) print("DISCOVERING CUSTOM FIELDS") print("="*80) result = self.make_request("/customfields") if result and "data" in result: custom_fields = result["data"] print(f"\nFound {len(custom_fields)} custom field(s):\n") # Group by account/space for field in custom_fields: print(f" • {field['title']}") print(f" ID: {field['id']}") print(f" Type: {field['type']}") if 'accountId' in field: print(f" Account ID: {field['accountId']}") if 'spaceId' in field: print(f" Space ID: {field['spaceId']}") print() return custom_fields return [] def generate_config_snippet(self, space_name: str, space_id: str, deliverable_type_id: Optional[str], custom_fields: list): """Generate Python config snippet for the discovered board""" print("\n" + "="*80) print("CONFIGURATION SNIPPET FOR wrike_monitor.py") print("="*80) config = f''' # === WRIKE SPACE CONFIGURATION - {space_name} === WRIKE_SPACE_ID = "{space_id}" WRIKE_SPACE_NAME = "{space_name}" ''' if deliverable_type_id: config += f'DELIVERABLE_ITEM_TYPE_ID = "{deliverable_type_id}" # Custom item type "Deliverable"\n' else: config += 'DELIVERABLE_ITEM_TYPE_ID = "XXXXXX" # ⚠️ NOT FOUND - Update manually\n' config += '\n# Custom field IDs\n' config += 'CUSTOM_FIELDS = {\n' # Try to match custom fields by name field_mapping = { "budget": None, "impact": None, "notes": None, "rag": None, "deliverable_category": None, "actions": None, "shoot_date": None, "omg_number": None, "omg_url": None, "box_link": None, "owner": None } for field in custom_fields: field_title = field['title'].lower().replace(" ", "_").replace("#", "number") for key in field_mapping.keys(): if key in field_title or field_title in key: field_mapping[key] = field['id'] break for key, value in field_mapping.items(): if value: config += f' "{key}": "{value}",\n' else: config += f' "{key}": "XXXXXX", # ⚠️ NOT FOUND - Update manually\n' config += '}\n' print(config) # Save to file output_file = f"config_{space_name.replace(' ', '_').lower()}.py" with open(output_file, 'w') as f: f.write(config) print(f"\n✅ Configuration saved to: {output_file}") return config def discover_board(self, space_name: str): """Main discovery function for a specific board""" print(f"\n🔍 Discovering configuration for: {space_name}\n") # Get all spaces spaces = self.get_all_spaces() # Find target space space_id = self.get_space_by_name(space_name) if not space_id: print(f"\n❌ Space '{space_name}' not found!") print(f"Available spaces: {[s['title'] for s in spaces]}") return print(f"\n✅ Found space: {space_name} (ID: {space_id})") # Get custom item types item_types = self.get_custom_item_types(space_id) deliverable_type_id = None for item_type in item_types: if "deliverable" in item_type['title'].lower(): deliverable_type_id = item_type['id'] print(f"✅ Found 'Deliverable' custom item type: {deliverable_type_id}") break if not deliverable_type_id: print("⚠️ WARNING: No 'Deliverable' custom item type found!") # Get custom fields custom_fields = self.get_custom_fields() # Generate config self.generate_config_snippet(space_name, space_id, deliverable_type_id, custom_fields) print("\n" + "="*80) print("DISCOVERY COMPLETE") print("="*80) print("\n📋 Next Steps:") print(" 1. Review the generated config file") print(" 2. Update any fields marked with ⚠️ XXXXXX") print(" 3. Copy the configuration into wrike_monitor.py") print(" 4. Test with a sample JSON file\n") def main(): """Main entry point""" print(""" ╔════════════════════════════════════════════════════════════════╗ ║ WRIKE BOARD DISCOVERY TOOL ║ ║ Discovers IDs and configuration for Wrike monitor script ║ ╚════════════════════════════════════════════════════════════════╝ """) # Configuration API_TOKEN = "eyJ0dCI6InAiLCJhbGciOiJIUzI1NiIsInR2IjoiMiJ9.eyJkIjoie1wiYVwiOjY5NjM3MzksXCJpXCI6OTU5MTM2MSxcImNcIjo0NzAyNjA1LFwidVwiOjIzMjcyNDA0LFwiclwiOlwiVVNcIixcInNcIjpbXCJXXCIsXCJGXCIsXCJJXCIsXCJVXCIsXCJLXCIsXCJDXCIsXCJEXCIsXCJNXCIsXCJBXCIsXCJMXCIsXCJQXCJdLFwielwiOltdLFwidFwiOjB9IiwiaWF0IjoxNzY2MDAwNjMyfQ.FwtNCIiBUbb82MlEnI_Z3vKt-W8IgKRwLwZY6IY6fEI" TARGET_SPACE = "LGL team" # Change this to discover a different space discoverer = WrikeBoardDiscovery(API_TOKEN) discoverer.discover_board(TARGET_SPACE) if __name__ == "__main__": main()