Skip to content

Commit eadff5a

Browse files
authored
feat(logs): add logs API support (#162)
1 parent ea3e3eb commit eadff5a

5 files changed

Lines changed: 225 additions & 1 deletion

File tree

examples/logs.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "../lib/resend"
4+
5+
raise if ENV["RESEND_API_KEY"].nil?
6+
7+
Resend.api_key = ENV["RESEND_API_KEY"]
8+
9+
def get_log
10+
log = Resend::Logs.get("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
11+
puts log
12+
end
13+
14+
def list
15+
logs = Resend::Logs.list
16+
puts logs
17+
end
18+
19+
def list_paginated
20+
logs = Resend::Logs.list({ limit: 10, after: "log_id_here" })
21+
puts logs
22+
puts "Has more: #{logs[:has_more]}" if logs[:has_more]
23+
end
24+
25+
get_log
26+
list
27+
# list_paginated

lib/resend.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
require "resend/emails/receiving"
2929
require "resend/emails/attachments"
3030
require "resend/emails/receiving/attachments"
31+
require "resend/logs"
3132
require "resend/topics"
3233
require "resend/webhooks"
3334

lib/resend/logs.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
module Resend
4+
# logs api wrapper
5+
module Logs
6+
class << self
7+
# https://resend.com/docs/api-reference/logs/retrieve-log
8+
def get(log_id = "")
9+
path = "logs/#{log_id}"
10+
Resend::Request.new(path, {}, "get").perform
11+
end
12+
13+
# https://resend.com/docs/api-reference/logs/list-logs
14+
def list(params = {})
15+
path = Resend::PaginationHelper.build_paginated_path("logs", params)
16+
Resend::Request.new(path, {}, "get").perform
17+
end
18+
end
19+
end
20+
end

lib/resend/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Resend
4-
VERSION = "1.0.1"
4+
VERSION = "1.1.0"
55
end

spec/logs_spec.rb

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe "Logs" do
4+
context "static api_key" do
5+
before do
6+
Resend.configure do |config|
7+
config.api_key = "re_123"
8+
end
9+
end
10+
11+
describe "get" do
12+
it "should retrieve a log" do
13+
resp = {
14+
"object": "log",
15+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
16+
"created_at": "2024-11-01T18:10:00.000Z",
17+
"endpoint": "/emails",
18+
"method": "POST",
19+
"response_status": 200,
20+
"user_agent": "resend-ruby:1.0.0",
21+
"request_body": { "from": "user@example.com", "to": "recipient@example.com" },
22+
"response_body": { "id": "email_123" }
23+
}
24+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
25+
result = Resend::Logs.get("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
26+
expect(result[:id]).to eql("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
27+
expect(result[:object]).to eql("log")
28+
expect(result[:endpoint]).to eql("/emails")
29+
expect(result[:method]).to eql("POST")
30+
expect(result[:response_status]).to eql(200)
31+
end
32+
33+
it "should handle nullable user_agent" do
34+
resp = {
35+
"object": "log",
36+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
37+
"created_at": "2024-11-01T18:10:00.000Z",
38+
"endpoint": "/emails",
39+
"method": "POST",
40+
"response_status": 200,
41+
"user_agent": nil,
42+
"request_body": {},
43+
"response_body": {}
44+
}
45+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
46+
result = Resend::Logs.get("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
47+
expect(result[:user_agent]).to be_nil
48+
end
49+
50+
it "should raise when log is not found" do
51+
resp = {
52+
"statusCode" => 404,
53+
"name" => "not_found",
54+
"message" => "Log not found"
55+
}
56+
allow(resp).to receive(:body).and_return(resp)
57+
allow(HTTParty).to receive(:send).and_return(resp)
58+
expect { Resend::Logs.get("missing-id") }.to raise_error(Resend::Error::InvalidRequestError, /Log not found/)
59+
end
60+
61+
it "should raise when log_id is not a valid UUID" do
62+
resp = {
63+
"statusCode" => 422,
64+
"name" => "validation_error",
65+
"message" => "The `logId` must be a valid UUID."
66+
}
67+
allow(resp).to receive(:body).and_return(resp)
68+
allow(HTTParty).to receive(:send).and_return(resp)
69+
expect { Resend::Logs.get("not-a-uuid") }.to raise_error(Resend::Error::InvalidRequestError, /must be a valid UUID/)
70+
end
71+
end
72+
73+
describe "list" do
74+
it "should list logs" do
75+
resp = {
76+
"object": "list",
77+
"has_more": false,
78+
"data": [
79+
{
80+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
81+
"created_at": "2024-11-01T18:10:00.000Z",
82+
"endpoint": "/emails",
83+
"method": "POST",
84+
"response_status": 200,
85+
"user_agent": "resend-ruby:1.0.0"
86+
},
87+
{
88+
"id": "4e5b583e-cd7e-5ee3-bbae-e4e22c650f66",
89+
"created_at": "2024-11-01T17:00:00.000Z",
90+
"endpoint": "/emails",
91+
"method": "POST",
92+
"response_status": 422,
93+
"user_agent": nil
94+
}
95+
]
96+
}
97+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
98+
result = Resend::Logs.list
99+
expect(result[:data].length).to eql(2)
100+
expect(result[:has_more]).to eql(false)
101+
expect(result[:data].first[:id]).to eql("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
102+
expect(result[:data].last[:user_agent]).to be_nil
103+
end
104+
105+
it "should list logs with pagination params" do
106+
resp = {
107+
"object": "list",
108+
"has_more": true,
109+
"data": [
110+
{
111+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
112+
"created_at": "2024-11-01T18:10:00.000Z",
113+
"endpoint": "/emails",
114+
"method": "POST",
115+
"response_status": 200,
116+
"user_agent": "resend-ruby:1.0.0"
117+
}
118+
]
119+
}
120+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
121+
result = Resend::Logs.list({ limit: 1 })
122+
expect(result[:data].length).to eql(1)
123+
expect(result[:has_more]).to eql(true)
124+
end
125+
end
126+
end
127+
128+
context "dynamic api_key" do
129+
before do
130+
Resend.configure do |config|
131+
config.api_key = -> { "re_123" }
132+
end
133+
end
134+
135+
describe "get" do
136+
it "should retrieve a log" do
137+
resp = {
138+
"object": "log",
139+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
140+
"created_at": "2024-11-01T18:10:00.000Z",
141+
"endpoint": "/emails",
142+
"method": "POST",
143+
"response_status": 200,
144+
"user_agent": "resend-ruby:1.0.0",
145+
"request_body": {},
146+
"response_body": {}
147+
}
148+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
149+
result = Resend::Logs.get("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
150+
expect(result[:id]).to eql("3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55")
151+
end
152+
end
153+
154+
describe "list" do
155+
it "should list logs" do
156+
resp = {
157+
"object": "list",
158+
"has_more": false,
159+
"data": [
160+
{
161+
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d11b549e55",
162+
"created_at": "2024-11-01T18:10:00.000Z",
163+
"endpoint": "/emails",
164+
"method": "POST",
165+
"response_status": 200,
166+
"user_agent": "resend-ruby:1.0.0"
167+
}
168+
]
169+
}
170+
allow_any_instance_of(Resend::Request).to receive(:perform).and_return(resp)
171+
result = Resend::Logs.list
172+
expect(result[:data].length).to eql(1)
173+
end
174+
end
175+
end
176+
end

0 commit comments

Comments
 (0)