render25 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/render25/client.rb +13 -0
- data/lib/render25/emails.rb +94 -0
- data/lib/render25/errors.rb +5 -0
- data/lib/render25/version.rb +3 -0
- data/lib/render25.rb +4 -107
- metadata +6 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d9904f85d22f8588d180067a8954b0e05907cac106a8d40b5c24c9c783cb7f6
|
|
4
|
+
data.tar.gz: 888c0cc3ed66c4cdca756b87c0510dcab73d278cc19be8c7d4cd9584f0fc7959
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e450d59bd45dab7a9788c99fa4ffb2216f872a8d3b2ed09e6b4d07104d41ee919a177448bcb4f46a4b81dff48bbfee0d2b04e096fdc9408770e89e3b3cef99f
|
|
7
|
+
data.tar.gz: e256ca03817a975d1b6eb593ce04b6a6e52614242d0e62a83e8911e20a412760d3fe90c6345f0258432aea1e740247204dcd554284ea9d8e39d5041d8cbb3dee
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Render25
|
|
2
|
+
class Client
|
|
3
|
+
attr_reader :api_key, :base_url, :emails
|
|
4
|
+
|
|
5
|
+
def initialize(api_key = nil, options = {})
|
|
6
|
+
@api_key = api_key || ENV['RENDER25_API_KEY']
|
|
7
|
+
raise AuthenticationError, "Render25: API Key is required. Pass it to Render25.new(api_key) or set RENDER25_API_KEY environment variable." if @api_key.nil? || @api_key.empty?
|
|
8
|
+
|
|
9
|
+
@base_url = (options[:base_url] || ENV['RENDER25_BASE_URL'] || "https://api.render25.com").sub(/\/+$/, '')
|
|
10
|
+
@emails = Emails.new(self)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
module Render25
|
|
7
|
+
class Emails
|
|
8
|
+
def initialize(client)
|
|
9
|
+
@client = client
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def send(options = {})
|
|
13
|
+
sender = options[:from] || options[:from_address]
|
|
14
|
+
raise ValidationError, "Render25: :from address is required" unless sender
|
|
15
|
+
|
|
16
|
+
to = options[:to]
|
|
17
|
+
raise ValidationError, "Render25: :to must contain at least one recipient" unless to
|
|
18
|
+
to = [to] if to.is_a?(String)
|
|
19
|
+
|
|
20
|
+
raise ValidationError, "Render25: :subject is required" unless options[:subject]
|
|
21
|
+
|
|
22
|
+
payload = {
|
|
23
|
+
from: sender,
|
|
24
|
+
to: to,
|
|
25
|
+
subject: options[:subject],
|
|
26
|
+
text: options[:text] || '',
|
|
27
|
+
html: options[:html] || ''
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if options[:cc]
|
|
31
|
+
payload[:cc] = options[:cc].is_a?(Array) ? options[:cc] : [options[:cc]]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if options[:bcc]
|
|
35
|
+
payload[:bcc] = options[:bcc].is_a?(Array) ? options[:bcc] : [options[:bcc]]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
reply_to = options[:reply_to] || options[:replyTo]
|
|
39
|
+
payload[:reply_to] = reply_to if reply_to
|
|
40
|
+
|
|
41
|
+
if options[:attachments] && options[:attachments].is_a?(Array)
|
|
42
|
+
payload[:attachments] = options[:attachments].map do |att|
|
|
43
|
+
filename = att[:filename] || 'attachment.bin'
|
|
44
|
+
content = att[:content]
|
|
45
|
+
content_type = att[:content_type] || att[:contentType] || 'application/octet-stream'
|
|
46
|
+
|
|
47
|
+
b64_content = if content.is_a?(String) && File.exist?(content)
|
|
48
|
+
Base64.strict_encode64(File.binread(content))
|
|
49
|
+
elsif content.is_a?(String)
|
|
50
|
+
begin
|
|
51
|
+
Base64.strict_decode64(content)
|
|
52
|
+
content
|
|
53
|
+
rescue
|
|
54
|
+
Base64.strict_encode64(content)
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
Base64.strict_encode64(content.to_s)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
{
|
|
61
|
+
filename: filename,
|
|
62
|
+
content: b64_content,
|
|
63
|
+
content_type: content_type
|
|
64
|
+
}
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
uri = URI.parse("#{@client.base_url}/api/send")
|
|
69
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
70
|
+
http.use_ssl = (uri.scheme == 'https')
|
|
71
|
+
http.open_timeout = 10
|
|
72
|
+
http.read_timeout = 30
|
|
73
|
+
|
|
74
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
|
75
|
+
request['Authorization'] = "Bearer #{@client.api_key}"
|
|
76
|
+
request['Content-Type'] = 'application/json'
|
|
77
|
+
request['User-Agent'] = "render25-ruby/#{Render25::VERSION}"
|
|
78
|
+
request.body = payload.to_json
|
|
79
|
+
|
|
80
|
+
begin
|
|
81
|
+
response = http.request(request)
|
|
82
|
+
parsed = JSON.parse(response.body) rescue { "error" => response.body }
|
|
83
|
+
|
|
84
|
+
if response.code.to_i >= 200 && response.code.to_i < 300
|
|
85
|
+
parsed
|
|
86
|
+
else
|
|
87
|
+
raise Error, "Render25 Error (#{response.code}): #{parsed['error'] || 'Unknown REST API error'}"
|
|
88
|
+
end
|
|
89
|
+
rescue StandardError => e
|
|
90
|
+
raise Error, "Render25 Error: #{e.message}"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
data/lib/render25.rb
CHANGED
|
@@ -1,113 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
require_relative 'render25/version'
|
|
2
|
+
require_relative 'render25/errors'
|
|
3
|
+
require_relative 'render25/emails'
|
|
4
|
+
require_relative 'render25/client'
|
|
5
5
|
|
|
6
6
|
module Render25
|
|
7
|
-
class Error < StandardError; end
|
|
8
|
-
|
|
9
7
|
def self.new(api_key = nil, options = {})
|
|
10
8
|
Client.new(api_key, options)
|
|
11
9
|
end
|
|
12
|
-
|
|
13
|
-
class Client
|
|
14
|
-
attr_reader :api_key, :base_url, :emails
|
|
15
|
-
|
|
16
|
-
def initialize(api_key = nil, options = {})
|
|
17
|
-
@api_key = api_key || ENV['RENDER25_API_KEY']
|
|
18
|
-
raise ArgumentError, "Render25: API Key is required. Pass it to Render25.new(api_key) or set RENDER25_API_KEY environment variable." if @api_key.nil? || @api_key.empty?
|
|
19
|
-
|
|
20
|
-
@base_url = (options[:base_url] || ENV['RENDER25_BASE_URL'] || "https://api.render25.com").sub(/\/+$/, '')
|
|
21
|
-
@emails = EmailsService.new(self)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
class EmailsService
|
|
26
|
-
def initialize(client)
|
|
27
|
-
@client = client
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def send(options = {})
|
|
31
|
-
sender = options[:from] || options[:from_address]
|
|
32
|
-
raise ArgumentError, "Render25: :from address is required" unless sender
|
|
33
|
-
|
|
34
|
-
to = options[:to]
|
|
35
|
-
raise ArgumentError, "Render25: :to must contain at least one recipient" unless to
|
|
36
|
-
to = [to] if to.is_a?(String)
|
|
37
|
-
|
|
38
|
-
raise ArgumentError, "Render25: :subject is required" unless options[:subject]
|
|
39
|
-
|
|
40
|
-
payload = {
|
|
41
|
-
from: sender,
|
|
42
|
-
to: to,
|
|
43
|
-
subject: options[:subject],
|
|
44
|
-
text: options[:text] || '',
|
|
45
|
-
html: options[:html] || ''
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if options[:cc]
|
|
49
|
-
payload[:cc] = options[:cc].is_a?(Array) ? options[:cc] : [options[:cc]]
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
if options[:bcc]
|
|
53
|
-
payload[:bcc] = options[:bcc].is_a?(Array) ? options[:bcc] : [options[:bcc]]
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
reply_to = options[:reply_to] || options[:replyTo]
|
|
57
|
-
payload[:reply_to] = reply_to if reply_to
|
|
58
|
-
|
|
59
|
-
if options[:attachments] && options[:attachments].is_a?(Array)
|
|
60
|
-
payload[:attachments] = options[:attachments].map do |att|
|
|
61
|
-
filename = att[:filename] || 'attachment.bin'
|
|
62
|
-
content = att[:content]
|
|
63
|
-
content_type = att[:content_type] || att[:contentType] || 'application/octet-stream'
|
|
64
|
-
|
|
65
|
-
b64_content = if content.is_a?(String) && File.exist?(content)
|
|
66
|
-
Base64.strict_encode64(File.binread(content))
|
|
67
|
-
elsif content.is_a?(String)
|
|
68
|
-
# If already base64 or plain string
|
|
69
|
-
begin
|
|
70
|
-
Base64.strict_decode64(content)
|
|
71
|
-
content
|
|
72
|
-
rescue
|
|
73
|
-
Base64.strict_encode64(content)
|
|
74
|
-
end
|
|
75
|
-
else
|
|
76
|
-
Base64.strict_encode64(content.to_s)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
{
|
|
80
|
-
filename: filename,
|
|
81
|
-
content: b64_content,
|
|
82
|
-
content_type: content_type
|
|
83
|
-
}
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
uri = URI.parse("#{@client.base_url}/api/send")
|
|
88
|
-
http = Net::HTTP.new(uri.host, uri.port)
|
|
89
|
-
http.use_ssl = (uri.scheme == 'https')
|
|
90
|
-
http.open_timeout = 10
|
|
91
|
-
http.read_timeout = 30
|
|
92
|
-
|
|
93
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
|
94
|
-
request['Authorization'] = "Bearer #{@client.api_key}"
|
|
95
|
-
request['Content-Type'] = 'application/json'
|
|
96
|
-
request['User-Agent'] = 'render25-ruby/1.0.0'
|
|
97
|
-
request.body = payload.to_json
|
|
98
|
-
|
|
99
|
-
begin
|
|
100
|
-
response = http.request(request)
|
|
101
|
-
parsed = JSON.parse(response.body) rescue { "error" => response.body }
|
|
102
|
-
|
|
103
|
-
if response.code.to_i >= 200 && response.code.to_i < 300
|
|
104
|
-
parsed
|
|
105
|
-
else
|
|
106
|
-
raise Error, "Render25 Error (#{response.code}): #{parsed['error'] || 'Unknown REST API error'}"
|
|
107
|
-
end
|
|
108
|
-
rescue StandardError => e
|
|
109
|
-
raise Error, "Render25 Error: #{e.message}"
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
10
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: render25
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Render25 Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Send high-deliverability transactional emails with Render25 using Ruby
|
|
14
14
|
and Ruby on Rails.
|
|
@@ -21,6 +21,10 @@ files:
|
|
|
21
21
|
- LICENSE
|
|
22
22
|
- README.md
|
|
23
23
|
- lib/render25.rb
|
|
24
|
+
- lib/render25/client.rb
|
|
25
|
+
- lib/render25/emails.rb
|
|
26
|
+
- lib/render25/errors.rb
|
|
27
|
+
- lib/render25/version.rb
|
|
24
28
|
homepage: https://render25.com
|
|
25
29
|
licenses:
|
|
26
30
|
- MIT
|