From 8bba82696482f210badc14c9dc68ee149a6b5793 Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Thu, 3 Sep 2026 09:33:48 -0300 Subject: [PATCH 1/2] feat(webhooks): add event replay endpoint --- .rubocop.yml | 3 +++ examples/webhooks.rb | 4 ++++ lib/resend/webhooks.rb | 16 ++++++++++++++++ spec/webhooks_spec.rb | 16 ++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 8b577e6..51bc004 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -23,6 +23,9 @@ Layout/LineLength: Metrics/ClassLength: Max: 169 +Metrics/ModuleLength: + Max: 169 + Metrics/MethodLength: Max: 14 diff --git a/examples/webhooks.rb b/examples/webhooks.rb index 9ee3d21..a66a245 100644 --- a/examples/webhooks.rb +++ b/examples/webhooks.rb @@ -71,6 +71,10 @@ puts "\nWebhook event: #{webhook_event[:id]}" puts "Status: #{webhook_event[:status]}" + # Replay a webhook event + replayed_event = Resend::Webhooks.replay_event(webhook[:id], event_id) + puts "\nReplayed webhook event: #{replayed_event[:id]}" + # List delivery attempts for a webhook event attempts = Resend::Webhooks.list_event_attempts(webhook[:id], event_id, limit: 10) puts "\nDelivery attempts: #{attempts[:data].length}" diff --git a/lib/resend/webhooks.rb b/lib/resend/webhooks.rb index 150c6ab..30bd6b2 100644 --- a/lib/resend/webhooks.rb +++ b/lib/resend/webhooks.rb @@ -117,6 +117,22 @@ def get_event(webhook_id, event_id) Resend::Request.new(path, {}, "get").perform end + # Replay a webhook event + # + # Queues one more delivery of the event to the webhook. Manual replays do not schedule automatic retries. + # + # @param webhook_id [String] The webhook ID + # @param event_id [String] The webhook event ID + # + # @return [Hash] The replayed webhook event id and object type + # + # @example + # Resend::Webhooks.replay_event("4dd369bc-aa82-4ff3-97de-514ae3000ee0", "msg_123") + def replay_event(webhook_id, event_id) + path = "webhooks/#{webhook_id}/events/#{event_id}/replay" + Resend::Request.new(path, {}, "post").perform + end + # Retrieve delivery attempts for a webhook event # # @param webhook_id [String] The webhook ID diff --git a/spec/webhooks_spec.rb b/spec/webhooks_spec.rb index 6b656f6..45f2e7d 100644 --- a/spec/webhooks_spec.rb +++ b/spec/webhooks_spec.rb @@ -106,6 +106,22 @@ end end + describe "replay_event" do + it "replays a webhook event" do + resp = { "object": "webhook_event", "id": "msg_1srOrx2ZWZBpBUvZwXKQmoEYga2" } + request = instance_double(Resend::Request) + expect(Resend::Request).to receive(:new) + .with("webhooks/webhook_123/events/msg_1srOrx2ZWZBpBUvZwXKQmoEYga2/replay", {}, "post") + .and_return(request) + expect(request).to receive(:perform).and_return(resp) + + result = Resend::Webhooks.replay_event("webhook_123", "msg_1srOrx2ZWZBpBUvZwXKQmoEYga2") + + expect(result[:object]).to eql("webhook_event") + expect(result[:id]).to eql("msg_1srOrx2ZWZBpBUvZwXKQmoEYga2") + end + end + describe "list_event_attempts" do it "lists webhook event attempts with pagination" do request = instance_double(Resend::Request) From b3ed14bb1758745601216ff6cde6cb2d93fa9c44 Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Thu, 3 Sep 2026 09:37:21 -0300 Subject: [PATCH 2/2] test(webhooks): match get_event spec shape for replay_event --- spec/webhooks_spec.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/spec/webhooks_spec.rb b/spec/webhooks_spec.rb index 45f2e7d..0f47c32 100644 --- a/spec/webhooks_spec.rb +++ b/spec/webhooks_spec.rb @@ -108,17 +108,13 @@ describe "replay_event" do it "replays a webhook event" do - resp = { "object": "webhook_event", "id": "msg_1srOrx2ZWZBpBUvZwXKQmoEYga2" } request = instance_double(Resend::Request) expect(Resend::Request).to receive(:new) .with("webhooks/webhook_123/events/msg_1srOrx2ZWZBpBUvZwXKQmoEYga2/replay", {}, "post") .and_return(request) - expect(request).to receive(:perform).and_return(resp) - - result = Resend::Webhooks.replay_event("webhook_123", "msg_1srOrx2ZWZBpBUvZwXKQmoEYga2") + expect(request).to receive(:perform) - expect(result[:object]).to eql("webhook_event") - expect(result[:id]).to eql("msg_1srOrx2ZWZBpBUvZwXKQmoEYga2") + Resend::Webhooks.replay_event("webhook_123", "msg_1srOrx2ZWZBpBUvZwXKQmoEYga2") end end