- Automatic folder/project/task creation from JSON files
- Duplicate detection via OMG numbers
- Custom field mapping
- File management (Processed folder + 24hr cleanup)
- Production ready
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
|
||
|---|---|---|
| .gitignore | ||
| README.md | ||
| wrike_import.py | ||
Wrike Import Script
A Python script to automatically import project structures and deliverable tasks into Wrike from JSON files.
Overview
This script processes JSON files containing job specifications and creates the corresponding structure in Wrike:
- Folders (product categories like "Dry Specialty", "Air", "PDC")
- Projects (campaigns with timelines and metadata)
- Tasks (deliverables with custom fields and due dates)
The script intelligently handles duplicates by checking OMG numbers before creating new items, updating existing ones instead.
Features
- ✅ Automatic folder creation from BusinessArea hierarchy
- ✅ Project management with start/end dates and campaign codes
- ✅ Task creation/updates with comprehensive custom fields
- ✅ Duplicate prevention via OMG number checking
- ✅ Smart caching to minimize API calls
- ✅ Detailed logging with progress tracking
- ✅ Batch processing of multiple JSON files
- ✅ Automatic file management - moves processed files to Processed subfolder
- ✅ Auto-cleanup - deletes files older than 24 hours from Processed folder
Requirements
Python Dependencies
pip install requests
Python Version
- Python 3.6 or higher
Wrike Requirements
- Valid Wrike API token with write permissions
- Access to the target Wrike space
- Custom fields configured in the space (see Configuration section)
Installation
- Clone or download this repository
- Install dependencies:
pip install requests - Configure your Wrike API token in the script (see Configuration)
Configuration
1. API Token
Edit wrike_import.py and update the WRIKE_TOKEN constant:
WRIKE_TOKEN = "your_wrike_api_token_here"
2. Target Space
Update the STAGING_SPACE_ID to point to your target Wrike space:
STAGING_SPACE_ID = "MQAAAABpz7l_" # Your space ID
To find your space ID:
curl -X GET "https://www.wrike.com/api/v4/spaces" \
-H "Authorization: Bearer YOUR_TOKEN"
3. Custom Fields
The script expects the following custom fields to exist in your Wrike space:
| Field Name | Type | ID Variable | Usage |
|---|---|---|---|
| Budget | Currency | budget |
Project budgets |
| Impact | Dropdown | impact |
Priority level |
| Notes | Text | notes |
Additional information |
| RAG | Dropdown | rag |
Status (Red/Amber/Green) |
| Deliverable Category | Dropdown | deliverable_category |
Type of deliverable |
| Actions | Text | actions |
Next steps |
| Shoot date | Date | shoot_date |
Photography date |
| OMG # | Text | omg_number |
Job/Campaign number |
| Box Link | Text | box_link |
Link to assets |
| Owner | Contacts | owner |
Task owner |
To create these fields, use the Wrike API or create them manually in the Wrike interface.
Update custom field IDs in the script after creating them:
CUSTOM_FIELDS = {
"budget": "YOUR_BUDGET_FIELD_ID",
"impact": "YOUR_IMPACT_FIELD_ID",
# ... etc
}
JSON File Format
Required Structure
{
"JobSpecification": {
"ProjectDetails": {
"BusinessArea": "BISSELL > PRODUCT MARKETING > Dry Specialty",
"Title": "PowerClean FurFinder + FurGuard 2025",
"Description": "<p>PowerClean FurFinder + FurGuard 2025-related workflows</p>",
"StartDate": "2025-04-08 13:00:00+00",
"EndDate": "2025-12-31 17:06:00+00"
},
"JobDetails": {
"Number": "5791330",
"Title": "PowerClean Corded Mass User Guide",
"CampaignCode": "1647476",
"JobCategory": "UX User Guide",
"MediaType": "Creative development",
"Type": "Creative development",
"Notes": "User guide for mass market",
"BriefDate": "2025-05-23 16:00:00+00",
"DueDate": "2025-09-17 16:04:00+00",
"BusinessArea": "BISSELL > PRODUCT MARKETING > Dry Specialty"
}
}
}
Field Mapping
Project Level
| JSON Field | Maps To | Notes |
|---|---|---|
ProjectDetails.BusinessArea |
Folder name | Last segment (e.g., "Dry Specialty") |
ProjectDetails.Title |
Project title | |
ProjectDetails.Description |
Project description | HTML tags removed |
ProjectDetails.StartDate |
Project start date | Converted to YYYY-MM-DD |
ProjectDetails.EndDate |
Project end date | Converted to YYYY-MM-DD |
JobDetails.CampaignCode |
Project OMG # | Custom field |
Task/Deliverable Level
| JSON Field | Maps To | Notes |
|---|---|---|
JobDetails.Number |
Task OMG # | Used for duplicate detection |
JobDetails.Title |
Task title | |
JobDetails.Notes |
Task description | |
JobDetails.JobCategory |
Deliverable Category | Custom field |
JobDetails.MediaType |
Deliverable Category | Fallback if JobCategory empty |
JobDetails.Type |
Notes field | Combined with Details |
JobDetails.BriefDate |
Task start date | |
JobDetails.DueDate |
Task due date |
Usage
Basic Usage
Process all JSON files in a directory:
python wrike_import.py /path/to/json/files/
Example
# Process files in the current directory
python wrike_import.py ./jobs/
# Process files in a specific folder
python wrike_import.py ~/Documents/wrike_imports/
Output Example
Found 3 JSON file(s) to process
Target: Wrike Staging Space (MQAAAABpz7l_)
================================================================================
Processing: 5791330.json
================================================================================
1. Processing folder: 'Dry Specialty'
Found existing folder 'Dry Specialty': MQAAAABpz123
2. Processing project: 'PowerClean FurFinder + FurGuard 2025'
Campaign Code: 1647476
Found existing project 'PowerClean FurFinder + FurGuard 2025': MQAAAABpz456
3. Processing deliverable task
Checking for existing task with OMG #: 5791330
Creating new task 'PowerClean Corded Mass User Guide' (Job #5791330)
✓ Created task 'PowerClean Corded Mass User Guide': MAAAAABpz789
✓ Successfully processed 5791330.json
→ Moved to: Processed/5791330.json
================================================================================
Processing: 5791331.json
================================================================================
1. Processing folder: 'Air'
Found existing folder 'Air': MQAAAABpz124
2. Processing project: 'Air Purifier 2025'
Campaign Code: 1647477
Found existing project 'Air Purifier 2025': MQAAAABpz457
3. Processing deliverable task
Checking for existing task with OMG #: 5791331
Found existing task: MAAAAABpz790
⊙ Task 'Air Purifier Hero Image' already exists (Job #5791331) - skipping
⊙ Successfully processed 5791331.json (task already exists)
→ Moved to: Processed/5791331.json
================================================================================
CLEANUP
================================================================================
Deleted old file: 5791329.json
Deleted old file: 5791328.json
Deleted 2 file(s) older than 24 hours from Processed folder
================================================================================
SUMMARY
================================================================================
Total files: 3
Successful: 3
Skipped (already exists): 1
Failed: 0
Moved to Processed: 3
Folders created/found: 2
Projects created/found: 3
How It Works
1. Folder Management
- Extracts the last segment from
BusinessArea(e.g., "BISSELL > PRODUCT MARKETING > Dry Specialty" → "Dry Specialty") - Checks if folder exists in the target space
- Creates folder if not found
- Caches folder IDs for performance
2. Project Management
- Searches for existing project by title in the folder
- Creates new project if not found
- Converts folder to project with start/end dates
- Adds campaign code as OMG # custom field
- Caches project IDs for performance
3. Task Management
- Checks for existing task by OMG # (job number)
- If found: Updates existing task with new data
- If not found: Creates new task
- Populates all custom fields and dates
4. Duplicate Handling
The script prevents duplicates using OMG numbers:
- Projects: Matched by title within folder
- Tasks: Matched by OMG # custom field (job number)
When processing the same JSON file twice:
- 1st run: Creates folder, project, and task
- 2nd run:
- Finds existing folder and project (reuses them)
- Finds existing task with same OMG # → Skips task creation
- Marks file as "skipped" and moves to Processed folder
Important: Tasks are never updated once created. If a task with the same OMG # exists, it's left unchanged.
5. File Management
After successful processing:
- Moves file to
Processed/subfolder (auto-created) - Failed files remain in the source directory for retry
- Cleanup: Deletes files older than 24 hours from Processed folder
Directory structure:
json_files/
├── 5791331.json # Pending
├── 5791332.json # Pending
└── Processed/
├── 5791330.json # Processed today (kept)
└── 5791329.json # Processed >24h ago (deleted)
Troubleshooting
Common Issues
1. Authentication Error
Error making Wrike request: 401 Unauthorized
Solution: Verify your API token is correct and has write permissions.
2. Custom Field Not Found
Error: Custom field ID not found
Solution: Ensure all custom fields are created in Wrike and IDs are updated in the script.
3. No JSON Files Found
No JSON files found in '/path/to/directory'
Solution:
- Verify the directory path is correct
- Ensure files have
.jsonextension - Check file permissions
4. Invalid Space ID
Error: Space 'MQAAAABpz7l_' not found
Solution:
- Get your space ID from the API:
GET /spaces - Update
STAGING_SPACE_IDin the script
Debug Mode
To see detailed API responses, modify the make_wrike_request function to print full responses:
def make_wrike_request(method, endpoint, data=None):
# ... existing code ...
print(f"Response: {response.json()}") # Add this line
return response.json()
API Rate Limits
Wrike API has rate limits:
- 100 requests per minute per token
- 1000 requests per hour per token
The script is optimized with caching to minimize API calls, but for very large batches (100+ files), you may need to:
- Process in smaller batches
- Add delays between requests
Data Mapping Reference
Date Format Conversion
Input: "2025-05-23 16:00:00+00"
Output: "2025-05-23"
HTML Cleaning
Input: "<p>PowerClean FurFinder + FurGuard 2025-related workflows</p>"
Output: "PowerClean FurFinder + FurGuard 2025-related workflows"
Business Area Parsing
Input: "BISSELL > PRODUCT MARKETING > Dry Specialty"
Output: "Dry Specialty" (folder name)
Advanced Usage
Custom Field Mapping
To add more custom fields, update the script:
- Add field ID to
CUSTOM_FIELDSdictionary - Update
create_or_update_deliverable_task()function:
# Add your custom field
custom_fields.append({
"id": CUSTOM_FIELDS["your_field_name"],
"value": job_details.get("YourJsonField", "")
})
Filter by Business Area
To process only specific business areas, add a filter in process_json_file():
folder_name = parse_business_area(business_area)
# Only process specific folders
if folder_name not in ["Dry Specialty", "Air"]:
print(f" Skipping folder '{folder_name}'")
return False
Batch Processing Script
Create a wrapper script for automated processing:
#!/bin/bash
# process_all.sh
IMPORT_DIR="/path/to/json/files"
# Run import (automatically moves to Processed/ and cleans up old files)
python wrike_import.py "$IMPORT_DIR"
# Optional: Send notification
if [ $? -eq 0 ]; then
echo "Wrike import completed successfully"
fi
Scheduled Processing with Cron
Set up automatic processing every hour:
# Edit crontab
crontab -e
# Add this line to run every hour
0 * * * * /usr/bin/python3 /path/to/wrike_import.py /path/to/json/files >> /var/log/wrike_import.log 2>&1
Change Cleanup Retention Period
To change the 24-hour retention to a different period, modify the cleanup call in the script:
# Delete files older than 48 hours instead
deleted_count = cleanup_old_files(json_dir, hours=48)
# Delete files older than 7 days
deleted_count = cleanup_old_files(json_dir, hours=168)
Security Notes
⚠️ Important Security Considerations:
- Never commit API tokens to version control
- Store tokens in environment variables:
import os WRIKE_TOKEN = os.environ.get('WRIKE_API_TOKEN') - Use a
.envfile for local development (add to.gitignore) - Rotate tokens regularly
- Use read-only tokens for testing
Support
Getting Help
- Check the Wrike API Documentation
- Review error messages in script output
- Enable debug mode for detailed logging
- Check Wrike API status at status.wrike.com
Reporting Issues
When reporting issues, include:
- Script version
- Python version (
python --version) - Full error message
- Sample JSON structure (redacted)
- Wrike space configuration
License
This script is provided as-is for internal use.
Changelog
Version 1.2 (Current)
- Added automatic file movement to Processed subfolder
- Implemented auto-cleanup of files older than 24 hours
- Improved file management and organization
- Enhanced output with file movement tracking
Version 1.1
- Added duplicate detection via OMG numbers
- Separated project and task OMG numbers
- Improved error handling
- Added caching for performance
- Enhanced logging output
Version 1.0
- Initial release
- Basic folder/project/task creation
- Custom field mapping
Last Updated: October 2025 Author: Dave Porter Wrike Space: Staging (MQAAAABpz7l_)