mailkite 0.5.0 → 0.6.0
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/mailkite.rb +88 -6
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79f557c742e7377043c6fbbfc62c788bde380e6c75f647a354c4182346275a4d
|
|
4
|
+
data.tar.gz: be02421caccae364a81433fd239d043e19aeb546817c0acbf3c9727850894785
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94b4ec4ac99c756f5887d9f5526ac931df163675e0dcd7a460a9703847b253a5c2852d744f227704f847791bb183f6a1226178ee0714b26eb6fc4249d68a3e17
|
|
7
|
+
data.tar.gz: 501cce3bfee6edd4123a24f337325668e2a4009523814b5d3989fa197a4d4fc2185587dfd3bdf694f2ceed3ba0330e14ceeeac54f351f4f8e30c91b4310c7a97
|
data/lib/mailkite.rb
CHANGED
|
@@ -15,7 +15,7 @@ require "base64"
|
|
|
15
15
|
require "cgi"
|
|
16
16
|
|
|
17
17
|
module Mailkite
|
|
18
|
-
VERSION = "0.
|
|
18
|
+
VERSION = "0.6.0"
|
|
19
19
|
DEFAULT_BASE_URL = "https://api.mailkite.dev"
|
|
20
20
|
# Reject webhook events older than this (ms) to block replays. Pass 0 to disable.
|
|
21
21
|
DEFAULT_TOLERANCE_MS = 5 * 60 * 1000
|
|
@@ -165,6 +165,27 @@ module Mailkite
|
|
|
165
165
|
req.body = JSON.generate(body)
|
|
166
166
|
end
|
|
167
167
|
|
|
168
|
+
perform(req, uri)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Raw-binary request used by uploadAttachment for `bytes`/`path` uploads:
|
|
172
|
+
# the body is the file bytes themselves (not JSON, not multipart) and the
|
|
173
|
+
# Content-Type names the file's media type. Same auth + response parsing.
|
|
174
|
+
def request_binary(bytes, filename:, content_type:, retention_days: nil)
|
|
175
|
+
query = { "filename" => filename }
|
|
176
|
+
query["retentionDays"] = retention_days unless retention_days.nil?
|
|
177
|
+
qs = query.map { |k, v| "#{CGI.escape(k)}=#{CGI.escape(v.to_s)}" }.join("&")
|
|
178
|
+
uri = URI("#{@base_url}/v1/attachments?#{qs}")
|
|
179
|
+
req = Net::HTTP::Post.new(uri)
|
|
180
|
+
req["Authorization"] = "Bearer #{@api_key}"
|
|
181
|
+
req["Content-Type"] = content_type
|
|
182
|
+
req.body = bytes
|
|
183
|
+
perform(req, uri)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Send a prepared Net::HTTP request and parse the JSON response (shared by
|
|
187
|
+
# `request` and `request_binary`).
|
|
188
|
+
def perform(req, uri)
|
|
168
189
|
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == "https") { |http| http.request(req) }
|
|
169
190
|
text = res.body
|
|
170
191
|
data = text && !text.empty? ? JSON.parse(text) : nil
|
|
@@ -184,12 +205,73 @@ module Mailkite
|
|
|
184
205
|
request("POST", "/v1/send", message)
|
|
185
206
|
end
|
|
186
207
|
|
|
187
|
-
#
|
|
188
|
-
#
|
|
189
|
-
|
|
190
|
-
|
|
208
|
+
# Extension → MIME map for raw-binary attachment uploads (default
|
|
209
|
+
# application/octet-stream when an extension is unknown).
|
|
210
|
+
ATTACHMENT_MIME = {
|
|
211
|
+
"pdf" => "application/pdf",
|
|
212
|
+
"png" => "image/png",
|
|
213
|
+
"jpg" => "image/jpeg",
|
|
214
|
+
"jpeg" => "image/jpeg",
|
|
215
|
+
"gif" => "image/gif",
|
|
216
|
+
"webp" => "image/webp",
|
|
217
|
+
"svg" => "image/svg+xml",
|
|
218
|
+
"csv" => "text/csv",
|
|
219
|
+
"txt" => "text/plain",
|
|
220
|
+
"html" => "text/html",
|
|
221
|
+
"json" => "application/json",
|
|
222
|
+
"zip" => "application/zip",
|
|
223
|
+
"doc" => "application/msword",
|
|
224
|
+
"docx" => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
225
|
+
"xls" => "application/vnd.ms-excel",
|
|
226
|
+
"xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
227
|
+
"ics" => "text/calendar",
|
|
228
|
+
"ical" => "text/calendar",
|
|
229
|
+
}.freeze
|
|
230
|
+
|
|
231
|
+
# Upload a file and get back a secure, time-limited URL to reference as a
|
|
232
|
+
# send() attachment ({ filename, url }) or link inline — instead of
|
|
233
|
+
# base64-inlining large files on every send. Provide the file ONE of four
|
|
234
|
+
# ways via the `file` hash (priority order):
|
|
235
|
+
# 1. url — MailKite fetches & re-hosts the remote file
|
|
236
|
+
# 2. bytes — raw binary string, uploaded directly
|
|
237
|
+
# 3. path — local file read off disk, then uploaded as bytes
|
|
238
|
+
# 4. content — base64 string (the original behavior)
|
|
239
|
+
# Plus optional filename, contentType, and retentionDays.
|
|
191
240
|
def uploadAttachment(file)
|
|
192
|
-
|
|
241
|
+
url = file["url"] || file[:url]
|
|
242
|
+
bytes = file["bytes"] || file[:bytes]
|
|
243
|
+
path = file["path"] || file[:path]
|
|
244
|
+
content = file["content"] || file[:content]
|
|
245
|
+
filename = file["filename"] || file[:filename]
|
|
246
|
+
content_type = file["contentType"] || file[:contentType]
|
|
247
|
+
retention_days = file["retentionDays"] || file[:retentionDays]
|
|
248
|
+
|
|
249
|
+
if url
|
|
250
|
+
body = { "url" => url }
|
|
251
|
+
body["filename"] = filename unless filename.nil?
|
|
252
|
+
body["contentType"] = content_type unless content_type.nil?
|
|
253
|
+
body["retentionDays"] = retention_days unless retention_days.nil?
|
|
254
|
+
return request("POST", "/v1/attachments", body)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
if bytes || path
|
|
258
|
+
if path
|
|
259
|
+
bytes = File.binread(path)
|
|
260
|
+
filename ||= File.basename(path)
|
|
261
|
+
content_type ||= ATTACHMENT_MIME[File.extname(path).downcase.delete_prefix(".")]
|
|
262
|
+
end
|
|
263
|
+
content_type ||= "application/octet-stream"
|
|
264
|
+
return request_binary(bytes, filename: filename, content_type: content_type, retention_days: retention_days)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
if content
|
|
268
|
+
body = { "content" => content, "filename" => filename }
|
|
269
|
+
body["contentType"] = content_type unless content_type.nil?
|
|
270
|
+
body["retentionDays"] = retention_days unless retention_days.nil?
|
|
271
|
+
return request("POST", "/v1/attachments", body)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
raise ArgumentError, "uploadAttachment requires one of: path, bytes, url, or content"
|
|
193
275
|
end
|
|
194
276
|
|
|
195
277
|
# Run an inbound message through an AI agent. message keys: text (required),
|