3333
3434@router .post ("/commands" )
3535async def slack_slash_command (request : Request ):
36+ """Handle Slack slash commands and open the draft generation modal."""
3637 form_data = await request .form ()
3738 command = form_data .get ("command" )
3839 trigger_id = form_data .get ("trigger_id" )
@@ -41,7 +42,7 @@ async def slack_slash_command(request: Request):
4142 if command != "/draft" :
4243 return {"response_type" : "ephemeral" , "text" : SLACK_UI ["cmd_unknown" ]}
4344
44- # Відкриваємо модалку замість парсингу тексту
45+ # Open a modal instead of parsing the command text
4546 modal_view = build_generation_modal (channel_id = channel_id )
4647 slack_token = (
4748 settings .SLACK_BOT_TOKEN .get_secret_value () if settings .SLACK_BOT_TOKEN else ""
@@ -57,7 +58,7 @@ async def slack_slash_command(request: Request):
5758 if not res .json ().get ("ok" ):
5859 logger .error ("slack_modal_open_error" , error = res .json ())
5960
60- # Повертаємо 200 OK без тіла, щоб Slack не дублював повідомлення
61+ # Return 200 OK with no body so Slack does not duplicate the message
6162 return Response (status_code = 200 )
6263
6364
@@ -66,6 +67,7 @@ async def slack_interactions(
6667 request : Request ,
6768 session : AsyncSession = Depends (get_db_session ), # noqa: B008
6869):
70+ """Dispatch Slack block_actions and view_submission interaction payloads."""
6971 form_data = await request .form ()
7072 payload_str = form_data .get ("payload" )
7173
@@ -87,11 +89,11 @@ async def slack_interactions(
8789 action_id = action .get ("action_id" )
8890 response_url = payload .get ("response_url" )
8991 logger .info ("slack_block_action" , action_id = action_id , trigger_id = trigger_id )
90- action_value = action .get ("value" , "temp_id|telegram " )
92+ action_value = action .get ("value" , "temp_id|threads " )
9193 value_parts = action_value .split ("|" )
9294 draft_id = value_parts [0 ]
93- platform = value_parts [1 ] if len (value_parts ) > 1 else "telegram "
94- # --- ГРУПА 1: Дії, що відкривають модалки (response_url НЕ потрібен ) ---
95+ platform = value_parts [1 ] if len (value_parts ) > 1 else "threads "
96+ # --- GROUP 1: Actions that open modals (response_url not needed ) ---
9597 if action_id == "action_open_upload_modal" :
9698 modal_view = build_upload_modal ()
9799 async with httpx .AsyncClient () as client :
@@ -186,7 +188,7 @@ async def slack_interactions(
186188 json = {"trigger_id" : trigger_id , "view" : modal_view },
187189 )
188190 return Response (status_code = 200 )
189- # --- ГРУПА 2: Дії з повідомленнями (response_url ОБОВ'ЯЗКОВИЙ ) ---
191+ # --- GROUP 2: Message actions (response_url required ) ---
190192 if action_id in [
191193 "action_publish_draft" ,
192194 "action_reject_draft" ,
@@ -200,7 +202,7 @@ async def slack_interactions(
200202 )
201203 return Response (status_code = 200 )
202204
203- # Беремо topic і draft_text з БД якщо є draft_id
205+ # Load topic and draft_text from DB when draft_id is available
204206 topic = "Медичний пост"
205207 blocks = payload .get ("message" , {}).get ("blocks" , [])
206208 raw_draft = ""
@@ -220,7 +222,7 @@ async def slack_interactions(
220222
221223 async with httpx .AsyncClient () as client :
222224 if action_id == "action_publish_draft" :
223- # ДОДАНО: Змінюємо статус на Опубліковано
225+ # Update status to Published
224226 if draft_id .isdigit ():
225227 repo = DraftRepository (session )
226228 await repo .update (
@@ -294,7 +296,7 @@ async def slack_interactions(
294296 callback_id = view .get ("callback_id" )
295297 state_values = view .get ("state" , {}).get ("values" , {})
296298
297- # --- СЦЕНАРІЙ 1: Генерація нового драфту ---
299+ # --- SCENARIO 1: Generate a new draft ---
298300 if callback_id == "modal_generate_draft" :
299301 channel_id = view .get ("private_metadata" )
300302 topic = (
@@ -321,8 +323,8 @@ async def slack_interactions(
321323 platform = platform ,
322324 )
323325
324- # --- ДОДАНО: СТВОРЕННЯ КОРИСТУВАЧА ТА ДРАФТУ В БД ---
325- # 1. Знаходимо або створюємо користувача ( Slack ID)
326+ # Create user and draft in the database
327+ # 1. Find or create the user by Slack ID
326328 user_query = await session .execute (
327329 select (User ).where (User .username == user_id )
328330 )
@@ -332,15 +334,14 @@ async def slack_interactions(
332334 session .add (db_user )
333335 await session .flush ()
334336
335- # 2. Створюємо драфт (статус pending)
337+ # 2. Create draft with pending status
336338 repo = DraftRepository (session )
337339 new_draft = await repo .create (
338340 DraftCreate (topic = topic , platform = platform , user_id = db_user .id )
339341 )
340342 real_draft_id = str (new_draft .id )
341- # ---------------------------------------------------
342343
343- # Передаємо РЕАЛЬНИЙ ID з бази замість UUID
344+ # Pass the real database ID instead of a UUID
344345 await generate_draft_task .kiq ( # type: ignore[call-overload]
345346 topic = topic ,
346347 platform = platform .value ,
@@ -367,15 +368,15 @@ async def slack_interactions(
367368 status_code = 200 ,
368369 )
369370
370- # --- СЦЕНАРІЙ 2: Збереження відредагованого драфту ---
371+ # --- SCENARIO 2: Save an edited draft ---
371372 elif callback_id == "modal_edit_draft" :
372373 draft_content = (
373374 state_values .get ("block_draft_content" , {})
374375 .get ("input_draft_content" , {})
375376 .get ("value" , "" )
376377 )
377378
378- # Надійний парсинг селектора платформи
379+ # Safely parse the platform selector value
379380 block_state = state_values .get ("block_platform_select" , {}).get (
380381 "input_platform_select" , {}
381382 )
@@ -387,7 +388,7 @@ async def slack_interactions(
387388 )
388389 platform = Platform (platform_raw ) if platform_raw else None
389390
390- # 1. СПОЧАТКУ витягуємо метадані (ID, канали, топік )
391+ # 1. Extract metadata first (ID, channels, topic )
391392 metadata_parts = view .get ("private_metadata" , "" ).split ("|" )
392393 topic = metadata_parts [0 ] if len (metadata_parts ) > 0 else "Медичний пост"
393394 draft_id = metadata_parts [1 ] if len (metadata_parts ) > 1 else "temp_id"
@@ -401,21 +402,21 @@ async def slack_interactions(
401402 draft_id = draft_id ,
402403 )
403404
404- # 2. ПОТІМ зберігаємо в базу даних
405+ # 2. Then save to the database
405406 if draft_id .isdigit ():
406407 repo = DraftRepository (session )
407408 await repo .update (
408409 int (draft_id ), DraftUpdate (content = draft_content , platform = platform )
409410 )
410411
411- # 3. ПОТІМ перемальовуємо повідомлення новою карткою з кнопками
412+ # 3. Then redraw the message with an updated card and buttons
412413 if msg_channel_id and message_ts :
413414 updated_blocks = build_draft_card (
414415 topic = topic ,
415416 draft = draft_content ,
416417 user_id = user_id ,
417418 draft_id = draft_id ,
418- platform = platform .value if platform else "telegram " ,
419+ platform = platform .value if platform else "threads " ,
419420 )
420421 async with httpx .AsyncClient () as client :
421422 await client .post (
@@ -431,14 +432,14 @@ async def slack_interactions(
431432 },
432433 )
433434
434- # 4. В КІНЦІ закриваємо модалку одним return
435+ # 4. Close the modal with a single return at the end
435436 return Response (
436437 content = json .dumps ({"response_action" : "clear" }),
437438 media_type = "application/json" ,
438439 status_code = 200 ,
439440 )
440441
441- # --- СЦЕНАРІЙ 3: Ручний пост ---
442+ # --- SCENARIO 3: Manual post ---
442443 elif callback_id == "modal_manual_post" :
443444 content = (
444445 state_values .get ("block_manual_content" , {})
@@ -469,7 +470,7 @@ async def slack_interactions(
469470 else None
470471 )
471472
472- # Знаходимо або створюємо користувача
473+ # Find or create the user
473474 user_query = await session .execute (
474475 select (User ).where (User .username == user_id )
475476 )
@@ -522,11 +523,11 @@ async def slack_interactions(
522523 status_code = 200 ,
523524 )
524525
525- # --- СЦЕНАРІЙ 4: Планування публікації ---
526+ # --- SCENARIO 4: Schedule a publication ---
526527 elif callback_id == "modal_schedule_draft" :
527528 metadata_parts = view .get ("private_metadata" , "" ).split ("|" )
528529 draft_id = metadata_parts [0 ] if len (metadata_parts ) > 0 else ""
529- platform = metadata_parts [1 ] if len (metadata_parts ) > 1 else "telegram "
530+ platform = metadata_parts [1 ] if len (metadata_parts ) > 1 else "threads "
530531
531532 schedule_timestamp = (
532533 state_values .get ("block_schedule_time" , {})
@@ -572,7 +573,7 @@ async def slack_interactions(
572573 status_code = 200 ,
573574 )
574575
575- # --- СЦЕНАРІЙ 5: Завантаження гайдлайну ---
576+ # --- SCENARIO 5: Upload a guideline ---
576577 elif callback_id == "modal_upload_guideline" :
577578 files = (
578579 state_values .get ("block_file_upload" , {})
@@ -606,7 +607,7 @@ async def slack_events(
606607 request : Request ,
607608 session : AsyncSession = Depends (get_db_session ), # noqa: B008
608609):
609- """Обробка Events API (наприклад, відкриття вкладки Home) ."""
610+ """Handle Events API callbacks such as the app_home_opened event ."""
610611 data = await request .json ()
611612
612613 if data .get ("type" ) == "url_verification" :
@@ -618,15 +619,15 @@ async def slack_events(
618619 logger .info ("slack_event_received" , event_type = event .get ("type" ), user_id = user_id )
619620
620621 if event .get ("type" ) == "app_home_opened" :
621- # 1. Витягуємо останні 10 драфтів
622+ # 1. Fetch the latest 10 drafts
622623 repo = DraftRepository (session )
623624 recent_drafts = await repo .get_recent_drafts (limit = 10 )
624625
625626 logger .info (
626627 "slack_home_opened" , user_id = user_id , drafts_count = len (recent_drafts )
627628 )
628629
629- # 2. Рендеримо дашборд
630+ # 2. Render the dashboard
630631 slack_token = (
631632 settings .SLACK_BOT_TOKEN .get_secret_value ()
632633 if hasattr (settings .SLACK_BOT_TOKEN , "get_secret_value" )
0 commit comments