openemail 0.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 +7 -0
- data/README.md +183 -0
- data/lib/openemail/api_paths.rb +249 -0
- data/lib/openemail/client.rb +69 -0
- data/lib/openemail/constants.rb +851 -0
- data/lib/openemail/credentials.rb +53 -0
- data/lib/openemail/decode.rb +34 -0
- data/lib/openemail/defaults.rb +111 -0
- data/lib/openemail/endpoint.rb +144 -0
- data/lib/openemail/errors.rb +121 -0
- data/lib/openemail/http.rb +172 -0
- data/lib/openemail/languages.rb +42 -0
- data/lib/openemail/pagination.rb +63 -0
- data/lib/openemail/protocol.rb +169 -0
- data/lib/openemail/raw_body.rb +83 -0
- data/lib/openemail/request_path.rb +50 -0
- data/lib/openemail/resource.rb +70 -0
- data/lib/openemail/resources/account.rb +64 -0
- data/lib/openemail/resources/addresses.rb +38 -0
- data/lib/openemail/resources/analytics.rb +17 -0
- data/lib/openemail/resources/app_host.rb +23 -0
- data/lib/openemail/resources/audiences.rb +90 -0
- data/lib/openemail/resources/billing.rb +64 -0
- data/lib/openemail/resources/branding.rb +24 -0
- data/lib/openemail/resources/broadcasts.rb +65 -0
- data/lib/openemail/resources/calendar.rb +59 -0
- data/lib/openemail/resources/chats.rb +31 -0
- data/lib/openemail/resources/contacts.rb +111 -0
- data/lib/openemail/resources/dns_connections.rb +19 -0
- data/lib/openemail/resources/domains.rb +153 -0
- data/lib/openemail/resources/drafts.rb +35 -0
- data/lib/openemail/resources/emails.rb +100 -0
- data/lib/openemail/resources/encryption.rb +19 -0
- data/lib/openemail/resources/exports.rb +27 -0
- data/lib/openemail/resources/files.rb +95 -0
- data/lib/openemail/resources/forms.rb +111 -0
- data/lib/openemail/resources/imports.rb +86 -0
- data/lib/openemail/resources/keys.rb +127 -0
- data/lib/openemail/resources/labels.rb +39 -0
- data/lib/openemail/resources/languages.rb +11 -0
- data/lib/openemail/resources/me.rb +19 -0
- data/lib/openemail/resources/members.rb +74 -0
- data/lib/openemail/resources/provider_imports.rb +40 -0
- data/lib/openemail/resources/roles.rb +39 -0
- data/lib/openemail/resources/rules.rb +57 -0
- data/lib/openemail/resources/security.rb +19 -0
- data/lib/openemail/resources/senders.rb +15 -0
- data/lib/openemail/resources/settings.rb +16 -0
- data/lib/openemail/resources/subscriptions.rb +30 -0
- data/lib/openemail/resources/support.rb +11 -0
- data/lib/openemail/resources/suppressions.rb +31 -0
- data/lib/openemail/resources/temp_mail.rb +67 -0
- data/lib/openemail/resources/templates.rb +151 -0
- data/lib/openemail/resources/threads.rb +104 -0
- data/lib/openemail/resources/tools.rb +19 -0
- data/lib/openemail/resources/tracking.rb +63 -0
- data/lib/openemail/resources/webhooks.rb +142 -0
- data/lib/openemail/resources/workspaces.rb +28 -0
- data/lib/openemail/results.rb +33 -0
- data/lib/openemail/transport.rb +272 -0
- data/lib/openemail/update_notice.rb +69 -0
- data/lib/openemail/version.rb +5 -0
- data/lib/openemail/webhook.rb +82 -0
- data/lib/openemail/wire.rb +95 -0
- data/lib/openemail.rb +125 -0
- metadata +109 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenEmail
|
|
4
|
+
module Wire
|
|
5
|
+
RECIPIENT_FIELDS = %w[to cc bcc].freeze
|
|
6
|
+
BASE64_TEXT = %r{\A(?:[A-Za-z0-9+/_-]{4})*(?:[A-Za-z0-9+/_-]{2}==|[A-Za-z0-9+/_-]{3}=)?\z}
|
|
7
|
+
BASE64_WHITESPACE = " \t\n\f\r"
|
|
8
|
+
ISO_INSTANT = "%Y-%m-%dT%H:%M:%S.%LZ"
|
|
9
|
+
|
|
10
|
+
module_function
|
|
11
|
+
|
|
12
|
+
def body(value, fields)
|
|
13
|
+
base = value.nil? ? {} : hash_of(value)
|
|
14
|
+
base.merge(fields).transform_keys(&:to_s)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def hash_of(value)
|
|
18
|
+
return value if value.is_a?(Hash)
|
|
19
|
+
return value.to_hash if value.respond_to?(:to_hash)
|
|
20
|
+
|
|
21
|
+
raise ArgumentError, Defaults::MESSAGES[:BODY_SHAPE]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def email(body)
|
|
25
|
+
recipients(body).tap do |wire|
|
|
26
|
+
next unless wire.key?("attachments")
|
|
27
|
+
|
|
28
|
+
attachments = wire.delete("attachments")
|
|
29
|
+
wire["attachments"] = list(attachments).map { |attachment| attachment(attachment) } unless attachments.nil?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def recipients(body)
|
|
34
|
+
body.dup.tap do |wire|
|
|
35
|
+
RECIPIENT_FIELDS.each { |field| wire[field] = many(wire[field]) unless wire[field].nil? }
|
|
36
|
+
wire["scheduledAt"] = instant(wire["scheduledAt"]) if wire.key?("scheduledAt")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def many(value)
|
|
41
|
+
collection?(value) ? list(value) : [value]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def attachment(value)
|
|
45
|
+
entry = hash_of(value).transform_keys(&:to_s)
|
|
46
|
+
return {"fileId" => entry["fileId"]} if entry.key?("fileId")
|
|
47
|
+
|
|
48
|
+
wire = {"filename" => entry["filename"], "content" => content(entry["content"])}
|
|
49
|
+
wire["contentType"] = entry["contentType"] if entry.key?("contentType")
|
|
50
|
+
wire
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def content(value)
|
|
54
|
+
return [RawBody.read(value)].pack("m0") unless value.is_a?(String) && value.encoding != Encoding::BINARY
|
|
55
|
+
return value if BASE64_TEXT.match?(value.delete(BASE64_WHITESPACE))
|
|
56
|
+
|
|
57
|
+
raise ArgumentError, Defaults::MESSAGES[:ATTACHMENT_CONTENT_SHAPE]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def instant(value)
|
|
61
|
+
return value.getutc.strftime(ISO_INSTANT) if value.respond_to?(:getutc)
|
|
62
|
+
return value.new_offset(0).strftime(ISO_INSTANT) if value.is_a?(DateTime)
|
|
63
|
+
return value.iso8601 if value.is_a?(Date)
|
|
64
|
+
|
|
65
|
+
value
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def number(value)
|
|
69
|
+
return value if value.is_a?(Integer)
|
|
70
|
+
return value unless value.is_a?(Numeric) && value.finite?
|
|
71
|
+
|
|
72
|
+
(value == value.truncate) ? value.truncate : value.to_f
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def scalar(value)
|
|
76
|
+
number(instant(value))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def collection?(value)
|
|
80
|
+
value.is_a?(Array) || value.is_a?(Set)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def list(value)
|
|
84
|
+
collection?(value) ? value.to_a : value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def json_ready(value)
|
|
88
|
+
case value
|
|
89
|
+
when Hash then value.to_h { |key, item| [key, json_ready(item)] }
|
|
90
|
+
when Array, Set then value.map { |item| json_ready(item) }
|
|
91
|
+
else scalar(value)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
data/lib/openemail.rb
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ipaddr"
|
|
4
|
+
require "json"
|
|
5
|
+
require "net/http"
|
|
6
|
+
require "openssl"
|
|
7
|
+
require "pathname"
|
|
8
|
+
require "securerandom"
|
|
9
|
+
require "time"
|
|
10
|
+
require "uri"
|
|
11
|
+
|
|
12
|
+
require_relative "openemail/version"
|
|
13
|
+
require_relative "openemail/constants"
|
|
14
|
+
require_relative "openemail/protocol"
|
|
15
|
+
require_relative "openemail/api_paths"
|
|
16
|
+
require_relative "openemail/defaults"
|
|
17
|
+
require_relative "openemail/errors"
|
|
18
|
+
require_relative "openemail/credentials"
|
|
19
|
+
require_relative "openemail/endpoint"
|
|
20
|
+
require_relative "openemail/decode"
|
|
21
|
+
require_relative "openemail/request_path"
|
|
22
|
+
require_relative "openemail/raw_body"
|
|
23
|
+
require_relative "openemail/wire"
|
|
24
|
+
require_relative "openemail/http"
|
|
25
|
+
require_relative "openemail/update_notice"
|
|
26
|
+
require_relative "openemail/transport"
|
|
27
|
+
require_relative "openemail/results"
|
|
28
|
+
require_relative "openemail/pagination"
|
|
29
|
+
require_relative "openemail/webhook"
|
|
30
|
+
require_relative "openemail/languages"
|
|
31
|
+
require_relative "openemail/resource"
|
|
32
|
+
|
|
33
|
+
Dir[File.join(__dir__, "openemail", "resources", "*.rb")].sort.each { |path| require path }
|
|
34
|
+
|
|
35
|
+
require_relative "openemail/client"
|
|
36
|
+
|
|
37
|
+
module OpenEmail
|
|
38
|
+
@default_client = nil
|
|
39
|
+
@default_lock = Mutex.new
|
|
40
|
+
|
|
41
|
+
class << self
|
|
42
|
+
def new(...)
|
|
43
|
+
Client.new(...)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_client(key = nil, api_key: nil, access_token: nil, base_url: nil, **options)
|
|
47
|
+
raise ArgumentError, Defaults::MESSAGES[:KEY_TWICE] unless key.nil? || api_key.nil?
|
|
48
|
+
|
|
49
|
+
api_key = key if api_key.nil?
|
|
50
|
+
explicit = !api_key.nil? || !access_token.nil?
|
|
51
|
+
api_key = from_environment(Protocol::ENV_VARS[:API_KEY]) unless explicit
|
|
52
|
+
access_token = from_environment(Protocol::ENV_VARS[:ACCESS_TOKEN]) unless explicit || !api_key.nil?
|
|
53
|
+
base_url = Endpoint.normalise(base_url || from_environment(Protocol::ENV_VARS[:BASE_URL]))
|
|
54
|
+
|
|
55
|
+
Client.new(api_key:, access_token:, base_url:, **options)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def init(...)
|
|
59
|
+
created = create_client(...)
|
|
60
|
+
@default_lock.synchronize { @default_client = created }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def client
|
|
64
|
+
@default_lock.synchronize { @default_client ||= create_client }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def reset_client
|
|
68
|
+
@default_lock.synchronize { @default_client = nil }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def create_temp_mail(base_url: nil, inbox_token: nil, adapter: nil, max_retries: nil, timeout: nil, user_agent: nil,
|
|
72
|
+
headers: nil, disable_update_notice: false)
|
|
73
|
+
base_url = Endpoint.normalise(base_url || from_environment(Protocol::ENV_VARS[:BASE_URL]))
|
|
74
|
+
transport = Transport.new(base_url:, inbox_token:, adapter:, max_retries:, timeout:, user_agent:, headers:,
|
|
75
|
+
disable_update_notice:)
|
|
76
|
+
Resources::TempMail.new(transport)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def verify_webhook_signature(payload:, headers:, secret:, tolerance_seconds: nil)
|
|
80
|
+
Webhook.verify(payload:, headers:, secret:, tolerance_seconds:)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def to_base64(bytes)
|
|
84
|
+
[RawBody.read(bytes)].pack("m0")
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def api_key?(value)
|
|
88
|
+
Credentials.api_key?(value)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def access_token?(value)
|
|
92
|
+
Credentials.access_token?(value)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def sealed?(message)
|
|
96
|
+
encryption = message[:encryption] || message["encryption"]
|
|
97
|
+
return false unless encryption.is_a?(Hash)
|
|
98
|
+
|
|
99
|
+
Protocol::SEALED_ENCRYPTION_FORMATS.include?(encryption[:format] || encryption["format"])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def resolve_language(input)
|
|
103
|
+
Languages.resolve(input)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def language_by_code(code)
|
|
107
|
+
Languages.by_code(code)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def rtl_language?(code)
|
|
111
|
+
Languages.rtl?(code)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
Client::NAMESPACES.each_key do |name|
|
|
115
|
+
define_method(name) { client.public_send(name) }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
private
|
|
119
|
+
|
|
120
|
+
def from_environment(name)
|
|
121
|
+
value = ENV.fetch(name, nil)
|
|
122
|
+
(value.nil? || value.empty?) ? nil : value
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: openemail
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- OpenEmail
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Send email and broadcasts, work with threads, drafts, labels, templates,
|
|
13
|
+
rules, webhooks, tracking, contacts, audiences, sign-up forms, domains, suppressions,
|
|
14
|
+
files, API keys, roles, members, mailbox imports and disposable inboxes from Ruby.
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- README.md
|
|
20
|
+
- lib/openemail.rb
|
|
21
|
+
- lib/openemail/api_paths.rb
|
|
22
|
+
- lib/openemail/client.rb
|
|
23
|
+
- lib/openemail/constants.rb
|
|
24
|
+
- lib/openemail/credentials.rb
|
|
25
|
+
- lib/openemail/decode.rb
|
|
26
|
+
- lib/openemail/defaults.rb
|
|
27
|
+
- lib/openemail/endpoint.rb
|
|
28
|
+
- lib/openemail/errors.rb
|
|
29
|
+
- lib/openemail/http.rb
|
|
30
|
+
- lib/openemail/languages.rb
|
|
31
|
+
- lib/openemail/pagination.rb
|
|
32
|
+
- lib/openemail/protocol.rb
|
|
33
|
+
- lib/openemail/raw_body.rb
|
|
34
|
+
- lib/openemail/request_path.rb
|
|
35
|
+
- lib/openemail/resource.rb
|
|
36
|
+
- lib/openemail/resources/account.rb
|
|
37
|
+
- lib/openemail/resources/addresses.rb
|
|
38
|
+
- lib/openemail/resources/analytics.rb
|
|
39
|
+
- lib/openemail/resources/app_host.rb
|
|
40
|
+
- lib/openemail/resources/audiences.rb
|
|
41
|
+
- lib/openemail/resources/billing.rb
|
|
42
|
+
- lib/openemail/resources/branding.rb
|
|
43
|
+
- lib/openemail/resources/broadcasts.rb
|
|
44
|
+
- lib/openemail/resources/calendar.rb
|
|
45
|
+
- lib/openemail/resources/chats.rb
|
|
46
|
+
- lib/openemail/resources/contacts.rb
|
|
47
|
+
- lib/openemail/resources/dns_connections.rb
|
|
48
|
+
- lib/openemail/resources/domains.rb
|
|
49
|
+
- lib/openemail/resources/drafts.rb
|
|
50
|
+
- lib/openemail/resources/emails.rb
|
|
51
|
+
- lib/openemail/resources/encryption.rb
|
|
52
|
+
- lib/openemail/resources/exports.rb
|
|
53
|
+
- lib/openemail/resources/files.rb
|
|
54
|
+
- lib/openemail/resources/forms.rb
|
|
55
|
+
- lib/openemail/resources/imports.rb
|
|
56
|
+
- lib/openemail/resources/keys.rb
|
|
57
|
+
- lib/openemail/resources/labels.rb
|
|
58
|
+
- lib/openemail/resources/languages.rb
|
|
59
|
+
- lib/openemail/resources/me.rb
|
|
60
|
+
- lib/openemail/resources/members.rb
|
|
61
|
+
- lib/openemail/resources/provider_imports.rb
|
|
62
|
+
- lib/openemail/resources/roles.rb
|
|
63
|
+
- lib/openemail/resources/rules.rb
|
|
64
|
+
- lib/openemail/resources/security.rb
|
|
65
|
+
- lib/openemail/resources/senders.rb
|
|
66
|
+
- lib/openemail/resources/settings.rb
|
|
67
|
+
- lib/openemail/resources/subscriptions.rb
|
|
68
|
+
- lib/openemail/resources/support.rb
|
|
69
|
+
- lib/openemail/resources/suppressions.rb
|
|
70
|
+
- lib/openemail/resources/temp_mail.rb
|
|
71
|
+
- lib/openemail/resources/templates.rb
|
|
72
|
+
- lib/openemail/resources/threads.rb
|
|
73
|
+
- lib/openemail/resources/tools.rb
|
|
74
|
+
- lib/openemail/resources/tracking.rb
|
|
75
|
+
- lib/openemail/resources/webhooks.rb
|
|
76
|
+
- lib/openemail/resources/workspaces.rb
|
|
77
|
+
- lib/openemail/results.rb
|
|
78
|
+
- lib/openemail/transport.rb
|
|
79
|
+
- lib/openemail/update_notice.rb
|
|
80
|
+
- lib/openemail/version.rb
|
|
81
|
+
- lib/openemail/webhook.rb
|
|
82
|
+
- lib/openemail/wire.rb
|
|
83
|
+
homepage: https://openemail.uk
|
|
84
|
+
licenses:
|
|
85
|
+
- Nonstandard
|
|
86
|
+
metadata:
|
|
87
|
+
homepage_uri: https://openemail.uk
|
|
88
|
+
documentation_uri: https://openemail.uk/docs/ruby
|
|
89
|
+
changelog_uri: https://openemail.uk/docs/ruby/changelog
|
|
90
|
+
bug_tracker_uri: https://openemail.uk/contact
|
|
91
|
+
rubygems_mfa_required: 'true'
|
|
92
|
+
rdoc_options: []
|
|
93
|
+
require_paths:
|
|
94
|
+
- lib
|
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '3.2'
|
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
|
+
requirements:
|
|
102
|
+
- - ">="
|
|
103
|
+
- !ruby/object:Gem::Version
|
|
104
|
+
version: '0'
|
|
105
|
+
requirements: []
|
|
106
|
+
rubygems_version: 3.6.3
|
|
107
|
+
specification_version: 4
|
|
108
|
+
summary: The official Ruby SDK for the OpenEmail API.
|
|
109
|
+
test_files: []
|