π Goal-oriented synchronization between Jira tickets and Asana tasks running as a Keboola Custom Python Component
This Keboola component automatically synchronizes Jira tickets with Asana tasks, featuring:
- β Automatic health indicator updates in Asana based on Jira changes
- π Health indicator mapping from Jira to Asana
- π¬ Comment transfer from Jira to Asana status updates
- π Goal-oriented workflow via Asana Goals
- π Configuration via Keboola UI
- π Encrypted parameter storage for API tokens
- π Goal metric updates from Jira custom fields
jira_base_url
- Your Jira instance URL (e.g.,https://company.atlassian.net
)jira_email
- Your Jira email addressjira_token
- Jira API token (encrypted parameter)
asana_token
- Asana Personal Access Token (encrypted parameter)
asana_goal_gids
- Specific goal IDs to sync (string or array)asana_project_gids
- Project IDs - sync all goals in these projects (string or array)asana_team_gids
- Team IDs - sync all goals in these teams (string or array)asana_workspace_gids
- Workspace IDs - sync all goals in these workspaces (string or array)
dry_run
- Test mode that shows what would be done without making changes (default: false)status_mapping
- Custom health indicator mapping object (uses defaults if not provided)
{
"on_track": "on_track",
"at_risk": "at_risk",
"off_track": "off_track",
"complete": "complete"
}
{
"on_track": "on_track",
"at_risk": "at_risk",
"off_track": "off_track",
"complete": "complete"
}
Copy this JSON template into your Keboola component configuration:
{
"jira_base_url": "",
"jira_email": "",
"#jira_token": "",
"asana_goal_gids": [],
"asana_project_gids": [],
"asana_team_gids": [],
"asana_workspace_gids": [],
"#asana_token": "",
"dry_run": false,
"status_mapping": {
"on_track": "on_track",
"at_risk": "at_risk",
"done": "complete",
"off_track": "off_track"
}
}
Notes:
- Fill in the empty strings with your actual values
- At least one of the
asana_*_gids
parameters must be specified - Scope parameters can be strings or arrays:
"123456"
or["123456", "789012"]
dry_run: true
enables test mode without making changesstatus_mapping
shows the default mapping (Jira health indicator β Asana status type)- Mark
#jira_token
and#asana_token
as encrypted parameters in Keboola
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_goal_gids": ["1210803030748387", "1210803030748388"],
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": false
}
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_team_gids": "123456789012345",
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": false
}
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_project_gids": ["987654321098765", "456789012345678"],
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": false
}
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_goal_gids": "1210803030748387",
"asana_team_gids": ["123456789012345", "234567890123456"],
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": false
}
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_team_gids": "123456789012345",
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": false,
"status_mapping": {
"on_track": "on_track",
"at_risk": "at_risk",
"off_track": "off_track",
"complete": "complete"
}
}
{
"jira_base_url": "https://mycompany.atlassian.net",
"jira_email": "[email protected]",
"#jira_token": "your_jira_api_token_here",
"asana_team_gids": "123456789012345",
"#asana_token": "your_asana_personal_access_token_here",
"dry_run": true
}
graph TD
A["π Keboola Component Start"] --> B[Load configuration from UI]
B --> C[Validate scope parameters]
C --> D{asana_goal_gids specified?}
D -->|Yes| E[Sync specific goals by ID]
D -->|No| F{asana_project_gids specified?}
F -->|Yes| G[Sync all goals in projects]
F -->|No| H{asana_team_gids specified?}
H -->|Yes| I[Sync all goals in teams]
H -->|No| J{asana_workspace_gids specified?}
J -->|Yes| K[Sync all goals in workspaces]
J -->|No| L[Error: No scope specified]
E --> M[For each goal]
G --> N[Get goals from projects] --> M
I --> O[Get goals from teams] --> M
K --> P[Get goals from workspaces] --> M
M --> Q[Find tasks linked to goal]
Q --> R[Filter tasks with Jira ticket attachments]
R --> S[For each task with Jira ticket]
S --> T[Get Jira ticket from API]
T --> U{Health indicator changed?}
U -->|No| V[Skip]
U -->|Yes| W[Get new comments from Jira]
W --> X[Apply health indicator mapping]
X --> Y{dry_run mode?}
Y -->|Yes| Z[Log what would be done]
Y -->|No| AA[Create status update in Asana]
AA --> BB[Add comments to status]
BB --> CC[Update goal metrics]
Z --> CC[Next task?]
BB --> CC
V --> CC
CC -->|Yes| S
CC -->|No| DD{Next goal?}
DD -->|Yes| M
DD -->|No| EE[β
Complete]
The component includes a Test Connection sync action that validates:
- β Jira API connectivity and authentication
- β Asana API connectivity and authentication
- β Access to specified Asana team and goals
- Go to https://id.atlassian.com/manage-profile/security/api-tokens
- Create API token
- Add as encrypted parameter in Keboola configuration
- Go to Asana β Profile Settings β Apps β Developer Apps
- Create new Personal Access Token
- Add as encrypted parameter in Keboola configuration
The component automatically maps Jira health indicators to Asana goal status types:
on_track
- everything going according to plan (green)at_risk
- there are risks (yellow)off_track
- problems (red)complete
- finished (green)
The component also updates Asana goal metrics with integer values from Jira custom field 11699.
- Check that all required configuration parameters are filled in the Keboola UI
- Ensure encrypted parameters (API tokens) are properly set
- At least one of these parameters must be filled:
asana_goal_gids
,asana_project_gids
,asana_team_gids
, orasana_workspace_gids
- Scope parameters can be strings or arrays of GIDs
- Use the Test Connection sync action to verify API credentials
- Check API token permissions and expiration dates
- Verify that specified GIDs are correct and accessible
- Verify that the specified GIDs (goal/project/team/workspace) are correct
- Check that the specified entities contain goals
- Ensure API token has access to the specified resources
- Use
dry_run: true
to see what goals would be found
- Verify that Asana tasks have Jira ticket attachments (links to Jira tickets)
- Ensure attachment names contain valid Jira ticket format (e.g., ABC-123)
- Ensure tasks are linked to goals via Asana's Goal Relationships
- Use
dry_run: true
to see what tasks are being found
- Set
"dry_run": true
to test configuration without making changes - Dry run will show what goals and tasks would be processed
- Use this to verify your scope configuration before running actual sync
- Python 3.12+
- Keboola Custom Python Component environment
- Valid API access to both Jira and Asana
# Install UV: https://docs.astral.sh/uv/getting-started/installation/
uv sync
# Run locally (requires .env file for testing)
uv run python main.py
βββ main.py # Keboola component entry point
βββ src/
β βββ sync_manager.py # Main synchronization logic
β βββ jira_api.py # Jira API integration
β βββ asana_api.py # Asana API integration
βββ pyproject.toml # Modern Python project configuration
βββ README.md # This file
- UV for dependency management
- Python 3.12+ with modern type hints
- Keboola Component SDK for platform integration
- Requests for HTTP API calls
- python-dateutil for timezone handling
- BeautifulSoup4 for HTML parsing and generation
- Asana Python SDK for API integration
MIT License - feel free to modify and use for your projects!