openemail 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b529e237ea6cc98204574ecf5b0b0b58fb7e774cd18ed07ac265ec243885fe1c
4
- data.tar.gz: 26844441518ca76d25b0908248924119c0528f56bf874b919c6f4a8dd1942e2d
3
+ metadata.gz: 4cff89372bfc6111e224def38735f3bdbffe7464c09604265592ee363f06d0e2
4
+ data.tar.gz: 217b4a0639e711d2ad12ba39d3ccbf1324d484089cc15479be886cf772373f02
5
5
  SHA512:
6
- metadata.gz: b6236ffe92657e77e6478042d728023a16826bbc194b70178d7cdb809815ef577bae64b62d1ada664760ad4f0a3771a04a2b993254a43bccceb9db541680c9bd
7
- data.tar.gz: 871936c1946ea670dd8728a4651295114be58d11328307ba9bc298eb9b6c556793cb8112d932fe3a0958eb429f0c38721cd7072cc35fb8e2cf7d0f36fc033f47
6
+ metadata.gz: bd52a785df4468aff82d1248a975144ebbb54031a22da26eee5666c971e821e7247c8b2079fe8fc7198726c5d9f24eb2b2255b432f060ef8429a277d7136f89d
7
+ data.tar.gz: 4c4ea067759e4cea3d00cbf5abc446e42f9af217ec7753d35909bb5dbe4e688a83c1e959b37f7c8a12e2377f09474ed800d8ab617210f1f71b6d08881b7e9a2c
@@ -53,8 +53,15 @@ module OpenEmail
53
53
  CALENDAR_EVENT = "/calendar/events/:id"
54
54
  CALENDAR_EVENTS = "/calendar/events"
55
55
  CALENDAR_EVENT_CANCEL = "/calendar/events/:id/cancel"
56
+ CALENDAR_EVENT_DECLINE_PROPOSAL = "/calendar/events/:id/decline-proposal"
56
57
  CALENDAR_EVENT_ICS = "/calendar/events/:id/ics"
57
58
  CALENDAR_EVENT_RESPOND = "/calendar/events/:id/respond"
59
+ CALENDAR_FEED = "/calendar/feeds/:id"
60
+ CALENDAR_FEEDS = "/calendar/feeds"
61
+ CALENDAR_FEED_RESET = "/calendar/feeds/:id/reset"
62
+ CALENDAR_SUBSCRIPTION = "/calendar/subscriptions/:id"
63
+ CALENDAR_SUBSCRIPTIONS = "/calendar/subscriptions"
64
+ CALENDAR_SUBSCRIPTION_REFRESH = "/calendar/subscriptions/:id/refresh"
58
65
  CHAT = "/chats/:id"
59
66
  CHATS = "/chats"
60
67
  CONTACT = "/contacts/:email"
@@ -64,6 +71,8 @@ module OpenEmail
64
71
  CONTACT_ACTIVITY = "/contacts/:email/activity"
65
72
  CONTACT_AUDIENCES = "/contacts/:email/audiences"
66
73
  CONTACT_BLOCK = "/contacts/:email/block"
74
+ CONTACT_CARD = "/contacts/cards/:id"
75
+ CONTACT_CARDS = "/contacts/cards"
67
76
  CONTACT_PHOTO = "/contacts/:email/photo"
68
77
  CONTACT_THREADS = "/contacts/:email/threads"
69
78
  DNS_CONNECTION = "/dns-connections/:id"
@@ -72,10 +81,14 @@ module OpenEmail
72
81
  DOMAINS = "/domains"
73
82
  DOMAIN_ADDRESS = "/domains/:id/addresses/:addressId"
74
83
  DOMAIN_ADDRESSES = "/domains/:id/addresses"
84
+ DOMAIN_ADDRESS_APP_PASSWORD = "/domains/:id/addresses/:addressId/app-passwords/:passwordId"
85
+ DOMAIN_ADDRESS_APP_PASSWORDS = "/domains/:id/addresses/:addressId/app-passwords"
75
86
  DOMAIN_ADDRESS_FORWARD = "/domains/:id/addresses/:addressId/forwards/:forwardId"
76
87
  DOMAIN_ADDRESS_FORWARDS = "/domains/:id/addresses/:addressId/forwards"
77
88
  DOMAIN_ADDRESS_FORWARD_RESEND = "/domains/:id/addresses/:addressId/forwards/:forwardId/resend"
78
89
  DOMAIN_ADDRESS_LOGIN = "/domains/:id/addresses/:addressId/login"
90
+ DOMAIN_ADDRESS_MAIL_APPS = "/domains/:id/addresses/:addressId/mail-apps"
91
+ DOMAIN_ADDRESS_MAIL_APP_SETUP = "/domains/:id/addresses/:addressId/mail-app-setup"
79
92
  DOMAIN_ADDRESS_MEMBERS = "/domains/:id/addresses/:addressId/members"
80
93
  DOMAIN_ADDRESS_PHOTO = "/domains/:id/addresses/:addressId/photo"
81
94
  DOMAIN_DNS = "/domains/:id/dns"
@@ -139,6 +152,25 @@ module OpenEmail
139
152
  KEY_ROTATE = "/keys/:id/rotate"
140
153
  KEY_SELF = "/keys/self"
141
154
  KEY_SELF_ROTATE = "/keys/self/rotate"
155
+ KNOWLEDGE = "/knowledge"
156
+ KNOWLEDGE_CONNECTOR = "/knowledge/connectors/:id"
157
+ KNOWLEDGE_CONNECTORS = "/knowledge/connectors"
158
+ KNOWLEDGE_CONNECTOR_SYNC = "/knowledge/connectors/:id/sync"
159
+ KNOWLEDGE_DRAFTS = "/knowledge/drafts"
160
+ KNOWLEDGE_FILES = "/knowledge/files"
161
+ KNOWLEDGE_FLAGS = "/knowledge/flags"
162
+ KNOWLEDGE_FLAG_DISMISS = "/knowledge/flags/:id/dismiss"
163
+ KNOWLEDGE_ITEM = "/knowledge/:id"
164
+ KNOWLEDGE_ITEM_REFRESH = "/knowledge/:id/refresh"
165
+ KNOWLEDGE_LEVELS = "/knowledge/levels"
166
+ KNOWLEDGE_LINKS = "/knowledge/links"
167
+ KNOWLEDGE_NOTES = "/knowledge/notes"
168
+ KNOWLEDGE_SEARCH = "/knowledge/search"
169
+ KNOWLEDGE_STATS = "/knowledge/stats"
170
+ KNOWLEDGE_SUGGESTIONS = "/knowledge/suggestions"
171
+ KNOWLEDGE_SUGGESTION_ACCEPT = "/knowledge/suggestions/:id/accept"
172
+ KNOWLEDGE_SUGGESTION_DISMISS = "/knowledge/suggestions/:id/dismiss"
173
+ KNOWLEDGE_USAGE = "/knowledge/usage"
142
174
  LABEL = "/labels/:id"
143
175
  LABELS = "/labels"
144
176
  LABEL_COLORS = "/labels/colors"
@@ -216,6 +248,7 @@ module OpenEmail
216
248
  THREAD_NOTE = "/threads/:id/notes/:noteId"
217
249
  THREAD_NOTES = "/threads/:id/notes"
218
250
  THREAD_NOTES_REORDER = "/threads/:id/notes/reorder"
251
+ THREAD_REPLY_SUGGESTIONS = "/threads/:id/reply-suggestions"
219
252
  THREAD_RESTORE = "/threads/:id/restore"
220
253
  THREAD_SNOOZE = "/threads/:id/snooze"
221
254
  THREAD_SUMMARY = "/threads/:id/summary"
@@ -223,8 +256,10 @@ module OpenEmail
223
256
  THREAD_UNSNOOZE = "/threads/:id/unsnooze"
224
257
  THREAD_UNSUBSCRIBE = "/threads/:id/unsubscribe"
225
258
  TOOLS_BIMI = "/tools/bimi"
259
+ TOOLS_COST = "/tools/cost"
226
260
  TOOLS_DELIVERABILITY = "/tools/deliverability"
227
261
  TOOLS_DMARC = "/tools/dmarc"
262
+ TOOLS_VERIFICATION_CODE = "/tools/verification-code"
228
263
  TRACKED = "/tracking/:id"
229
264
  TRACKED_CLICKS = "/tracking/:id/clicks"
230
265
  TRACKED_OPENS = "/tracking/:id/opens"
@@ -32,6 +32,7 @@ module OpenEmail
32
32
  members: Resources::Members,
33
33
  suppressions: Resources::Suppressions,
34
34
  files: Resources::Files,
35
+ knowledge: Resources::Knowledge,
35
36
  temp_mail: Resources::TempMail,
36
37
  exports: Resources::Exports,
37
38
  chats: Resources::Chats,
@@ -55,6 +55,8 @@ module OpenEmail
55
55
  KEYS_MANAGE: "keys:manage",
56
56
  FORMS_READ: "forms:read",
57
57
  FORMS_WRITE: "forms:write",
58
+ KNOWLEDGE_READ: "knowledge:read",
59
+ KNOWLEDGE_WRITE: "knowledge:write",
58
60
  BILLING_READ: "billing:read",
59
61
  BILLING_WRITE: "billing:write",
60
62
  ACCOUNT_READ: "account:read",
@@ -63,6 +65,8 @@ module OpenEmail
63
65
 
64
66
  APP_HOST_STATUSES = {NONE: "none", PENDING: "pending", ACTIVE: "active", FAILED: "failed"}.freeze
65
67
 
68
+ APP_PASSWORD_ORIGINS = {SETTINGS: "settings", SETUP_LINK: "setup-link", API: "api"}.freeze
69
+
66
70
  AUDIENCE_MEMBER_STATUSES = {SUBSCRIBED: "subscribed", UNSUBSCRIBED: "unsubscribed"}.freeze
67
71
 
68
72
  BILLING_ALERT_KINDS = {
@@ -168,10 +172,35 @@ module OpenEmail
168
172
  FAILED: "failed"
169
173
  }.freeze
170
174
 
175
+ CALENDAR_COLORS = {
176
+ BLUE: "blue",
177
+ SKY: "sky",
178
+ TEAL: "teal",
179
+ GREEN: "green",
180
+ LIME: "lime",
181
+ YELLOW: "yellow",
182
+ ORANGE: "orange",
183
+ RED: "red",
184
+ PINK: "pink",
185
+ PURPLE: "purple",
186
+ GRAY: "gray"
187
+ }.freeze
188
+
189
+ CALENDAR_FEED_MODES = {FULL: "full", BUSY: "busy"}.freeze
190
+
171
191
  CALENDAR_REMINDER_ACTIONS = {DISPLAY: "DISPLAY", EMAIL: "EMAIL", AUDIO: "AUDIO"}.freeze
172
192
 
173
193
  CALENDAR_RESPONSES = {ACCEPTED: "ACCEPTED", DECLINED: "DECLINED", TENTATIVE: "TENTATIVE"}.freeze
174
194
 
195
+ CALENDAR_SUBSCRIPTION_ERRORS = {
196
+ UNREACHABLE: "unreachable",
197
+ TOO_LARGE: "too-large",
198
+ NOT_A_CALENDAR: "not-a-calendar",
199
+ TOO_MANY_EVENTS: "too-many-events"
200
+ }.freeze
201
+
202
+ CALENDAR_SUBSCRIPTION_STATUSES = {ACTIVE: "active", FAILING: "failing", STOPPED: "stopped"}.freeze
203
+
175
204
  CALENDAR_TRANSPARENCIES = {OPAQUE: "OPAQUE", TRANSPARENT: "TRANSPARENT"}.freeze
176
205
 
177
206
  CALENDAR_VISIBILITIES = {PUBLIC: "PUBLIC", PRIVATE: "PRIVATE", CONFIDENTIAL: "CONFIDENTIAL"}.freeze
@@ -198,8 +227,20 @@ module OpenEmail
198
227
 
199
228
  CONTACT_BLOCK_LISTS = {BLOCKED_SENDERS: "blockedSenders", BLOCKED_DOMAINS: "blockedDomains"}.freeze
200
229
 
230
+ CONTACT_CARD_LABELS = {
231
+ HOME: "home",
232
+ WORK: "work",
233
+ MOBILE: "mobile",
234
+ MAIN: "main",
235
+ FAX: "fax",
236
+ PAGER: "pager",
237
+ OTHER: "other"
238
+ }.freeze
239
+
201
240
  CONTACT_PHOTO_TYPES = {PNG: "image/png", JPEG: "image/jpeg", WEBP: "image/webp", GIF: "image/gif"}.freeze
202
241
 
242
+ CONTACT_SOURCES = {MANUAL: "manual", AUTO: "auto", FORM: "form"}.freeze
243
+
203
244
  CONTACT_THREAD_SORTS = {NEWEST: "newest", OLDEST: "oldest", SENDER: "sender", SUBJECT: "subject"}.freeze
204
245
 
205
246
  CREDENTIAL_KINDS = {API_KEY: "apiKey", OAUTH: "oauth"}.freeze
@@ -365,6 +406,49 @@ module OpenEmail
365
406
 
366
407
  FORM_WIDTHS = {NARROW: "narrow", NORMAL: "normal", WIDE: "wide"}.freeze
367
408
 
409
+ IMPORT_FORMATS = {
410
+ GMAIL: "gmail",
411
+ OPENEMAIL: "openemail",
412
+ THUNDERBIRD: "thunderbird",
413
+ PROTON: "proton",
414
+ MBOX: "mbox",
415
+ EML: "eml"
416
+ }.freeze
417
+
418
+ KNOWLEDGE_CONNECTOR_KINDS = {SITE: "site", SITEMAP: "sitemap", FEED: "feed", ZENDESK: "zendesk"}.freeze
419
+
420
+ KNOWLEDGE_CONNECTOR_STATUSES = {QUEUED: "queued", SYNCING: "syncing", READY: "ready", FAILED: "failed"}.freeze
421
+
422
+ KNOWLEDGE_FAILURES = {
423
+ UNSUPPORTED: "unsupported",
424
+ EMPTY: "empty",
425
+ TOO_LARGE: "too_large",
426
+ FETCH_FAILED: "fetch_failed",
427
+ BLOCKED_URL: "blocked_url",
428
+ CONVERSION_FAILED: "conversion_failed",
429
+ INDEX_FAILED: "index_failed",
430
+ OVER_ALLOWANCE: "over_allowance",
431
+ MISSING_FILE: "missing_file"
432
+ }.freeze
433
+
434
+ KNOWLEDGE_FLAG_KINDS = {DUPLICATE: "duplicate", CONFLICT: "conflict"}.freeze
435
+
436
+ KNOWLEDGE_FLAG_STATUSES = {OPEN: "open", DISMISSED: "dismissed"}.freeze
437
+
438
+ KNOWLEDGE_KINDS = {NOTE: "note", FILE: "file", LINK: "link"}.freeze
439
+
440
+ KNOWLEDGE_LEVELS = {WORKSPACE: "workspace", DOMAIN: "domain", ADDRESS: "address"}.freeze
441
+
442
+ KNOWLEDGE_ORIGINS = {APP: "app", API: "api", ASSISTANT: "assistant", MCP: "mcp"}.freeze
443
+
444
+ KNOWLEDGE_REFRESH_DAY_CHOICES = {DAY: 1, WEEK: 7, MONTH: 30}.freeze
445
+
446
+ KNOWLEDGE_STATUSES = {QUEUED: "queued", PROCESSING: "processing", READY: "ready", FAILED: "failed"}.freeze
447
+
448
+ KNOWLEDGE_SUGGESTION_KINDS = {LEARNED: "learned", QUESTION: "question"}.freeze
449
+
450
+ KNOWLEDGE_SUGGESTION_STATUSES = {PENDING: "pending", ACCEPTED: "accepted", DISMISSED: "dismissed"}.freeze
451
+
368
452
  LANGUAGES = [
369
453
  {code: "en", label: "English", native: "English", flag: "🇬🇧", rtl: false}.freeze,
370
454
  {code: "es", label: "Spanish", native: "Español", flag: "🇪🇸", rtl: false}.freeze,
@@ -652,6 +736,30 @@ module OpenEmail
652
736
 
653
737
  LOGIN_LOGOS = {DARK: "dark", LIGHT: "light"}.freeze
654
738
 
739
+ MAIL_APP_PROTOCOLS = {IMAP: "imap", SMTP: "smtp", POP3: "pop3", CALDAV: "caldav", CARDDAV: "carddav"}.freeze
740
+
741
+ MAIL_APP_SECURITIES = {SSL_TLS: "ssl-tls"}.freeze
742
+
743
+ MAIL_SERVICES = {
744
+ OPENEMAIL: "openemail",
745
+ GMAIL: "gmail",
746
+ OUTLOOK: "outlook",
747
+ ICLOUD: "icloud",
748
+ YAHOO: "yahoo",
749
+ PROTON: "proton",
750
+ ZOHO: "zoho",
751
+ FASTMAIL: "fastmail",
752
+ RESEND: "resend",
753
+ SENDGRID: "sendgrid",
754
+ MAILGUN: "mailgun",
755
+ POSTMARK: "postmark",
756
+ MAILCHIMP: "mailchimp",
757
+ BREVO: "brevo",
758
+ SPARKPOST: "sparkpost",
759
+ HUBSPOT: "hubspot",
760
+ AMAZON_SES: "amazon-ses"
761
+ }.freeze
762
+
655
763
  MESSAGE_ENCRYPTION_FORMATS = {
656
764
  PGP_MIME: "pgp-mime",
657
765
  PGP_SIGNED: "pgp-signed",
@@ -668,10 +776,20 @@ module OpenEmail
668
776
 
669
777
  PEOPLE_SORTS = {RECENT: "recent", NAME: "name", THREADS: "threads"}.freeze
670
778
 
779
+ PLAN_BLOCKERS = {DOMAINS: "domains", PEOPLE: "people", SENDS: "sends"}.freeze
780
+
671
781
  PLAN_IDS = {FREE: "free", STARTER: "starter", BUSINESS: "business", ENTERPRISE: "enterprise"}.freeze
672
782
 
673
783
  PROVIDER_IMPORT_DOMAIN_STATES = {ABSENT: "absent", ADDED: "added", VERIFIED: "verified"}.freeze
674
784
 
785
+ PROVIDER_IMPORT_PROVIDERS = {
786
+ RESEND: "resend",
787
+ SENDGRID: "sendgrid",
788
+ POSTMARK: "postmark",
789
+ MAILGUN: "mailgun",
790
+ MAILCHIMP: "mailchimp"
791
+ }.freeze
792
+
675
793
  PROVIDER_IMPORT_RESOURCES = {
676
794
  SUPPRESSIONS: "suppressions",
677
795
  AUDIENCES: "audiences",
@@ -690,6 +808,8 @@ module OpenEmail
690
808
  CANCELLED: "cancelled"
691
809
  }.freeze
692
810
 
811
+ REPLY_SUGGESTION_STATES = {READY: "ready", PENDING: "pending", NONE: "none"}.freeze
812
+
693
813
  REWRITE_ACTIONS = {
694
814
  SHORTEN: "shorten",
695
815
  LENGTHEN: "lengthen",
@@ -749,6 +869,16 @@ module OpenEmail
749
869
  LT: "lt"
750
870
  }.freeze
751
871
 
872
+ SETTINGS_COLOR_THEMES = {LIGHT: "light", DARK: "dark", SYSTEM: "system"}.freeze
873
+
874
+ SETTINGS_DATE_FORMATS = {DMY: "dmy", MDY: "mdy", YMD: "ymd"}.freeze
875
+
876
+ SETTINGS_IMAGE_COMPRESSIONS = {LOW: "low", MEDIUM: "medium", ORIGINAL: "original"}.freeze
877
+
878
+ SETTINGS_TIME_FORMATS = {H12: "12h", H24: "24h"}.freeze
879
+
880
+ SETTINGS_WEEK_STARTS = {MONDAY: "monday", SUNDAY: "sunday"}.freeze
881
+
752
882
  STEP_UP_ERROR_CODES = {
753
883
  STEP_UP_REQUIRED: "step_up_required",
754
884
  STEP_UP_NOT_APPLICABLE: "step_up_not_applicable",
@@ -123,10 +123,12 @@ module OpenEmail
123
123
  BROADCAST_ID: "broadcastId",
124
124
  BROADCAST_IDS: "broadcastIds",
125
125
  EMAIL: "email",
126
+ WITHOUT_EMAIL: "withoutEmail",
126
127
  BLOCKED: "blocked",
127
128
  DATE_FROM: "dateFrom",
128
129
  DATE_TO: "dateTo",
129
130
  FROM_CONTACTS: "fromContacts",
131
+ SEMANTIC: "semantic",
130
132
  REASON: "reason",
131
133
  KIND: "kind",
132
134
  ENDPOINT_IDS: "endpointIds",
@@ -142,7 +144,17 @@ module OpenEmail
142
144
  OFFSET: "offset",
143
145
  REFRESH: "refresh",
144
146
  CONFIRM: "confirm",
145
- USERNAME: "username"
147
+ USERNAME: "username",
148
+ SCOPE: "scope",
149
+ LEVEL: "level",
150
+ PINNED: "pinned",
151
+ TITLE: "title",
152
+ ITEM_ID: "itemId",
153
+ SENDS: "sends",
154
+ DOMAINS: "domains",
155
+ PEOPLE: "people",
156
+ AI_ACTIONS: "aiActions",
157
+ INTERVAL: "interval"
146
158
  }.freeze
147
159
 
148
160
  RETRY = {
@@ -66,5 +66,19 @@ module OpenEmail
66
66
  def raw_content_type(data, content_type)
67
67
  RawBody.content_type(data, content_type)
68
68
  end
69
+
70
+ def upload_name(data, filename)
71
+ name = (filename.nil? ? RawBody.file_name(data) : filename).to_s.strip
72
+ raise ArgumentError, Defaults::MESSAGES[:FILENAME_REQUIRED] if name.empty?
73
+
74
+ name
75
+ end
76
+
77
+ def upload_timeout(timeout)
78
+ return timeout unless timeout.nil?
79
+
80
+ base = @transport.timeout
81
+ base.to_f.positive? ? [base, Defaults::UPLOAD_TIMEOUT].max : base
82
+ end
69
83
  end
70
84
  end
@@ -40,7 +40,47 @@ module OpenEmail
40
40
  end
41
41
 
42
42
  def respond_to_event(id, body = nil, api_key: nil, **fields)
43
- request(fill(ApiPaths::CALENDAR_EVENT_RESPOND, id:), method: :post, body: payload(body, fields), api_key:)
43
+ request(fill(ApiPaths::CALENDAR_EVENT_RESPOND, id:), method: :post, body: answer_wire(payload(body, fields)), api_key:)
44
+ end
45
+
46
+ def decline_proposal(id, body = nil, api_key: nil, **fields)
47
+ request(fill(ApiPaths::CALENDAR_EVENT_DECLINE_PROPOSAL, id:), method: :post, body: payload(body, fields), api_key:)
48
+ end
49
+
50
+ def list_feeds(api_key: nil)
51
+ fetch_list(ApiPaths::CALENDAR_FEEDS, api_key:)
52
+ end
53
+
54
+ def create_feed(body = nil, api_key: nil, **fields)
55
+ request(ApiPaths::CALENDAR_FEEDS, method: :post, body: payload(body, fields), api_key:)
56
+ end
57
+
58
+ def reset_feed(id, api_key: nil)
59
+ request(fill(ApiPaths::CALENDAR_FEED_RESET, id:), method: :post, api_key:)
60
+ end
61
+
62
+ def delete_feed(id, api_key: nil)
63
+ request(fill(ApiPaths::CALENDAR_FEED, id:), method: :delete, api_key:)
64
+ end
65
+
66
+ def list_subscriptions(api_key: nil)
67
+ fetch_list(ApiPaths::CALENDAR_SUBSCRIPTIONS, api_key:)
68
+ end
69
+
70
+ def create_subscription(body = nil, api_key: nil, **fields)
71
+ request(ApiPaths::CALENDAR_SUBSCRIPTIONS, method: :post, body: payload(body, fields), api_key:)
72
+ end
73
+
74
+ def update_subscription(id, patch = nil, api_key: nil, **fields)
75
+ request(fill(ApiPaths::CALENDAR_SUBSCRIPTION, id:), method: :patch, body: payload(patch, fields), api_key:)
76
+ end
77
+
78
+ def refresh_subscription(id, api_key: nil)
79
+ request(fill(ApiPaths::CALENDAR_SUBSCRIPTION_REFRESH, id:), method: :post, api_key:)
80
+ end
81
+
82
+ def delete_subscription(id, api_key: nil)
83
+ request(fill(ApiPaths::CALENDAR_SUBSCRIPTION, id:), method: :delete, api_key:)
44
84
  end
45
85
 
46
86
  private
@@ -54,6 +94,12 @@ module OpenEmail
54
94
  wire["end"] = instant(wire["end"]) if wire.key?("end")
55
95
  wire
56
96
  end
97
+
98
+ def answer_wire(wire)
99
+ wire["proposedStart"] = instant(wire["proposedStart"]) if wire.key?("proposedStart")
100
+ wire["proposedEnd"] = instant(wire["proposedEnd"]) if wire.key?("proposedEnd")
101
+ wire
102
+ end
57
103
  end
58
104
  end
59
105
  end
@@ -101,11 +101,44 @@ module OpenEmail
101
101
  api_key:)
102
102
  end
103
103
 
104
+ def list_cards(email: nil, without_email: nil, limit: nil, cursor: nil, api_key: nil)
105
+ fetch_page(ApiPaths::CONTACT_CARDS, card_query(email, without_email), limit:, cursor:, api_key:)
106
+ end
107
+
108
+ def list_all_cards(email: nil, without_email: nil, limit: nil, cursor: nil, api_key: nil)
109
+ collect_all(ApiPaths::CONTACT_CARDS, card_query(email, without_email), limit:, cursor:, api_key:)
110
+ end
111
+
112
+ def iterate_cards(email: nil, without_email: nil, limit: nil, cursor: nil, api_key: nil, &)
113
+ iterate_pages(ApiPaths::CONTACT_CARDS, card_query(email, without_email), limit:, cursor:, api_key:, &)
114
+ end
115
+
116
+ def get_card(id, api_key: nil)
117
+ request(fill(ApiPaths::CONTACT_CARD, id:), api_key:)
118
+ end
119
+
120
+ def create_card(body = nil, api_key: nil, **fields)
121
+ request(ApiPaths::CONTACT_CARDS, method: :post, body: payload(body, fields), api_key:)
122
+ end
123
+
124
+ def update_card(id, patch = nil, api_key: nil, **fields)
125
+ request(fill(ApiPaths::CONTACT_CARD, id:), method: :patch, body: payload(patch, fields), repeatable: true,
126
+ api_key:)
127
+ end
128
+
129
+ def delete_card(id, api_key: nil)
130
+ request(fill(ApiPaths::CONTACT_CARD, id:), method: :delete, api_key:)
131
+ end
132
+
104
133
  private
105
134
 
106
135
  def people_query(q, email, sort, blocked)
107
136
  query_params(q:, email:, sort:, blocked: flag(blocked))
108
137
  end
138
+
139
+ def card_query(email, without_email)
140
+ query_params(email:, without_email: flag(without_email))
141
+ end
109
142
  end
110
143
  end
111
144
  end
@@ -137,6 +137,39 @@ module OpenEmail
137
137
  request(fill(ApiPaths::DOMAIN_ADDRESS_LOGIN, id:, addressId: address_id), method: :delete, api_key:)
138
138
  end
139
139
 
140
+ def get_mail_app_settings(id, address_id, api_key: nil)
141
+ request(fill(ApiPaths::DOMAIN_ADDRESS_MAIL_APPS, id:, addressId: address_id), api_key:)
142
+ end
143
+
144
+ def update_mail_app_settings(id, address_id, patch = nil, api_key: nil, **fields)
145
+ request(fill(ApiPaths::DOMAIN_ADDRESS_MAIL_APPS, id:, addressId: address_id), method: :patch,
146
+ body: payload(patch, fields), repeatable: true, api_key:)
147
+ end
148
+
149
+ def list_app_passwords(id, address_id, api_key: nil)
150
+ request(fill(ApiPaths::DOMAIN_ADDRESS_APP_PASSWORDS, id:, addressId: address_id), api_key:)
151
+ end
152
+
153
+ def create_app_password(id, address_id, body = nil, api_key: nil, **fields)
154
+ request(fill(ApiPaths::DOMAIN_ADDRESS_APP_PASSWORDS, id:, addressId: address_id), method: :post,
155
+ body: payload(body, fields), api_key:)
156
+ end
157
+
158
+ def update_app_password(id, address_id, password_id, patch = nil, api_key: nil, **fields)
159
+ request(fill(ApiPaths::DOMAIN_ADDRESS_APP_PASSWORD, id:, addressId: address_id, passwordId: password_id),
160
+ method: :patch, body: payload(patch, fields), repeatable: true, api_key:)
161
+ end
162
+
163
+ def delete_app_password(id, address_id, password_id, api_key: nil)
164
+ request(fill(ApiPaths::DOMAIN_ADDRESS_APP_PASSWORD, id:, addressId: address_id, passwordId: password_id),
165
+ method: :delete, api_key:)
166
+ end
167
+
168
+ def send_mail_app_setup(id, address_id, body = nil, api_key: nil, **fields)
169
+ request(fill(ApiPaths::DOMAIN_ADDRESS_MAIL_APP_SETUP, id:, addressId: address_id), method: :post,
170
+ body: payload(body, fields), api_key:)
171
+ end
172
+
140
173
  def get_dns(id, refresh: nil, api_key: nil)
141
174
  request(fill(ApiPaths::DOMAIN_DNS, id:), query: query_params(refresh:), api_key:)
142
175
  end
@@ -76,20 +76,6 @@ module OpenEmail
76
76
  def list_query(q, kind, direction, address, since, until_value, sort)
77
77
  query_params(q:, kind:, direction:, address:, since: instant(since), until: instant(until_value), sort:)
78
78
  end
79
-
80
- def upload_name(data, filename)
81
- name = (filename.nil? ? RawBody.file_name(data) : filename).to_s.strip
82
- raise ArgumentError, Defaults::MESSAGES[:FILENAME_REQUIRED] if name.empty?
83
-
84
- name
85
- end
86
-
87
- def upload_timeout(timeout)
88
- return timeout unless timeout.nil?
89
-
90
- base = @transport.timeout
91
- base.to_f.positive? ? [base, Defaults::UPLOAD_TIMEOUT].max : base
92
- end
93
79
  end
94
80
  end
95
81
  end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenEmail
4
+ module Resources
5
+ class Knowledge < Resource
6
+ def list(scope: nil, level: nil, kind: nil, status: nil, pinned: nil, q: nil, limit: nil, cursor: nil,
7
+ api_key: nil)
8
+ fetch_page(ApiPaths::KNOWLEDGE, list_query(scope, level, kind, status, pinned, q), limit:, cursor:, api_key:)
9
+ end
10
+
11
+ def list_all(scope: nil, level: nil, kind: nil, status: nil, pinned: nil, q: nil, limit: nil, cursor: nil,
12
+ api_key: nil)
13
+ collect_all(ApiPaths::KNOWLEDGE, list_query(scope, level, kind, status, pinned, q), limit:, cursor:, api_key:)
14
+ end
15
+
16
+ def iterate(scope: nil, level: nil, kind: nil, status: nil, pinned: nil, q: nil, limit: nil, cursor: nil,
17
+ api_key: nil, &)
18
+ iterate_pages(ApiPaths::KNOWLEDGE, list_query(scope, level, kind, status, pinned, q), limit:, cursor:,
19
+ api_key:, &)
20
+ end
21
+
22
+ def levels(api_key: nil)
23
+ fetch_list(ApiPaths::KNOWLEDGE_LEVELS, api_key:)
24
+ end
25
+
26
+ def usage(api_key: nil)
27
+ request(ApiPaths::KNOWLEDGE_USAGE, api_key:)
28
+ end
29
+
30
+ def search(body = nil, api_key: nil, **fields)
31
+ request(ApiPaths::KNOWLEDGE_SEARCH, method: :post, body: payload(body, fields), repeatable: true, api_key:)
32
+ end
33
+
34
+ def create_note(body = nil, api_key: nil, **fields)
35
+ request(ApiPaths::KNOWLEDGE_NOTES, method: :post, body: payload(body, fields), api_key:)
36
+ end
37
+
38
+ def add_link(body = nil, api_key: nil, **fields)
39
+ request(ApiPaths::KNOWLEDGE_LINKS, method: :post, body: payload(body, fields), api_key:)
40
+ end
41
+
42
+ def upload_file(data, filename: nil, content_type: nil, scope: nil, title: nil, timeout: nil, api_key: nil)
43
+ query = query_params(filename: upload_name(data, filename), scope:, title:)
44
+ request(ApiPaths::KNOWLEDGE_FILES, method: :post, query:, raw: data,
45
+ content_type: raw_content_type(data, content_type), timeout: upload_timeout(timeout), api_key:)
46
+ end
47
+
48
+ def get(id, api_key: nil)
49
+ request(fill(ApiPaths::KNOWLEDGE_ITEM, id:), api_key:)
50
+ end
51
+
52
+ def update(id, patch = nil, api_key: nil, **fields)
53
+ request(fill(ApiPaths::KNOWLEDGE_ITEM, id:), method: :patch, body: payload(patch, fields), repeatable: true,
54
+ api_key:)
55
+ end
56
+
57
+ def delete(id, api_key: nil)
58
+ request(fill(ApiPaths::KNOWLEDGE_ITEM, id:), method: :delete, api_key:)
59
+ end
60
+
61
+ def refresh(id, api_key: nil)
62
+ request(fill(ApiPaths::KNOWLEDGE_ITEM_REFRESH, id:), method: :post, repeatable: true, api_key:)
63
+ end
64
+
65
+ def stats(days: nil, api_key: nil)
66
+ request(ApiPaths::KNOWLEDGE_STATS, query: query_params(days:), api_key:)
67
+ end
68
+
69
+ def list_suggestions(kind: nil, status: nil, limit: nil, cursor: nil, api_key: nil)
70
+ fetch_page(ApiPaths::KNOWLEDGE_SUGGESTIONS, suggestion_query(kind, status), limit:, cursor:, api_key:)
71
+ end
72
+
73
+ def list_all_suggestions(kind: nil, status: nil, limit: nil, cursor: nil, api_key: nil)
74
+ collect_all(ApiPaths::KNOWLEDGE_SUGGESTIONS, suggestion_query(kind, status), limit:, cursor:, api_key:)
75
+ end
76
+
77
+ def iterate_suggestions(kind: nil, status: nil, limit: nil, cursor: nil, api_key: nil, &)
78
+ iterate_pages(ApiPaths::KNOWLEDGE_SUGGESTIONS, suggestion_query(kind, status), limit:, cursor:, api_key:, &)
79
+ end
80
+
81
+ def accept_suggestion(id, body = nil, api_key: nil, **fields)
82
+ request(fill(ApiPaths::KNOWLEDGE_SUGGESTION_ACCEPT, id:), method: :post, body: payload(body, fields), api_key:)
83
+ end
84
+
85
+ def dismiss_suggestion(id, api_key: nil)
86
+ request(fill(ApiPaths::KNOWLEDGE_SUGGESTION_DISMISS, id:), method: :post, api_key:)
87
+ end
88
+
89
+ def list_flags(item_id: nil, limit: nil, api_key: nil)
90
+ fetch_list(ApiPaths::KNOWLEDGE_FLAGS, query_params(item_id:, limit:), api_key:)
91
+ end
92
+
93
+ def dismiss_flag(id, api_key: nil)
94
+ request(fill(ApiPaths::KNOWLEDGE_FLAG_DISMISS, id:), method: :post, repeatable: true, api_key:)
95
+ end
96
+
97
+ def list_connectors(api_key: nil)
98
+ fetch_list(ApiPaths::KNOWLEDGE_CONNECTORS, api_key:)
99
+ end
100
+
101
+ def add_connector(body = nil, api_key: nil, **fields)
102
+ request(ApiPaths::KNOWLEDGE_CONNECTORS, method: :post, body: payload(body, fields), api_key:)
103
+ end
104
+
105
+ def get_connector(id, api_key: nil)
106
+ request(fill(ApiPaths::KNOWLEDGE_CONNECTOR, id:), api_key:)
107
+ end
108
+
109
+ def update_connector(id, patch = nil, api_key: nil, **fields)
110
+ request(fill(ApiPaths::KNOWLEDGE_CONNECTOR, id:), method: :patch, body: payload(patch, fields), repeatable: true,
111
+ api_key:)
112
+ end
113
+
114
+ def delete_connector(id, api_key: nil)
115
+ request(fill(ApiPaths::KNOWLEDGE_CONNECTOR, id:), method: :delete, api_key:)
116
+ end
117
+
118
+ def sync_connector(id, api_key: nil)
119
+ request(fill(ApiPaths::KNOWLEDGE_CONNECTOR_SYNC, id:), method: :post, repeatable: true, api_key:)
120
+ end
121
+
122
+ def draft_from_thread(body = nil, api_key: nil, **fields)
123
+ request(ApiPaths::KNOWLEDGE_DRAFTS, method: :post, body: payload(body, fields), api_key:)
124
+ end
125
+
126
+ private
127
+
128
+ def list_query(scope, level, kind, status, pinned, q)
129
+ query_params(scope:, level:, kind:, status:, pinned: flag(pinned), q:)
130
+ end
131
+
132
+ def suggestion_query(kind, status)
133
+ query_params(kind:, status:)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -6,10 +6,12 @@ module OpenEmail
6
6
  NOT_GIVEN = Object.new.freeze
7
7
  private_constant :NOT_GIVEN
8
8
 
9
- def inspect(provider_key = NOT_GIVEN, api_key: nil)
9
+ def inspect(provider_key = NOT_GIVEN, provider: nil, api_key: nil)
10
10
  return super() if provider_key.equal?(NOT_GIVEN)
11
11
 
12
- request(ApiPaths::PROVIDER_IMPORTS_INSPECT, method: :post, body: {"apiKey" => provider_key}, api_key:)
12
+ body = {"apiKey" => provider_key}
13
+ body["provider"] = provider unless provider.nil?
14
+ request(ApiPaths::PROVIDER_IMPORTS_INSPECT, method: :post, body:, api_key:)
13
15
  end
14
16
 
15
17
  def create(body = nil, api_key: nil, **fields)
@@ -81,8 +81,9 @@ module OpenEmail
81
81
  body: payload(body, fields), api_key:)
82
82
  end
83
83
 
84
- def publish(id_or_slug, api_key: nil)
85
- request(fill(ApiPaths::TEMPLATE_VERSIONS, id: id_or_slug), method: :post, repeatable: true, api_key:)
84
+ def publish(id_or_slug, expected_version: nil, api_key: nil)
85
+ request(fill(ApiPaths::TEMPLATE_VERSIONS, id: id_or_slug), method: :post,
86
+ body: expected_version.nil? ? nil : {"expectedVersion" => expected_version}, repeatable: true, api_key:)
86
87
  end
87
88
 
88
89
  def preview(id_or_slug, body = nil, api_key: nil, **fields)
@@ -4,20 +4,23 @@ module OpenEmail
4
4
  module Resources
5
5
  class Threads < Resource
6
6
  def list(folder: nil, query: nil, label_ids: nil, sort: nil, date_from: nil, date_to: nil, from_contacts: nil,
7
- limit: nil, cursor: nil, api_key: nil)
8
- fetch_page(ApiPaths::THREADS, list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts),
7
+ semantic: nil, address: nil, limit: nil, cursor: nil, api_key: nil)
8
+ fetch_page(ApiPaths::THREADS,
9
+ list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts, semantic, address),
9
10
  style: PAGE_TOKEN, limit:, cursor:, api_key:)
10
11
  end
11
12
 
12
13
  def list_all(folder: nil, query: nil, label_ids: nil, sort: nil, date_from: nil, date_to: nil,
13
- from_contacts: nil, limit: nil, cursor: nil, api_key: nil)
14
- collect_all(ApiPaths::THREADS, list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts),
14
+ from_contacts: nil, semantic: nil, address: nil, limit: nil, cursor: nil, api_key: nil)
15
+ collect_all(ApiPaths::THREADS,
16
+ list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts, semantic, address),
15
17
  style: PAGE_TOKEN, limit:, cursor:, api_key:)
16
18
  end
17
19
 
18
20
  def iterate(folder: nil, query: nil, label_ids: nil, sort: nil, date_from: nil, date_to: nil, from_contacts: nil,
19
- limit: nil, cursor: nil, api_key: nil, &)
20
- iterate_pages(ApiPaths::THREADS, list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts),
21
+ semantic: nil, address: nil, limit: nil, cursor: nil, api_key: nil, &)
22
+ iterate_pages(ApiPaths::THREADS,
23
+ list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts, semantic, address),
21
24
  style: PAGE_TOKEN, limit:, cursor:, api_key:, &)
22
25
  end
23
26
 
@@ -81,6 +84,10 @@ module OpenEmail
81
84
  request(fill(ApiPaths::THREAD_SUMMARY, id:), api_key:)
82
85
  end
83
86
 
87
+ def reply_suggestions(id, api_key: nil)
88
+ request(fill(ApiPaths::THREAD_REPLY_SUGGESTIONS, id:), api_key:)
89
+ end
90
+
84
91
  def restore(id, api_key: nil)
85
92
  request(fill(ApiPaths::THREAD_RESTORE, id:), method: :post, repeatable: true, api_key:)
86
93
  end
@@ -95,9 +102,9 @@ module OpenEmail
95
102
 
96
103
  private
97
104
 
98
- def list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts)
105
+ def list_query(folder, query, label_ids, sort, date_from, date_to, from_contacts, semantic, address)
99
106
  query_params(folder:, query:, label_ids: joined(label_ids), sort:, date_from: instant(date_from),
100
- date_to: instant(date_to), from_contacts: flag(from_contacts))
107
+ date_to: instant(date_to), from_contacts: flag(from_contacts), semantic: flag(semantic), address:)
101
108
  end
102
109
  end
103
110
  end
@@ -14,6 +14,14 @@ module OpenEmail
14
14
  def check_deliverability(domain, api_key: nil)
15
15
  request(ApiPaths::TOOLS_DELIVERABILITY, query: query_params(domain:), api_key:)
16
16
  end
17
+
18
+ def read_verification_code(body = nil, api_key: nil, **fields)
19
+ request(ApiPaths::TOOLS_VERIFICATION_CODE, method: :post, body: payload(body, fields), api_key:)
20
+ end
21
+
22
+ def estimate_cost(sends: nil, domains: nil, people: nil, ai_actions: nil, interval: nil, api_key: nil)
23
+ request(ApiPaths::TOOLS_COST, query: query_params(sends:, domains:, people:, ai_actions:, interval:), api_key:)
24
+ end
17
25
  end
18
26
  end
19
27
  end
@@ -3,22 +3,27 @@
3
3
  module OpenEmail
4
4
  module Resources
5
5
  class Tracking < Resource
6
- def list(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, limit: nil, cursor: nil, api_key: nil)
7
- fetch_page(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain), limit:, cursor:, api_key:)
6
+ def list(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, address: nil, limit: nil, cursor: nil,
7
+ api_key: nil)
8
+ fetch_page(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain, address), limit:, cursor:,
9
+ api_key:)
8
10
  end
9
11
 
10
- def list_all(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, limit: nil, cursor: nil,
11
- api_key: nil)
12
- collect_all(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain), limit:, cursor:, api_key:)
12
+ def list_all(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, address: nil, limit: nil,
13
+ cursor: nil, api_key: nil)
14
+ collect_all(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain, address), limit:, cursor:,
15
+ api_key:)
13
16
  end
14
17
 
15
- def iterate(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, limit: nil, cursor: nil,
16
- api_key: nil, &)
17
- iterate_pages(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain), limit:, cursor:, api_key:, &)
18
+ def iterate(opened: nil, clicked: nil, days: nil, minutes: nil, grain: nil, address: nil, limit: nil,
19
+ cursor: nil, api_key: nil, &)
20
+ iterate_pages(ApiPaths::TRACKING, list_query(opened, clicked, days, minutes, grain, address), limit:, cursor:,
21
+ api_key:, &)
18
22
  end
19
23
 
20
- def get_stats(days: nil, minutes: nil, grain: nil, offset_minutes: nil, api_key: nil)
21
- request(ApiPaths::TRACKING_STATS, query: query_params(days:, minutes:, grain:, offset_minutes:), api_key:)
24
+ def get_stats(days: nil, minutes: nil, grain: nil, offset_minutes: nil, address: nil, api_key: nil)
25
+ request(ApiPaths::TRACKING_STATS, query: query_params(days:, minutes:, grain:, offset_minutes:, address:),
26
+ api_key:)
22
27
  end
23
28
 
24
29
  def get(id, api_key: nil)
@@ -51,8 +56,8 @@ module OpenEmail
51
56
 
52
57
  private
53
58
 
54
- def list_query(opened, clicked, days, minutes, grain)
55
- query_params(opened: flag(opened), clicked: flag(clicked), days:, minutes:, grain:)
59
+ def list_query(opened, clicked, days, minutes, grain, address)
60
+ query_params(opened: flag(opened), clicked: flag(clicked), days:, minutes:, grain:, address:)
56
61
  end
57
62
 
58
63
  def hit_query(include_machine)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenEmail
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.2"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openemail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenEmail
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-10-04 00:00:00.000000000 Z
10
+ date: 2026-10-10 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Send email and broadcasts, work with threads, drafts, labels, templates,
13
13
  rules, webhooks, tracking, contacts, audiences, sign-up forms, domains, suppressions,
@@ -54,6 +54,7 @@ files:
54
54
  - lib/openemail/resources/forms.rb
55
55
  - lib/openemail/resources/imports.rb
56
56
  - lib/openemail/resources/keys.rb
57
+ - lib/openemail/resources/knowledge.rb
57
58
  - lib/openemail/resources/labels.rb
58
59
  - lib/openemail/resources/languages.rb
59
60
  - lib/openemail/resources/me.rb