From bcc09785fd2a5ece1f3c63987a9addbd4d9cdb5e Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Fri, 14 Aug 2026 11:51:46 -0300 Subject: [PATCH 1/3] feat(automations): duplicate endpoint Co-Authored-By: Claude Fable 5 --- lib/resend/automations.rb | 5 +++++ spec/automations_spec.rb | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/lib/resend/automations.rb b/lib/resend/automations.rb index 00cdef6..16f235a 100644 --- a/lib/resend/automations.rb +++ b/lib/resend/automations.rb @@ -26,6 +26,11 @@ def remove(automation_id = "") Resend::Request.new("automations/#{automation_id}", {}, "delete").perform end + # https://resend.com/docs/api-reference/automations/duplicate-automation + def duplicate(automation_id = "") + Resend::Request.new("automations/#{automation_id}/duplicate", {}, "post").perform + end + # https://resend.com/docs/api-reference/automations/stop-automation def stop(automation_id = "") Resend::Request.new("automations/#{automation_id}/stop", {}, "post").perform diff --git a/spec/automations_spec.rb b/spec/automations_spec.rb index 872d059..81731ce 100644 --- a/spec/automations_spec.rb +++ b/spec/automations_spec.rb @@ -132,6 +132,26 @@ end end + describe "duplicate" do + it "should duplicate an automation" do + resp = { object: "automation", id: "e169aa45-1ecf-4183-9955-b1499d5701d3" } + allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) + result = Resend::Automations.duplicate(automation_id) + expect(result[:object]).to eql("automation") + expect(result[:id]).to eql("e169aa45-1ecf-4183-9955-b1499d5701d3") + end + + it "should use POST /automations/:id/duplicate" do + req = double("req", perform: { id: automation_id }) + expect(Resend::Request).to receive(:new).once do |path, _body, verb| + expect(path).to eql("automations/#{automation_id}/duplicate") + expect(verb).to eql("post") + req + end + Resend::Automations.duplicate(automation_id) + end + end + describe "stop" do it "should stop an automation" do resp = { object: "automation", id: automation_id, status: "disabled" } From d5fb34781fd89ebdfcb6980da9631356d1c96a3b Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Fri, 14 Aug 2026 12:24:58 -0300 Subject: [PATCH 2/3] remove should from tests Signed-off-by: Gabriel Miranda --- spec/automations_spec.rb | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spec/automations_spec.rb b/spec/automations_spec.rb index 81731ce..6e7a2d7 100644 --- a/spec/automations_spec.rb +++ b/spec/automations_spec.rb @@ -22,7 +22,7 @@ end describe "create" do - it "should create an automation" do + it "creates an automation" do resp = { object: "automation", id: automation_id @@ -34,7 +34,7 @@ expect(result[:object]).to eql("automation") end - it "should use POST /automations" do + it "uses POST /automations" do params = { name: "Welcome Automation", steps: steps, connections: connections } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| @@ -47,7 +47,7 @@ end describe "get" do - it "should retrieve an automation" do + it "retrieves an automation" do resp = { object: "automation", id: automation_id, @@ -69,7 +69,7 @@ expect(result[:status]).to eql("enabled") end - it "should use GET /automations/:id" do + it "uses GET /automations/:id" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}") @@ -81,7 +81,7 @@ end describe "update" do - it "should update an automation" do + it "updates an automation" do resp = { object: "automation", id: automation_id } params = { automation_id: automation_id, status: "enabled" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) @@ -89,7 +89,7 @@ expect(result[:id]).to eql(automation_id) end - it "should use PATCH /automations/:id" do + it "uses PATCH /automations/:id" do params = { automation_id: automation_id, status: "enabled" } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| @@ -100,7 +100,7 @@ Resend::Automations.update(params) end - it "should NOT include automation_id in the request body" do + it "does NOT include automation_id in the request body" do params = { automation_id: automation_id, name: "Updated Name" } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |_path, body, _verb| @@ -113,7 +113,7 @@ end describe "remove" do - it "should delete an automation" do + it "deletes an automation" do resp = { object: "automation", id: automation_id, deleted: true } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.remove(automation_id) @@ -121,7 +121,7 @@ expect(result[:deleted]).to eql(true) end - it "should use DELETE /automations/:id" do + it "uses DELETE /automations/:id" do req = double("req", perform: { id: automation_id, deleted: true }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}") @@ -133,7 +133,7 @@ end describe "duplicate" do - it "should duplicate an automation" do + it "duplicates an automation" do resp = { object: "automation", id: "e169aa45-1ecf-4183-9955-b1499d5701d3" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.duplicate(automation_id) @@ -141,7 +141,7 @@ expect(result[:id]).to eql("e169aa45-1ecf-4183-9955-b1499d5701d3") end - it "should use POST /automations/:id/duplicate" do + it "uses POST /automations/:id/duplicate" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/duplicate") @@ -153,7 +153,7 @@ end describe "stop" do - it "should stop an automation" do + it "stops an automation" do resp = { object: "automation", id: automation_id, status: "disabled" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.stop(automation_id) @@ -161,7 +161,7 @@ expect(result[:status]).to eql("disabled") end - it "should use POST /automations/:id/stop" do + it "uses POST /automations/:id/stop" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/stop") @@ -173,7 +173,7 @@ end describe "list" do - it "should list automations" do + it "lists automations" do resp = { object: "list", has_more: false, @@ -189,21 +189,21 @@ expect(result[:data].first["id"]).to eql(automation_id) end - it "should list automations with status filter" do + it "list automations with status filter" do resp = { object: "list", has_more: false, data: [{ "id" => automation_id, "status" => "enabled" }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.list({ status: "enabled" }) expect(result[:data].first["status"]).to eql("enabled") end - it "should list automations with pagination params" do + it "lists automations with pagination params" do resp = { object: "list", has_more: true, data: [{ "id" => automation_id }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.list({ limit: 1 }) expect(result[:has_more]).to eql(true) end - it "should use GET /automations" do + it "uses GET /automations" do req = double("req", perform: { object: "list", data: [], has_more: false }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations") @@ -215,12 +215,12 @@ end describe "Runs" do - it "should be accessible as Resend::Automations::Runs" do + it "is accessible as Resend::Automations::Runs" do expect(Resend::Automations::Runs).to be_a(Module) end describe "list" do - it "should list runs for an automation" do + it "lists runs for an automation" do resp = { object: "list", has_more: false, @@ -242,7 +242,7 @@ expect(result[:has_more]).to eql(false) end - it "should use GET /automations/:id/runs" do + it "uses GET /automations/:id/runs" do req = double("req", perform: { object: "list", data: [], has_more: false }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/runs") @@ -252,7 +252,7 @@ Resend::Automations::Runs.list(automation_id) end - it "should list runs with pagination params" do + it "lists runs with pagination params" do resp = { object: "list", has_more: true, data: [{ "id" => run_id }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations::Runs.list(automation_id, { limit: 1 }) @@ -261,7 +261,7 @@ end describe "get" do - it "should retrieve a specific run" do + it "retrieves a specific run" do resp = { object: "automation_run", id: run_id, @@ -278,7 +278,7 @@ expect(result[:status]).to eql("completed") end - it "should use GET /automations/:id/runs/:run_id" do + it "uses GET /automations/:id/runs/:run_id" do req = double("req", perform: { id: run_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/runs/#{run_id}") From f50619385703804b5f1b199ddf068c6bbb2fc88e Mon Sep 17 00:00:00 2001 From: Gabriel Miranda Date: Fri, 14 Aug 2026 12:25:33 -0300 Subject: [PATCH 3/3] Revert "remove should from tests" This reverts commit d5fb34781fd89ebdfcb6980da9631356d1c96a3b. --- spec/automations_spec.rb | 46 ++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spec/automations_spec.rb b/spec/automations_spec.rb index 6e7a2d7..81731ce 100644 --- a/spec/automations_spec.rb +++ b/spec/automations_spec.rb @@ -22,7 +22,7 @@ end describe "create" do - it "creates an automation" do + it "should create an automation" do resp = { object: "automation", id: automation_id @@ -34,7 +34,7 @@ expect(result[:object]).to eql("automation") end - it "uses POST /automations" do + it "should use POST /automations" do params = { name: "Welcome Automation", steps: steps, connections: connections } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| @@ -47,7 +47,7 @@ end describe "get" do - it "retrieves an automation" do + it "should retrieve an automation" do resp = { object: "automation", id: automation_id, @@ -69,7 +69,7 @@ expect(result[:status]).to eql("enabled") end - it "uses GET /automations/:id" do + it "should use GET /automations/:id" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}") @@ -81,7 +81,7 @@ end describe "update" do - it "updates an automation" do + it "should update an automation" do resp = { object: "automation", id: automation_id } params = { automation_id: automation_id, status: "enabled" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) @@ -89,7 +89,7 @@ expect(result[:id]).to eql(automation_id) end - it "uses PATCH /automations/:id" do + it "should use PATCH /automations/:id" do params = { automation_id: automation_id, status: "enabled" } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| @@ -100,7 +100,7 @@ Resend::Automations.update(params) end - it "does NOT include automation_id in the request body" do + it "should NOT include automation_id in the request body" do params = { automation_id: automation_id, name: "Updated Name" } req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |_path, body, _verb| @@ -113,7 +113,7 @@ end describe "remove" do - it "deletes an automation" do + it "should delete an automation" do resp = { object: "automation", id: automation_id, deleted: true } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.remove(automation_id) @@ -121,7 +121,7 @@ expect(result[:deleted]).to eql(true) end - it "uses DELETE /automations/:id" do + it "should use DELETE /automations/:id" do req = double("req", perform: { id: automation_id, deleted: true }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}") @@ -133,7 +133,7 @@ end describe "duplicate" do - it "duplicates an automation" do + it "should duplicate an automation" do resp = { object: "automation", id: "e169aa45-1ecf-4183-9955-b1499d5701d3" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.duplicate(automation_id) @@ -141,7 +141,7 @@ expect(result[:id]).to eql("e169aa45-1ecf-4183-9955-b1499d5701d3") end - it "uses POST /automations/:id/duplicate" do + it "should use POST /automations/:id/duplicate" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/duplicate") @@ -153,7 +153,7 @@ end describe "stop" do - it "stops an automation" do + it "should stop an automation" do resp = { object: "automation", id: automation_id, status: "disabled" } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.stop(automation_id) @@ -161,7 +161,7 @@ expect(result[:status]).to eql("disabled") end - it "uses POST /automations/:id/stop" do + it "should use POST /automations/:id/stop" do req = double("req", perform: { id: automation_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/stop") @@ -173,7 +173,7 @@ end describe "list" do - it "lists automations" do + it "should list automations" do resp = { object: "list", has_more: false, @@ -189,21 +189,21 @@ expect(result[:data].first["id"]).to eql(automation_id) end - it "list automations with status filter" do + it "should list automations with status filter" do resp = { object: "list", has_more: false, data: [{ "id" => automation_id, "status" => "enabled" }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.list({ status: "enabled" }) expect(result[:data].first["status"]).to eql("enabled") end - it "lists automations with pagination params" do + it "should list automations with pagination params" do resp = { object: "list", has_more: true, data: [{ "id" => automation_id }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations.list({ limit: 1 }) expect(result[:has_more]).to eql(true) end - it "uses GET /automations" do + it "should use GET /automations" do req = double("req", perform: { object: "list", data: [], has_more: false }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations") @@ -215,12 +215,12 @@ end describe "Runs" do - it "is accessible as Resend::Automations::Runs" do + it "should be accessible as Resend::Automations::Runs" do expect(Resend::Automations::Runs).to be_a(Module) end describe "list" do - it "lists runs for an automation" do + it "should list runs for an automation" do resp = { object: "list", has_more: false, @@ -242,7 +242,7 @@ expect(result[:has_more]).to eql(false) end - it "uses GET /automations/:id/runs" do + it "should use GET /automations/:id/runs" do req = double("req", perform: { object: "list", data: [], has_more: false }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/runs") @@ -252,7 +252,7 @@ Resend::Automations::Runs.list(automation_id) end - it "lists runs with pagination params" do + it "should list runs with pagination params" do resp = { object: "list", has_more: true, data: [{ "id" => run_id }] } allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) result = Resend::Automations::Runs.list(automation_id, { limit: 1 }) @@ -261,7 +261,7 @@ end describe "get" do - it "retrieves a specific run" do + it "should retrieve a specific run" do resp = { object: "automation_run", id: run_id, @@ -278,7 +278,7 @@ expect(result[:status]).to eql("completed") end - it "uses GET /automations/:id/runs/:run_id" do + it "should use GET /automations/:id/runs/:run_id" do req = double("req", perform: { id: run_id }) expect(Resend::Request).to receive(:new).once do |path, _body, verb| expect(path).to eql("automations/#{automation_id}/runs/#{run_id}")