11import logging
22
3- from fastapi import APIRouter , Depends , Query , Request
3+ from fastapi import APIRouter , Depends , HTTPException , Query , Request
44from pydantic import ValidationError
55
6- from api .dependencies import get_archive_offer_use_case
6+ from api .dependencies import get_archive_offer_use_case , get_load_offer_details_use_case
77from api .talentsoft import verify_talentsoft_signature
88from application .use_cases .archive_offer import ArchiveOfferUseCase
9+ from application .use_cases .load_offer_details import LoadOfferDetailsUseCase
910from presentation .dtos .talentsoft_webhook import (
1011 TalentsoftWebhookPayload ,
1112 should_archive ,
13+ should_load_offer_details ,
1214)
1315
1416logger = logging .getLogger (__name__ )
1517
1618public_router = APIRouter ()
1719
20+ _OK = {"status" : "ok" }
21+
1822
1923@public_router .get ("/health" )
2024def health ():
@@ -27,35 +31,61 @@ def health():
2731async def talentsoft_webhook (
2832 request : Request ,
2933 client_id : str = Query (...),
30- use_case : ArchiveOfferUseCase = Depends (get_archive_offer_use_case ),
34+ archive_use_case : ArchiveOfferUseCase | None = Depends (get_archive_offer_use_case ),
35+ load_offer_use_case : LoadOfferDetailsUseCase | None = Depends (
36+ get_load_offer_details_use_case
37+ ),
3138):
3239 body = await request .body ()
3340 logger .debug (
3441 "Received TalentSoft webhook body" ,
3542 extra = {"body" : body .decode (), "client_id" : client_id },
3643 )
3744 if not body :
38- return {"status" : "ok" }
45+ return _OK
46+
47+ payload = _parse_payload (body , client_id )
48+ if payload is None :
49+ return _OK
50+
51+ if should_archive (payload ):
52+ if archive_use_case is None :
53+ raise HTTPException (status_code = 500 , detail = "Web service not configured" )
54+ return await _handle_archive (payload , client_id , archive_use_case )
55+
56+ if should_load_offer_details (payload ):
57+ if load_offer_use_case is None :
58+ raise HTTPException (
59+ status_code = 500 , detail = "Talentsoft client not configured"
60+ )
61+ return await _handle_load_offer_details (payload , client_id , load_offer_use_case )
62+
63+ logger .info (
64+ "Unhandled event type %s for reference %s and status_id %s" ,
65+ payload .event_type ,
66+ payload .reference ,
67+ payload .status_id ,
68+ extra = {"client_id" : client_id },
69+ )
70+ return _OK
71+
3972
73+ def _parse_payload (body : bytes , client_id : str ) -> TalentsoftWebhookPayload | None :
4074 try :
41- payload = TalentsoftWebhookPayload .model_validate_json (body )
75+ return TalentsoftWebhookPayload .model_validate_json (body )
4276 except ValidationError :
4377 logger .warning (
4478 "Unrecognised TalentSoft webhook payload, ignoring" ,
4579 extra = {"body" : body .decode (), "client_id" : client_id },
4680 )
47- return {"status" : "ok" }
48-
49- if not should_archive (payload ):
50- logger .info (
51- "Unhandled event type %s for reference %s and status_id %s" ,
52- payload .event_type ,
53- payload .reference ,
54- payload .status_id ,
55- extra = {"client_id" : client_id },
56- )
57- return {"status" : "ok" }
81+ return None
82+
5883
84+ async def _handle_archive (
85+ payload : TalentsoftWebhookPayload ,
86+ client_id : str ,
87+ use_case : ArchiveOfferUseCase ,
88+ ) -> dict :
5989 # `source_id` will not be `client_id` soon
6090 # https://github.com/betagouv/csplab/issues/573 is required
6191 await use_case .execute (reference = payload .reference , source_id = client_id )
@@ -65,4 +95,19 @@ async def talentsoft_webhook(
6595 payload .reference ,
6696 extra = {"client_id" : client_id },
6797 )
68- return {"status" : "ok" }
98+ return _OK
99+
100+
101+ async def _handle_load_offer_details (
102+ payload : TalentsoftWebhookPayload ,
103+ client_id : str ,
104+ use_case : LoadOfferDetailsUseCase ,
105+ ) -> dict :
106+ await use_case .execute (reference = payload .reference )
107+ logger .info (
108+ "Handled event type %s for reference %s" ,
109+ payload .event_type ,
110+ payload .reference ,
111+ extra = {"client_id" : client_id },
112+ )
113+ return _OK
0 commit comments