refactor(events): populate object identifiers in outgoing webhooks analytics events during retries (#5067)

This commit is contained in:
Sanchith Hegde
2024-06-24 12:56:19 +05:30
committed by GitHub
parent 9caabeff86
commit b87840595d
13 changed files with 177 additions and 104 deletions

View File

@ -21,7 +21,9 @@ use crate::{
metrics,
},
db::StorageInterface,
events::outgoing_webhook_logs::{OutgoingWebhookEvent, OutgoingWebhookEventMetric},
events::outgoing_webhook_logs::{
OutgoingWebhookEvent, OutgoingWebhookEventContent, OutgoingWebhookEventMetric,
},
logger,
routes::{app::SessionStateInfo, SessionState},
services,
@ -29,6 +31,7 @@ use crate::{
api,
domain::{self, types as domain_types},
storage::{self, enums},
transformers::ForeignFrom,
},
utils::{OptionExt, ValueExt},
workflows::outgoing_webhook_retry,
@ -88,6 +91,8 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
.change_context(errors::ApiErrorResponse::WebhookProcessingFailure)
.attach_printable("Failed to construct outgoing webhook request content")?;
let event_metadata = storage::EventMetadata::foreign_from((&content, &primary_object_id));
let new_event = domain::Event {
event_id: event_id.clone(),
event_type,
@ -116,6 +121,7 @@ pub(crate) async fn create_event_and_trigger_outgoing_webhook(
),
response: None,
delivery_attempt: Some(delivery_attempt),
metadata: Some(event_metadata),
};
let event_insert_result = state
@ -440,7 +446,9 @@ fn raise_webhooks_analytics_event(
let outgoing_webhook_event_content = content
.as_ref()
.and_then(api::OutgoingWebhookContent::get_outgoing_webhook_event_content);
.and_then(api::OutgoingWebhookContent::get_outgoing_webhook_event_content)
.or_else(|| get_outgoing_webhook_event_content_from_event_metadata(event.metadata));
let webhook_event = OutgoingWebhookEvent::new(
merchant_id,
event.event_id,
@ -810,3 +818,76 @@ async fn error_response_handler(
Err(error)
}
impl ForeignFrom<(&api::OutgoingWebhookContent, &str)> for storage::EventMetadata {
fn foreign_from((content, primary_object_id): (&api::OutgoingWebhookContent, &str)) -> Self {
match content {
webhooks::OutgoingWebhookContent::PaymentDetails(payments_response) => Self::Payment {
payment_id: payments_response
.payment_id
.clone()
.unwrap_or_else(|| primary_object_id.to_owned()),
},
webhooks::OutgoingWebhookContent::RefundDetails(refund_response) => Self::Refund {
payment_id: refund_response.payment_id.clone(),
refund_id: refund_response.refund_id.clone(),
},
webhooks::OutgoingWebhookContent::DisputeDetails(dispute_response) => Self::Dispute {
payment_id: dispute_response.payment_id.clone(),
attempt_id: dispute_response.attempt_id.clone(),
dispute_id: dispute_response.dispute_id.clone(),
},
webhooks::OutgoingWebhookContent::MandateDetails(mandate_response) => Self::Mandate {
payment_method_id: mandate_response.payment_method_id.clone(),
mandate_id: mandate_response.mandate_id.clone(),
},
#[cfg(feature = "payouts")]
webhooks::OutgoingWebhookContent::PayoutDetails(payout_response) => Self::Payout {
payout_id: payout_response.payout_id.clone(),
},
}
}
}
fn get_outgoing_webhook_event_content_from_event_metadata(
event_metadata: Option<storage::EventMetadata>,
) -> Option<OutgoingWebhookEventContent> {
event_metadata.map(|metadata| match metadata {
diesel_models::EventMetadata::Payment { payment_id } => {
OutgoingWebhookEventContent::Payment {
payment_id: Some(payment_id),
content: serde_json::Value::Null,
}
}
diesel_models::EventMetadata::Payout { payout_id } => OutgoingWebhookEventContent::Payout {
payout_id,
content: serde_json::Value::Null,
},
diesel_models::EventMetadata::Refund {
payment_id,
refund_id,
} => OutgoingWebhookEventContent::Refund {
payment_id,
refund_id,
content: serde_json::Value::Null,
},
diesel_models::EventMetadata::Dispute {
payment_id,
attempt_id,
dispute_id,
} => OutgoingWebhookEventContent::Dispute {
payment_id,
attempt_id,
dispute_id,
content: serde_json::Value::Null,
},
diesel_models::EventMetadata::Mandate {
payment_method_id,
mandate_id,
} => OutgoingWebhookEventContent::Mandate {
payment_method_id,
mandate_id,
content: serde_json::Value::Null,
},
})
}