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:
@@ -159,6 +159,32 @@ async def migrate_schema(engine: AsyncEngine) -> None:
|
||||
)
|
||||
logger.info("Added %s column to tracking_config table", col_name)
|
||||
|
||||
# Add Planka tracking flags to tracking_config if missing
|
||||
if await _has_table(conn, "tracking_config"):
|
||||
planka_flags = [
|
||||
("track_card_created", "INTEGER DEFAULT 1"),
|
||||
("track_card_updated", "INTEGER DEFAULT 0"),
|
||||
("track_card_moved", "INTEGER DEFAULT 1"),
|
||||
("track_card_deleted", "INTEGER DEFAULT 0"),
|
||||
("track_card_commented", "INTEGER DEFAULT 1"),
|
||||
("track_comment_updated", "INTEGER DEFAULT 0"),
|
||||
("track_board_created", "INTEGER DEFAULT 1"),
|
||||
("track_board_updated", "INTEGER DEFAULT 0"),
|
||||
("track_board_deleted", "INTEGER DEFAULT 1"),
|
||||
("track_list_created", "INTEGER DEFAULT 0"),
|
||||
("track_list_updated", "INTEGER DEFAULT 0"),
|
||||
("track_list_deleted", "INTEGER DEFAULT 0"),
|
||||
("track_attachment_created", "INTEGER DEFAULT 1"),
|
||||
("track_card_label_added", "INTEGER DEFAULT 0"),
|
||||
("track_task_completed", "INTEGER DEFAULT 1"),
|
||||
]
|
||||
for col_name, col_type in planka_flags:
|
||||
if not await _has_column(conn, "tracking_config", col_name):
|
||||
await conn.execute(
|
||||
text(f"ALTER TABLE tracking_config ADD COLUMN {col_name} {col_type}")
|
||||
)
|
||||
logger.info("Added %s column to tracking_config table", col_name)
|
||||
|
||||
# Add collection_name and shared to tracker_state if missing
|
||||
state_table = "notification_tracker_state" if await _has_table(conn, "notification_tracker_state") else "tracker_state"
|
||||
if await _has_table(conn, state_table):
|
||||
|
||||
@@ -128,6 +128,23 @@ class TrackingConfig(SQLModel, table=True):
|
||||
track_pr_commented: bool = Field(default=False)
|
||||
track_release_published: bool = Field(default=True)
|
||||
|
||||
# Planka event tracking
|
||||
track_card_created: bool = Field(default=True)
|
||||
track_card_updated: bool = Field(default=False)
|
||||
track_card_moved: bool = Field(default=True)
|
||||
track_card_deleted: bool = Field(default=False)
|
||||
track_card_commented: bool = Field(default=True)
|
||||
track_comment_updated: bool = Field(default=False)
|
||||
track_board_created: bool = Field(default=True)
|
||||
track_board_updated: bool = Field(default=False)
|
||||
track_board_deleted: bool = Field(default=True)
|
||||
track_list_created: bool = Field(default=False)
|
||||
track_list_updated: bool = Field(default=False)
|
||||
track_list_deleted: bool = Field(default=False)
|
||||
track_attachment_created: bool = Field(default=True)
|
||||
track_card_label_added: bool = Field(default=False)
|
||||
track_task_completed: bool = Field(default=True)
|
||||
|
||||
# Scheduler event tracking
|
||||
track_scheduled_message: bool = Field(default=True)
|
||||
|
||||
|
||||
@@ -183,6 +183,7 @@ async def _seed_default_templates() -> None:
|
||||
async with AsyncSession(engine) as session:
|
||||
await _seed_provider_template(session, "immich", "Immich")
|
||||
await _seed_provider_template(session, "gitea", "Gitea")
|
||||
await _seed_provider_template(session, "planka", "Planka")
|
||||
await _seed_provider_template(session, "scheduler", "Scheduler")
|
||||
await session.commit()
|
||||
|
||||
@@ -201,6 +202,9 @@ async def _seed_default_command_templates() -> None:
|
||||
await _seed_provider_command_template(
|
||||
session, "gitea", "Default Gitea Commands", "Default Gitea command templates",
|
||||
)
|
||||
await _seed_provider_command_template(
|
||||
session, "planka", "Default Planka Commands", "Default Planka command templates",
|
||||
)
|
||||
await session.commit()
|
||||
|
||||
|
||||
@@ -227,6 +231,25 @@ async def _seed_default_tracking_configs() -> None:
|
||||
"track_pr_commented": False,
|
||||
"track_release_published": True,
|
||||
},
|
||||
{
|
||||
"provider_type": "planka",
|
||||
"name": "Default Planka",
|
||||
"track_card_created": True,
|
||||
"track_card_updated": False,
|
||||
"track_card_moved": True,
|
||||
"track_card_deleted": False,
|
||||
"track_card_commented": True,
|
||||
"track_comment_updated": False,
|
||||
"track_board_created": True,
|
||||
"track_board_updated": False,
|
||||
"track_board_deleted": True,
|
||||
"track_list_created": False,
|
||||
"track_list_updated": False,
|
||||
"track_list_deleted": False,
|
||||
"track_attachment_created": True,
|
||||
"track_card_label_added": False,
|
||||
"track_task_completed": True,
|
||||
},
|
||||
{
|
||||
"provider_type": "scheduler",
|
||||
"name": "Default Scheduler",
|
||||
@@ -280,6 +303,16 @@ async def _seed_default_command_configs() -> None:
|
||||
"default_count": 10,
|
||||
"rate_limits": {"api": 15, "default": 10},
|
||||
},
|
||||
{
|
||||
"provider_type": "planka",
|
||||
"name": "Default Planka",
|
||||
"enabled_commands": [
|
||||
"help", "status", "boards", "cards", "lists",
|
||||
],
|
||||
"response_mode": "text",
|
||||
"default_count": 10,
|
||||
"rate_limits": {"api": 15, "default": 10},
|
||||
},
|
||||
]
|
||||
|
||||
for cfg in defaults:
|
||||
|
||||
Reference in New Issue
Block a user