From a1c2790dc33dfb5903d300f922434c750e576798 Mon Sep 17 00:00:00 2001 From: Derich Pacheco Date: Mon, 16 Dec 2024 23:55:43 -0300 Subject: [PATCH 1/2] feat: impl broadcasts --- examples/api_keys.rb | 4 +- examples/broadcasts.rb | 34 +++++++++++ lib/resend/broadcasts.rb | 41 +++++++++++++ lib/resend/client.rb | 7 ++- spec/broadcasts_spec.rb | 129 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 examples/broadcasts.rb create mode 100644 lib/resend/broadcasts.rb create mode 100644 spec/broadcasts_spec.rb diff --git a/examples/api_keys.rb b/examples/api_keys.rb index 283ad78..c0ea37e 100644 --- a/examples/api_keys.rb +++ b/examples/api_keys.rb @@ -27,5 +27,5 @@ def remove end create -list -remove +# list +# remove diff --git a/examples/broadcasts.rb b/examples/broadcasts.rb new file mode 100644 index 0000000..b46d480 --- /dev/null +++ b/examples/broadcasts.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative "../lib/resend" + +raise if ENV["RESEND_API_KEY"].nil? + +Resend.api_key = ENV["RESEND_API_KEY"] + +params = { + from: "onboarding@resend.dev", + subject: "Hello", + audience_id: "78b8d3bc-a55a-45a3-aee6-6ec0a5e13d7e", + text: "Hello, how are you?", +} + +broadcast = Resend::Broadcasts.create(params) +puts "created broadcast: #{broadcast[:id]}" + +send_params = { + broadcast_id: broadcast[:id], + scheduled_at: "in 1 min", +} + +sent_broadcast = Resend::Broadcasts.send(send_params) +puts "sent broadcast: #{sent_broadcast[:id]}" + +broadcasts = Resend::Broadcasts.list +puts broadcasts + +retrieved = Resend::Broadcasts.get(broadcast[:id]) +puts "retrieved #{retrieved[:id]}" + +Resend::Broadcasts.remove(broadcast[:id]) +puts "removed #{broadcast[:id]}" \ No newline at end of file diff --git a/lib/resend/broadcasts.rb b/lib/resend/broadcasts.rb new file mode 100644 index 0000000..c6f5e62 --- /dev/null +++ b/lib/resend/broadcasts.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require "resend/request" +require "resend/errors" + +module Resend + # broadcasts api wrapper + module Broadcasts + class << self + # https://resend.com/docs/api-reference/broadcasts/create-broadcast + def create(params = {}) + path = "broadcasts" + Resend::Request.new(path, params, "post").perform + end + + # https://resend.com/docs/api-reference/broadcasts/send-broadcast + def send(params = {}) + path = "broadcasts/#{params[:broadcast_id]}/send" + Resend::Request.new(path, params, "post").perform + end + + # https://resend.com/docs/api-reference/broadcasts/list-broadcasts + def list + path = "broadcasts" + Resend::Request.new(path, {}, "get").perform + end + + # https://resend.com/docs/api-reference/broadcasts/delete-broadcast + def remove(broadcast_id = "") + path = "broadcasts/#{broadcast_id}" + Resend::Request.new(path, {}, "delete").perform + end + + # https://resend.com/docs/api-reference/broadcasts/get-broadcast + def get(broadcast_id = "") + path = "broadcasts/#{broadcast_id}" + Resend::Request.new(path, {}, "get").perform + end + end + end +end diff --git a/lib/resend/client.rb b/lib/resend/client.rb index 9351f5f..ccf9334 100644 --- a/lib/resend/client.rb +++ b/lib/resend/client.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true +require "resend/audiences" require "resend/api_keys" -require "resend/domains" -require "resend/emails" +require "resend/broadcasts" require "resend/batch" -require "resend/audiences" require "resend/contacts" +require "resend/domains" +require "resend/emails" require "httparty" module Resend diff --git a/spec/broadcasts_spec.rb b/spec/broadcasts_spec.rb new file mode 100644 index 0000000..e54814c --- /dev/null +++ b/spec/broadcasts_spec.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +RSpec.describe "Broadcasts" do + + before do + Resend.configure do |config| + config.api_key = "re_123" + end + end + + describe "create" do + it "should create broadcast" do + resp = { + "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794" + } + params = { + "audience_id": "123123" + } + allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) + expect(Resend::Broadcasts.create(params)[:id]).to eql("49a3999c-0ce1-4ea6-ab68-afcd6dc2e794") + end + end + + describe "send" do + it "should send broadcast" do + resp = { + "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794" + } + params = { + "broadcast_id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794", + "scheduled_at": "in 1 min" + } + allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) + expect(Resend::Broadcasts.send(params)[:id]).to eql("49a3999c-0ce1-4ea6-ab68-afcd6dc2e794") + end + end + + describe "list" do + it "should list broadcasts" do + resp = { + "object": "list", + "data": [ + { + "id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794", + "audience_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", + "status": "draft", + "created_at": "2024-11-01T15:13:31.723Z", + "scheduled_at": nil, + "sent_at": nil + }, + { + "id": "559ac32e-9ef5-46fb-82a1-b76b840c0f7b", + "audience_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", + "status": "sent", + "created_at": "2024-12-01T19:32:22.980Z", + "scheduled_at": "2024-12-02T19:32:22.980Z", + "sent_at": "2024-12-02T19:32:22.980Z" + } + ] + } + allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp) + + broadcasts = Resend::Broadcasts.list[:data] + + expect(broadcasts.length).to eql(2) + + expect(broadcasts[0][:id]).to eql("49a3999c-0ce1-4ea6-ab68-afcd6dc2e794") + expect(broadcasts[0][:audience_id]).to eql("78261eea-8f8b-4381-83c6-79fa7120f1cf") + expect(broadcasts[0][:status]).to eql("draft") + expect(broadcasts[0][:created_at]).to eql("2024-11-01T15:13:31.723Z") + expect(broadcasts[0][:scheduled_at]).to eql(nil) + expect(broadcasts[0][:sent_at]).to eql(nil) + + expect(broadcasts[1][:id]).to eql("559ac32e-9ef5-46fb-82a1-b76b840c0f7b") + expect(broadcasts[1][:audience_id]).to eql("78261eea-8f8b-4381-83c6-79fa7120f1cf") + expect(broadcasts[1][:status]).to eql("sent") + expect(broadcasts[1][:created_at]).to eql("2024-12-01T19:32:22.980Z") + expect(broadcasts[1][:scheduled_at]).to eql("2024-12-02T19:32:22.980Z") + expect(broadcasts[1][:sent_at]).to eql("2024-12-02T19:32:22.980Z") + end + end + + describe "remove" do + it "should remove broadcast" do + allow_any_instance_of(Resend::Request).to receive(:perform).and_return("") + expect { Resend::Broadcasts.remove }.not_to raise_error + end + end + + describe "get broadcast" do + + it "should retrieve a broadcast" do + + resp = { + "object": "broadcast", + "id": "559ac32e-9ef5-46fb-82a1-b76b840c0f7b", + "name": "Announcements", + "audience_id": "78261eea-8f8b-4381-83c6-79fa7120f1cf", + "from": "Acme ", + "subject": "hello world", + "reply_to": nil, + "preview_text": "Check out our latest announcements", + "status": "draft", + "created_at": "2024-12-01T19:32:22.980Z", + "scheduled_at": nil, + "sent_at": nil + } + + allow(resp).to receive(:body).and_return(resp) + allow(HTTParty).to receive(:send).and_return(resp) + + broadcast = Resend::Broadcasts.get("559ac32e-9ef5-46fb-82a1-b76b840c0f7b") + + expect(broadcast[:object]).to eql "broadcast" + expect(broadcast[:id]).to eql "559ac32e-9ef5-46fb-82a1-b76b840c0f7b" + expect(broadcast[:name]).to eql "Announcements" + expect(broadcast[:audience_id]).to eql "78261eea-8f8b-4381-83c6-79fa7120f1cf" + expect(broadcast[:from]).to eql "Acme " + expect(broadcast[:subject]).to eql "hello world" + expect(broadcast[:reply_to]).to eql nil + expect(broadcast[:preview_text]).to eql "Check out our latest announcements" + expect(broadcast[:status]).to eql "draft" + expect(broadcast[:created_at]).to eql "2024-12-01T19:32:22.980Z" + expect(broadcast[:scheduled_at]).to eql nil + expect(broadcast[:sent_at]).to eql nil + end + end + +end From 3e7719ebcdd21491b342f20be67effe718bef65f Mon Sep 17 00:00:00 2001 From: Derich Pacheco Date: Mon, 16 Dec 2024 23:56:53 -0300 Subject: [PATCH 2/2] doc: tweak --- examples/broadcasts.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/broadcasts.rb b/examples/broadcasts.rb index b46d480..7ba602a 100644 --- a/examples/broadcasts.rb +++ b/examples/broadcasts.rb @@ -9,7 +9,7 @@ params = { from: "onboarding@resend.dev", subject: "Hello", - audience_id: "78b8d3bc-a55a-45a3-aee6-6ec0a5e13d7e", + audience_id: "78b8d3bc-a55a-45a3-aee6-6ec0a5e13d7e", # replace with an existing audience id text: "Hello, how are you?", }