feat: add Planka service provider with full notification and command support
Webhook-based provider for Planka (self-hosted Kanban board) with: - 15 event types (cards, boards, lists, comments, tasks, attachments, labels) - Bearer token webhook authentication - Async API client for boards/cards/lists - 30 notification templates (en/ru) + 26 command templates (en/ru) - Bot commands: /status, /boards, /cards, /lists - Default tracking config, template config, command config seeded on startup - DB migration for 15 new tracking_config columns - Frontend: provider config UI with auto-name, Planka-specific hints - Frontend: tracking config event toggles for all 15 Planka events
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
from notify_bridge_core.providers.immich import ImmichServiceProvider
|
||||
from notify_bridge_core.providers.gitea import GiteaServiceProvider
|
||||
from notify_bridge_core.providers.planka import PlankaServiceProvider
|
||||
|
||||
from ..database.models import ServiceProvider
|
||||
|
||||
@@ -27,3 +28,14 @@ def make_gitea_provider(http_session, provider: ServiceProvider) -> GiteaService
|
||||
config.get("api_token", ""),
|
||||
provider.name,
|
||||
)
|
||||
|
||||
|
||||
def make_planka_provider(http_session, provider: ServiceProvider) -> PlankaServiceProvider:
|
||||
"""Create a PlankaServiceProvider from a DB provider model."""
|
||||
config = provider.config or {}
|
||||
return PlankaServiceProvider(
|
||||
http_session,
|
||||
config.get("url", ""),
|
||||
config.get("api_key", ""),
|
||||
provider.name,
|
||||
)
|
||||
|
||||
@@ -62,6 +62,22 @@ def event_allowed_by_config(event: ServiceEvent, tc: TrackingConfig) -> bool:
|
||||
"pr_merged": tc.track_pr_merged,
|
||||
"pr_commented": tc.track_pr_commented,
|
||||
"release_published": tc.track_release_published,
|
||||
# Planka events
|
||||
"card_created": tc.track_card_created,
|
||||
"card_updated": tc.track_card_updated,
|
||||
"card_moved": tc.track_card_moved,
|
||||
"card_deleted": tc.track_card_deleted,
|
||||
"card_commented": tc.track_card_commented,
|
||||
"comment_updated": tc.track_comment_updated,
|
||||
"board_created": tc.track_board_created,
|
||||
"board_updated": tc.track_board_updated,
|
||||
"board_deleted": tc.track_board_deleted,
|
||||
"list_created": tc.track_list_created,
|
||||
"list_updated": tc.track_list_updated,
|
||||
"list_deleted": tc.track_list_deleted,
|
||||
"attachment_created": tc.track_attachment_created,
|
||||
"card_label_added": tc.track_card_label_added,
|
||||
"task_completed": tc.track_task_completed,
|
||||
# Scheduler events
|
||||
"scheduled_message": tc.track_scheduled_message,
|
||||
}
|
||||
|
||||
@@ -142,6 +142,30 @@ _SAMPLE_CONTEXT = {
|
||||
"release_body": "Initial release",
|
||||
"release_draft": False,
|
||||
"release_prerelease": False,
|
||||
# Planka variables (for planka provider templates)
|
||||
"board_name": "My Project",
|
||||
"board_id": "123456",
|
||||
"board_url": "https://planka.example.com/boards/123456",
|
||||
"card_name": "Fix login bug",
|
||||
"card_id": "789012",
|
||||
"card_url": "https://planka.example.com/cards/789012",
|
||||
"card_description": "Users cannot log in with SSO",
|
||||
"card_due_date": "2026-04-01T00:00:00.000Z",
|
||||
"list_name": "In Progress",
|
||||
"list_id": "list-1",
|
||||
"old_list_name": "To Do",
|
||||
"new_list_name": "In Progress",
|
||||
"old_list_id": "list-0",
|
||||
"new_list_id": "list-1",
|
||||
"comment_text": "Looks good, ready for review!",
|
||||
"comment_id": "comment-1",
|
||||
"task_name": "Write unit tests",
|
||||
"task_id": "task-1",
|
||||
"task_completed": True,
|
||||
"attachment_name": "screenshot.png",
|
||||
"attachment_id": "att-1",
|
||||
"label_name": "bug",
|
||||
"label_color": "berry-red",
|
||||
# Scheduler variables (for scheduler provider templates)
|
||||
"schedule_name": "Daily Reminder",
|
||||
"fire_count": 42,
|
||||
|
||||
@@ -111,6 +111,9 @@ async def check_tracker(tracker_id: int) -> dict[str, Any]:
|
||||
# Gitea is webhook-based — events arrive via /api/webhooks/gitea endpoint.
|
||||
# The scheduler still calls check_tracker but there's nothing to poll.
|
||||
return {"status": "ok", "events_detected": 0, "collections_checked": 0}
|
||||
elif provider_type == "planka":
|
||||
# Planka is webhook-based — events arrive via /api/webhooks/planka endpoint.
|
||||
return {"status": "ok", "events_detected": 0, "collections_checked": 0}
|
||||
elif provider_type == "scheduler":
|
||||
from notify_bridge_core.providers.scheduler import SchedulerServiceProvider
|
||||
custom_vars = tracker_filters.get("custom_variables", {})
|
||||
|
||||
Reference in New Issue
Block a user