mobiscroll-connect 1.2.0 → 1.5.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/CHANGELOG.md +49 -0
- data/README.md +28 -1
- data/lib/mobiscroll/connect/client.rb +2 -1
- data/lib/mobiscroll/connect/models.rb +54 -2
- data/lib/mobiscroll/connect/resources/webhooks.rb +42 -0
- data/lib/mobiscroll/connect/version.rb +1 -1
- data/lib/mobiscroll/connect.rb +1 -0
- data/mobiscroll-connect.gemspec +9 -4
- metadata +11 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5b667cc604c98500160cd034837d4ef9b097ef5a08e50ff9ab75ec451f41d5f
|
|
4
|
+
data.tar.gz: b3d758a7b2cc387d570526a6ddae75ce216d12082ee156b341343942362e4f3c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: debeb4453999f74a080e45b5e1c1ea6ade00a6a3f370c665be12c2ce1e994244c7256738734ac00fa893cb754dd132a620aa63dc292fcb722f66b348e16cb455
|
|
7
|
+
data.tar.gz: 20c2e49dec99acc7fe35b4cf42b2a7a084a00d23ea86f802cd7714d5fbcf5a82c35c09cf57997d99ca688b3e6e16b5e8dace0ade00e64b16feaaa25eb32828f7
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to the Mobiscroll Connect Ruby SDK (RubyGems: `mobiscroll-connect`) are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this SDK follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html). SDKs in this monorepo version independently, so this file covers the Ruby SDK only.
|
|
6
|
+
|
|
7
|
+
## [1.5.1] — 2026-09-22
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Updated package metadata. No code or public API changes.
|
|
12
|
+
|
|
13
|
+
## [1.5.0] — 2026-09-21
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- `webhooks` resource with `subscribe_webhook()` and `unsubscribe_webhook()` for calendar change notifications.
|
|
18
|
+
- `sync_state` and `sync_state_updated_at` on `ConnectedAccount`.
|
|
19
|
+
|
|
20
|
+
## [1.2.0] — 2026-08-27
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- Granted OAuth scopes are reported on the connection status, and a missing scope now raises `CalendarPermissionError`.
|
|
25
|
+
|
|
26
|
+
## [1.1.0] — 2026-06-03
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Optional `lng` parameter on the authorization URL, for Connect's localized consent screens.
|
|
31
|
+
|
|
32
|
+
## [1.0.2] — 2026-05-26
|
|
33
|
+
|
|
34
|
+
### Added
|
|
35
|
+
|
|
36
|
+
- First published release: `auth`, `calendars` and `events` resources over Google Calendar, Microsoft Outlook, Apple Calendar and CalDAV.
|
|
37
|
+
- Automatic token refresh on 401 with an `on_tokens_refreshed` callback.
|
|
38
|
+
- Typed error hierarchy rooted at `Mobiscroll::Connect::Error`.
|
|
39
|
+
- Sinatra reference application under `minimal-app/`.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
|
|
43
|
+
- Minimum supported Ruby raised to 3.2.
|
|
44
|
+
|
|
45
|
+
[1.5.1]: https://github.com/acidb/mobiscroll-connect-sdks/releases/tag/ruby-v1.5.1
|
|
46
|
+
[1.5.0]: https://github.com/acidb/mobiscroll-connect-sdks/releases/tag/ruby-v1.5.0
|
|
47
|
+
[1.2.0]: https://github.com/acidb/mobiscroll-connect-sdks/releases/tag/ruby-v1.2.0
|
|
48
|
+
[1.1.0]: https://github.com/acidb/mobiscroll-connect-sdks/releases/tag/ruby-v1.1.0
|
|
49
|
+
[1.0.2]: https://github.com/acidb/mobiscroll-connect-sdks/releases/tag/ruby-v1.0.2
|
data/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Mobiscroll Connect Ruby SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Ruby client for [Mobiscroll Connect](https://mobiscroll.com/connect), the calendar connectivity layer for scheduling products — Google Calendar, Microsoft Outlook, Apple Calendar and CalDAV through one API. Backend only — works with your own UI.
|
|
4
|
+
|
|
5
|
+
[](https://rubygems.org/gems/mobiscroll-connect)
|
|
6
|
+
|
|
7
|
+
**[RubyGems](https://rubygems.org/gems/mobiscroll-connect)** · **[Documentation](https://mobiscroll.com/docs/connect/ruby-sdk)** · **[Changelog](CHANGELOG.md)** · **[Source](https://github.com/acidb/mobiscroll-connect-sdks/tree/main/sdks/ruby)**
|
|
4
8
|
|
|
5
9
|
## Installation
|
|
6
10
|
|
|
@@ -170,6 +174,29 @@ client.events.delete(
|
|
|
170
174
|
)
|
|
171
175
|
```
|
|
172
176
|
|
|
177
|
+
## Webhooks
|
|
178
|
+
|
|
179
|
+
### Subscribe to calendar change notifications
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
result = client.webhooks.subscribe_webhook(
|
|
183
|
+
provider: Mobiscroll::Connect::Provider::GOOGLE,
|
|
184
|
+
calendar_id: 'primary'
|
|
185
|
+
)
|
|
186
|
+
puts result.channel_id
|
|
187
|
+
puts result.server_webhook_url
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Unsubscribe
|
|
191
|
+
|
|
192
|
+
```ruby
|
|
193
|
+
client.webhooks.unsubscribe_webhook(
|
|
194
|
+
provider: 'google',
|
|
195
|
+
channel_id: result.channel_id,
|
|
196
|
+
resource_id: result.subscription.resource_id
|
|
197
|
+
)
|
|
198
|
+
```
|
|
199
|
+
|
|
173
200
|
## Error handling
|
|
174
201
|
|
|
175
202
|
All errors are subclasses of `Mobiscroll::Connect::Error`:
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Mobiscroll
|
|
4
4
|
module Connect
|
|
5
5
|
class Client
|
|
6
|
-
attr_reader :auth, :calendars, :events
|
|
6
|
+
attr_reader :auth, :calendars, :events, :webhooks
|
|
7
7
|
|
|
8
8
|
def initialize(client_id:, client_secret:, redirect_uri:,
|
|
9
9
|
base_url: DEFAULT_BASE_URL, timeout: DEFAULT_TIMEOUT,
|
|
@@ -20,6 +20,7 @@ module Mobiscroll
|
|
|
20
20
|
@auth = Resources::Auth.new(@config, @api_client)
|
|
21
21
|
@calendars = Resources::Calendars.new(@config, @api_client)
|
|
22
22
|
@events = Resources::Events.new(@config, @api_client)
|
|
23
|
+
@webhooks = Resources::Webhooks.new(@config, @api_client)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def set_credentials(tokens)
|
|
@@ -57,7 +57,15 @@ module Mobiscroll
|
|
|
57
57
|
# no calendars can be read from them until the user reconnects and allows access. It
|
|
58
58
|
# is nil when the question does not apply (Apple and CalDav authenticate with a
|
|
59
59
|
# username and app password) or no scopes were recorded for the account.
|
|
60
|
-
|
|
60
|
+
# `sync_state` reports whether the stored credentials still work: 'active', or
|
|
61
|
+
# 'reauth_required' once the provider has rejected them. It answers a different question
|
|
62
|
+
# from `calendar_permission_granted`, which records what was agreed at consent time and
|
|
63
|
+
# never changes afterwards. An account with no observed failure is 'active'. Recovery is
|
|
64
|
+
# the same reconnect — it cannot be repaired server-side.
|
|
65
|
+
ConnectedAccount = Struct.new(
|
|
66
|
+
:id, :display, :granted_scopes, :calendar_permission_granted, :sync_state, :sync_state_updated_at,
|
|
67
|
+
keyword_init: true
|
|
68
|
+
) do
|
|
61
69
|
def self.from_h(hash)
|
|
62
70
|
return nil if hash.nil?
|
|
63
71
|
|
|
@@ -67,7 +75,9 @@ module Mobiscroll
|
|
|
67
75
|
id: hash['id'] || hash[:id],
|
|
68
76
|
display: hash['display'] || hash[:display],
|
|
69
77
|
granted_scopes: Array(hash['grantedScopes'] || hash[:grantedScopes]),
|
|
70
|
-
calendar_permission_granted: granted
|
|
78
|
+
calendar_permission_granted: granted,
|
|
79
|
+
sync_state: hash['syncState'] || hash[:syncState] || 'active',
|
|
80
|
+
sync_state_updated_at: hash['syncStateUpdatedAt'] || hash[:syncStateUpdatedAt]
|
|
71
81
|
)
|
|
72
82
|
end
|
|
73
83
|
end
|
|
@@ -200,5 +210,47 @@ module Mobiscroll
|
|
|
200
210
|
)
|
|
201
211
|
end
|
|
202
212
|
end
|
|
213
|
+
|
|
214
|
+
# The channel details returned by Webhooks#subscribe_webhook. `resource_id` is
|
|
215
|
+
# present for Google; `expiration` is an ISO date string, present for some providers.
|
|
216
|
+
WebhookSubscription = Struct.new(:channel_id, :resource_id, :expiration, keyword_init: true) do
|
|
217
|
+
def self.from_h(hash)
|
|
218
|
+
return nil if hash.nil?
|
|
219
|
+
|
|
220
|
+
new(
|
|
221
|
+
channel_id: hash['channelId'] || hash[:channelId],
|
|
222
|
+
resource_id: hash['resourceId'] || hash[:resourceId],
|
|
223
|
+
expiration: hash['expiration'] || hash[:expiration]
|
|
224
|
+
)
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Response from Webhooks#subscribe_webhook.
|
|
229
|
+
SubscribeWebhookResponse = Struct.new(
|
|
230
|
+
:success, :provider, :subscription, :server_webhook_url, :channel_id, keyword_init: true
|
|
231
|
+
) do
|
|
232
|
+
def self.from_h(hash)
|
|
233
|
+
return nil if hash.nil?
|
|
234
|
+
|
|
235
|
+
new(
|
|
236
|
+
success: hash['success'] || hash[:success],
|
|
237
|
+
provider: hash['provider'] || hash[:provider],
|
|
238
|
+
subscription: WebhookSubscription.from_h(hash['subscription'] || hash[:subscription]),
|
|
239
|
+
server_webhook_url: hash['serverWebhookUrl'] || hash[:serverWebhookUrl],
|
|
240
|
+
channel_id: hash['channelId'] || hash[:channelId]
|
|
241
|
+
)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Response from Webhooks#unsubscribe_webhook. `success` is true whenever the local
|
|
246
|
+
# mapping was removed, even if the provider-side unsubscribe itself failed — `message`
|
|
247
|
+
# explains what happened in that case.
|
|
248
|
+
UnsubscribeWebhookResponse = Struct.new(:success, :message, keyword_init: true) do
|
|
249
|
+
def self.from_h(hash)
|
|
250
|
+
return nil if hash.nil?
|
|
251
|
+
|
|
252
|
+
new(success: hash['success'] || hash[:success], message: hash['message'] || hash[:message])
|
|
253
|
+
end
|
|
254
|
+
end
|
|
203
255
|
end
|
|
204
256
|
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
module Mobiscroll
|
|
6
|
+
module Connect
|
|
7
|
+
module Resources
|
|
8
|
+
class Webhooks
|
|
9
|
+
def initialize(_config, api_client)
|
|
10
|
+
@api_client = api_client
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Subscribes to push notifications for changes on a calendar.
|
|
14
|
+
#
|
|
15
|
+
# `channel_id` is auto-generated server-side when omitted. `expiration` is a
|
|
16
|
+
# provider-specific timestamp (ms epoch) the caller can suggest.
|
|
17
|
+
def subscribe_webhook(provider:, calendar_id:, channel_id: nil, expiration: nil)
|
|
18
|
+
body = { 'provider' => provider, 'calendarId' => calendar_id }
|
|
19
|
+
body['channelId'] = channel_id if channel_id
|
|
20
|
+
body['expiration'] = expiration if expiration
|
|
21
|
+
|
|
22
|
+
parsed = @api_client.post('/subscribe-webhook', body: JSON.generate(body))
|
|
23
|
+
SubscribeWebhookResponse.from_h(parsed)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Unsubscribes a previously created webhook channel. `resource_id` is required by
|
|
27
|
+
# some providers (e.g. Google) to fully unsubscribe.
|
|
28
|
+
#
|
|
29
|
+
# The backend treats a 200 response as final even when the provider-side
|
|
30
|
+
# unsubscribe itself failed (e.g. an already-expired subscription) — the local
|
|
31
|
+
# mapping is removed either way, and `message` explains what happened.
|
|
32
|
+
def unsubscribe_webhook(provider:, channel_id:, resource_id: nil)
|
|
33
|
+
body = { 'provider' => provider, 'channelId' => channel_id }
|
|
34
|
+
body['resourceId'] = resource_id if resource_id
|
|
35
|
+
|
|
36
|
+
parsed = @api_client.post('/unsubscribe-webhook', body: JSON.generate(body))
|
|
37
|
+
UnsubscribeWebhookResponse.from_h(parsed)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/mobiscroll/connect.rb
CHANGED
|
@@ -9,6 +9,7 @@ require_relative 'connect/api_client'
|
|
|
9
9
|
require_relative 'connect/resources/auth'
|
|
10
10
|
require_relative 'connect/resources/calendars'
|
|
11
11
|
require_relative 'connect/resources/events'
|
|
12
|
+
require_relative 'connect/resources/webhooks'
|
|
12
13
|
require_relative 'connect/client'
|
|
13
14
|
|
|
14
15
|
module Mobiscroll
|
data/mobiscroll-connect.gemspec
CHANGED
|
@@ -8,10 +8,13 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ['Mobiscroll']
|
|
9
9
|
spec.email = ['support@mobiscroll.com']
|
|
10
10
|
|
|
11
|
-
spec.summary = '
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
'
|
|
11
|
+
spec.summary = 'Ruby client for Mobiscroll Connect — Google Calendar, ' \
|
|
12
|
+
'Microsoft Outlook, Apple Calendar and CalDAV through one API.'
|
|
13
|
+
spec.description = 'Ruby client for Mobiscroll Connect, the calendar ' \
|
|
14
|
+
'connectivity layer for scheduling products. Google ' \
|
|
15
|
+
'Calendar, Microsoft Outlook, Apple Calendar and CalDAV ' \
|
|
16
|
+
'through one API, with OAuth 2.0 and webhooks. Backend ' \
|
|
17
|
+
'only — works with your own UI.'
|
|
15
18
|
spec.homepage = 'https://mobiscroll.com/connect'
|
|
16
19
|
spec.license = 'MIT'
|
|
17
20
|
|
|
@@ -20,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
|
20
23
|
spec.metadata = {
|
|
21
24
|
'homepage_uri' => spec.homepage,
|
|
22
25
|
'source_code_uri' => 'https://github.com/acidb/mobiscroll-connect-sdks',
|
|
26
|
+
'documentation_uri' => 'https://mobiscroll.com/docs/connect/ruby-sdk',
|
|
23
27
|
'bug_tracker_uri' => 'https://github.com/acidb/mobiscroll-connect-sdks/issues',
|
|
24
28
|
'changelog_uri' => 'https://github.com/acidb/mobiscroll-connect-sdks/blob/main/sdks/ruby/CHANGELOG.md',
|
|
25
29
|
'rubygems_mfa_required' => 'true'
|
|
@@ -28,6 +32,7 @@ Gem::Specification.new do |spec|
|
|
|
28
32
|
spec.files = Dir[
|
|
29
33
|
'lib/**/*.rb',
|
|
30
34
|
'README.md',
|
|
35
|
+
'CHANGELOG.md',
|
|
31
36
|
'LICENSE',
|
|
32
37
|
'mobiscroll-connect.gemspec'
|
|
33
38
|
]
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mobiscroll-connect
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mobiscroll
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-09-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|
|
@@ -80,14 +80,17 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '3.23'
|
|
83
|
-
description: Ruby client for
|
|
84
|
-
|
|
83
|
+
description: Ruby client for Mobiscroll Connect, the calendar connectivity layer for
|
|
84
|
+
scheduling products. Google Calendar, Microsoft Outlook, Apple Calendar and CalDAV
|
|
85
|
+
through one API, with OAuth 2.0 and webhooks. Backend only — works with your own
|
|
86
|
+
UI.
|
|
85
87
|
email:
|
|
86
88
|
- support@mobiscroll.com
|
|
87
89
|
executables: []
|
|
88
90
|
extensions: []
|
|
89
91
|
extra_rdoc_files: []
|
|
90
92
|
files:
|
|
93
|
+
- CHANGELOG.md
|
|
91
94
|
- LICENSE
|
|
92
95
|
- README.md
|
|
93
96
|
- lib/mobiscroll-connect.rb
|
|
@@ -101,6 +104,7 @@ files:
|
|
|
101
104
|
- lib/mobiscroll/connect/resources/auth.rb
|
|
102
105
|
- lib/mobiscroll/connect/resources/calendars.rb
|
|
103
106
|
- lib/mobiscroll/connect/resources/events.rb
|
|
107
|
+
- lib/mobiscroll/connect/resources/webhooks.rb
|
|
104
108
|
- lib/mobiscroll/connect/version.rb
|
|
105
109
|
- mobiscroll-connect.gemspec
|
|
106
110
|
homepage: https://mobiscroll.com/connect
|
|
@@ -109,6 +113,7 @@ licenses:
|
|
|
109
113
|
metadata:
|
|
110
114
|
homepage_uri: https://mobiscroll.com/connect
|
|
111
115
|
source_code_uri: https://github.com/acidb/mobiscroll-connect-sdks
|
|
116
|
+
documentation_uri: https://mobiscroll.com/docs/connect/ruby-sdk
|
|
112
117
|
bug_tracker_uri: https://github.com/acidb/mobiscroll-connect-sdks/issues
|
|
113
118
|
changelog_uri: https://github.com/acidb/mobiscroll-connect-sdks/blob/main/sdks/ruby/CHANGELOG.md
|
|
114
119
|
rubygems_mfa_required: 'true'
|
|
@@ -130,5 +135,6 @@ requirements: []
|
|
|
130
135
|
rubygems_version: 3.5.22
|
|
131
136
|
signing_key:
|
|
132
137
|
specification_version: 4
|
|
133
|
-
summary:
|
|
138
|
+
summary: Ruby client for Mobiscroll Connect — Google Calendar, Microsoft Outlook,
|
|
139
|
+
Apple Calendar and CalDAV through one API.
|
|
134
140
|
test_files: []
|