Jira Provider¶
The Jira provider fetches issues from Jira using the go-jira community SDK.
Installation¶
The Jira provider is built into omnisignal:
Configuration¶
provider, err := omnisignal.New("jira", omnisignal.Config{
BaseURL: "https://company.atlassian.net",
APIKey: os.Getenv("JIRA_USER"), // Username/email
APISecret: os.Getenv("JIRA_TOKEN"), // API token
Options: map[string]any{
"projects": []string{"INFRA", "SUPPORT"},
},
})
Required Fields¶
| Field | Description |
|---|---|
BaseURL |
Jira instance URL (e.g., https://company.atlassian.net) |
APIKey |
Username or email address |
APISecret |
API token |
Optional Fields¶
| Field | Description |
|---|---|
Options["projects"] |
List of project keys to filter (e.g., ["INFRA", "SUPPORT"]) |
Getting an API Token¶
- Log in to Atlassian Account
- Click Create API token
- Use your email as
APIKeyand the token asAPISecret
Capabilities¶
| Capability | Value |
|---|---|
SupportsStreaming |
false |
SupportsBatchFetch |
true |
SupportsFiltering |
true |
SupportsAcknowledge |
false |
MaxBatchSize |
100 |
RateLimitPerMinute |
varies by instance |
SignalTypes |
support_ticket, feedback |
Usage¶
Fetch Recent Issues¶
signals, err := provider.Fetch(ctx, omnisignal.FetchOptions{
Since: time.Now().Add(-7 * 24 * time.Hour),
})
Filter by Status¶
Use Jira status names:
signals, err := provider.Fetch(ctx, omnisignal.FetchOptions{
Since: time.Now().Add(-30 * 24 * time.Hour),
Statuses: []string{"Open", "In Progress", "In Review"},
})
Filter by Severity¶
Severity maps to Jira priority:
| OmniSignal | Jira Priorities |
|---|---|
critical |
Highest, Blocker |
high |
High |
medium |
Medium, Normal |
low |
Low |
info |
Lowest, Trivial |
signals, err := provider.Fetch(ctx, omnisignal.FetchOptions{
Since: time.Now().Add(-7 * 24 * time.Hour),
Severities: []string{"critical", "high"},
})
Custom JQL Filter¶
Use the jql filter for advanced queries:
signals, err := provider.Fetch(ctx, omnisignal.FetchOptions{
Since: time.Now().Add(-30 * 24 * time.Hour),
Filters: map[string]string{
"jql": "labels = incident AND component = api",
},
})
Signal Mapping¶
Jira issues are normalized to signals:
| Signal Field | Jira Source |
|---|---|
ID |
jira-{issue.Key} |
Type |
support_ticket |
Status |
Mapped from issue status |
Severity |
Mapped from priority |
Summary |
issue.Fields.Summary |
Description |
issue.Fields.Description |
ObservedAt |
issue.Fields.Created |
Source.URL |
{BaseURL}/browse/{issue.Key} |
Source.ExternalID |
issue.Key |
Domain.Name |
Project key (lowercase) |
Domain.Subdomain |
Issue type (normalized) |
Tags |
Labels (kebab-case only) |
Status Mapping¶
| Jira Status | Signal Status |
|---|---|
| Contains "done", "closed", "resolved" | archived |
| Contains "progress", "review" | processing |
| Other | new |
Metadata¶
Provider-specific data in signal.Metadata:
metadata := signal.Metadata
issueType := metadata["jira_issue_type"].(string)
project := metadata["jira_project"].(string)
status := metadata["jira_status"].(string)
priority := metadata["jira_priority"].(string)
reporter := metadata["jira_reporter"].(string)
Entities¶
Components are extracted as entities:
for _, entity := range signal.Entities {
if entity.Type == "component" {
fmt.Printf("Component: %s (ID: %s)\n",
entity.Name,
entity.Attributes["jira_id"],
)
}
}
Tags¶
Jira labels are converted to tags if they are valid kebab-case:
incident→ includedhigh-priority→ includedHighPriority→ excluded (not kebab-case)has spaces→ excluded (not kebab-case)
Streaming¶
Jira doesn't support real-time streaming via API. The Subscribe() method returns ErrNotSupported.
For real-time updates, configure Jira Webhooks to push events to your application.