( toolName: string, response: Record<string, unknown>, requestIdempotencyKey: string | undefined, principal: string, )
| 125 | * idempotency cache uses (`scopedPrincipal(auth, accountScope)`), so both |
| 126 | * caches partition identically. */ |
| 127 | export function deriveWebhookOperationId( |
| 128 | toolName: string, |
| 129 | response: Record<string, unknown>, |
| 130 | requestIdempotencyKey: string | undefined, |
| 131 | principal: string, |
| 132 | ): string { |
| 133 | for (const field of ['media_buy_id', 'creative_id', 'activation_id', 'signal_activation_id', 'task_id', 'list_id', 'account_id']) { |
| 134 | const v = response[field]; |
| 135 | if (typeof v === 'string' && v.length > 0) return `${principal}|${toolName}.${v}`; |
| 136 | } |
| 137 | if (requestIdempotencyKey) return `${principal}|${toolName}.${requestIdempotencyKey}`; |
| 138 | return `${principal}|${toolName}.${randomUUID()}`; |
| 139 | } |
| 140 | |
| 141 | export function deriveRegisteredWebhookDeliveryOperationId( |
| 142 | toolName: string, |
no outgoing calls
no test coverage detected