seam 2.0.0a2 → 2.0.0b0
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/Gemfile.lock +54 -51
- data/README.md +323 -3
- data/Rakefile +4 -1
- data/lib/seam/auth.rb +118 -0
- data/lib/seam/base_resource.rb +63 -0
- data/lib/seam/deep_hash_accessor.rb +37 -0
- data/lib/seam/default_endpoint.rb +5 -0
- data/lib/seam/helpers/action_attempt.rb +45 -0
- data/lib/seam/http.rb +52 -0
- data/lib/seam/http_multi_workspace.rb +62 -0
- data/lib/seam/http_single_workspace.rb +42 -0
- data/lib/seam/options.rb +64 -0
- data/lib/seam/parse_options.rb +23 -0
- data/lib/seam/request.rb +82 -51
- data/lib/seam/routes/clients/access_codes.rb +74 -0
- data/lib/seam/routes/clients/access_codes_simulate.rb +18 -0
- data/lib/seam/routes/clients/access_codes_unmanaged.rb +42 -0
- data/lib/seam/routes/clients/acs.rb +44 -0
- data/lib/seam/routes/clients/acs_access_groups.rb +48 -0
- data/lib/seam/routes/clients/acs_access_groups_unmanaged.rb +24 -0
- data/lib/seam/routes/clients/acs_credential_pools.rb +18 -0
- data/lib/seam/routes/clients/acs_credential_provisioning_automations.rb +18 -0
- data/lib/seam/routes/clients/acs_credentials.rb +60 -0
- data/lib/seam/routes/clients/acs_credentials_unmanaged.rb +24 -0
- data/lib/seam/routes/clients/acs_encoders.rb +36 -0
- data/lib/seam/routes/clients/acs_entrances.rb +36 -0
- data/lib/seam/routes/clients/acs_systems.rb +30 -0
- data/lib/seam/routes/clients/acs_users.rb +78 -0
- data/lib/seam/routes/clients/acs_users_unmanaged.rb +24 -0
- data/lib/seam/routes/clients/action_attempts.rb +28 -0
- data/lib/seam/routes/clients/client_sessions.rb +54 -0
- data/lib/seam/routes/clients/connect_webviews.rb +36 -0
- data/lib/seam/routes/clients/connected_accounts.rb +36 -0
- data/lib/seam/routes/clients/devices.rb +50 -0
- data/lib/seam/routes/clients/devices_simulate.rb +30 -0
- data/lib/seam/routes/clients/devices_unmanaged.rb +30 -0
- data/lib/seam/routes/clients/events.rb +24 -0
- data/lib/seam/routes/clients/index.rb +38 -0
- data/lib/seam/routes/clients/locks.rb +42 -0
- data/lib/seam/routes/clients/networks.rb +24 -0
- data/lib/seam/routes/clients/noise_sensors.rb +26 -0
- data/lib/seam/routes/clients/noise_sensors_noise_thresholds.rb +42 -0
- data/lib/seam/routes/clients/noise_sensors_simulate.rb +18 -0
- data/lib/seam/routes/clients/phones.rb +28 -0
- data/lib/seam/routes/clients/phones_simulate.rb +18 -0
- data/lib/seam/routes/clients/thermostats.rb +108 -0
- data/lib/seam/routes/clients/thermostats_schedules.rb +42 -0
- data/lib/seam/routes/clients/user_identities.rb +88 -0
- data/lib/seam/routes/clients/user_identities_enrollment_automations.rb +36 -0
- data/lib/seam/routes/clients/webhooks.rb +42 -0
- data/lib/seam/routes/clients/workspaces.rb +40 -0
- data/lib/seam/routes/resources/access_code.rb +14 -0
- data/lib/seam/routes/resources/acs_access_group.rb +11 -0
- data/lib/seam/routes/resources/acs_credential.rb +14 -0
- data/lib/seam/routes/resources/acs_credential_pool.rb +11 -0
- data/lib/seam/routes/resources/acs_credential_provisioning_automation.rb +11 -0
- data/lib/seam/routes/resources/acs_entrance.rb +13 -0
- data/lib/seam/routes/resources/acs_system.rb +14 -0
- data/lib/seam/routes/resources/acs_user.rb +14 -0
- data/lib/seam/routes/resources/action_attempt.rb +9 -0
- data/lib/seam/routes/resources/client_session.rb +11 -0
- data/lib/seam/routes/resources/connect_webview.rb +11 -0
- data/lib/seam/routes/resources/connected_account.rb +14 -0
- data/lib/seam/routes/resources/device.rb +14 -0
- data/lib/seam/routes/resources/device_provider.rb +9 -0
- data/lib/seam/routes/resources/enrollment_automation.rb +11 -0
- data/lib/seam/routes/resources/event.rb +11 -0
- data/lib/seam/routes/resources/index.rb +33 -0
- data/lib/seam/routes/resources/network.rb +11 -0
- data/lib/seam/routes/resources/noise_threshold.rb +9 -0
- data/lib/seam/routes/resources/phone.rb +14 -0
- data/lib/seam/routes/resources/resource_error.rb +11 -0
- data/lib/seam/routes/resources/resource_errors_support.rb +11 -0
- data/lib/seam/routes/resources/resource_warning.rb +11 -0
- data/lib/seam/routes/resources/resource_warnings_support.rb +11 -0
- data/lib/seam/routes/resources/service_health.rb +9 -0
- data/lib/seam/routes/resources/thermostat_schedule.rb +13 -0
- data/lib/seam/routes/resources/unmanaged_access_code.rb +14 -0
- data/lib/seam/routes/resources/unmanaged_device.rb +14 -0
- data/lib/seam/routes/resources/user_identity.rb +11 -0
- data/lib/seam/routes/resources/webhook.rb +9 -0
- data/lib/seam/routes/resources/workspace.rb +9 -0
- data/lib/seam/routes/routes.rb +94 -0
- data/lib/seam/token.rb +53 -0
- data/lib/seam/version.rb +1 -1
- data/lib/seam/wait_for_action_attempt.rb +32 -0
- data/lib/seam/webhook.rb +22 -0
- data/lib/seam.rb +19 -68
- metadata +115 -70
- data/lib/seam/client.rb +0 -129
- data/lib/seam/clients/access_codes.rb +0 -95
- data/lib/seam/clients/access_codes_simulate.rb +0 -17
- data/lib/seam/clients/access_codes_unmanaged.rb +0 -57
- data/lib/seam/clients/acs.rb +0 -35
- data/lib/seam/clients/acs_access_groups.rb +0 -57
- data/lib/seam/clients/acs_credential_pools.rb +0 -17
- data/lib/seam/clients/acs_credential_provisioning_automations.rb +0 -17
- data/lib/seam/clients/acs_credentials.rb +0 -77
- data/lib/seam/clients/acs_entrances.rb +0 -47
- data/lib/seam/clients/acs_systems.rb +0 -27
- data/lib/seam/clients/acs_users.rb +0 -117
- data/lib/seam/clients/action_attempts.rb +0 -30
- data/lib/seam/clients/base_client.rb +0 -21
- data/lib/seam/clients/client_sessions.rb +0 -77
- data/lib/seam/clients/connect_webviews.rb +0 -47
- data/lib/seam/clients/connected_accounts.rb +0 -47
- data/lib/seam/clients/devices.rb +0 -65
- data/lib/seam/clients/devices_simulate.rb +0 -17
- data/lib/seam/clients/devices_unmanaged.rb +0 -37
- data/lib/seam/clients/events.rb +0 -27
- data/lib/seam/clients/locks.rb +0 -53
- data/lib/seam/clients/networks.rb +0 -27
- data/lib/seam/clients/noise_sensors.rb +0 -15
- data/lib/seam/clients/noise_sensors_noise_thresholds.rb +0 -57
- data/lib/seam/clients/noise_sensors_simulate.rb +0 -17
- data/lib/seam/clients/phones.rb +0 -31
- data/lib/seam/clients/phones_simulate.rb +0 -17
- data/lib/seam/clients/thermostats.rb +0 -106
- data/lib/seam/clients/thermostats_climate_setting_schedules.rb +0 -57
- data/lib/seam/clients/user_identities.rb +0 -131
- data/lib/seam/clients/user_identities_enrollment_automations.rb +0 -47
- data/lib/seam/clients/webhooks.rb +0 -57
- data/lib/seam/clients/workspaces.rb +0 -50
- data/lib/seam/resources/access_code.rb +0 -12
- data/lib/seam/resources/acs_access_group.rb +0 -9
- data/lib/seam/resources/acs_credential.rb +0 -12
- data/lib/seam/resources/acs_credential_pool.rb +0 -9
- data/lib/seam/resources/acs_credential_provisioning_automation.rb +0 -9
- data/lib/seam/resources/acs_entrance.rb +0 -9
- data/lib/seam/resources/acs_system.rb +0 -9
- data/lib/seam/resources/acs_user.rb +0 -9
- data/lib/seam/resources/action_attempt.rb +0 -46
- data/lib/seam/resources/base_resource.rb +0 -58
- data/lib/seam/resources/client_session.rb +0 -9
- data/lib/seam/resources/climate_setting_schedule.rb +0 -11
- data/lib/seam/resources/connect_webview.rb +0 -9
- data/lib/seam/resources/connected_account.rb +0 -12
- data/lib/seam/resources/device.rb +0 -12
- data/lib/seam/resources/device_provider.rb +0 -7
- data/lib/seam/resources/enrollment_automation.rb +0 -9
- data/lib/seam/resources/event.rb +0 -9
- data/lib/seam/resources/network.rb +0 -9
- data/lib/seam/resources/noise_threshold.rb +0 -7
- data/lib/seam/resources/phone.rb +0 -12
- data/lib/seam/resources/resource_error.rb +0 -9
- data/lib/seam/resources/resource_errors_support.rb +0 -9
- data/lib/seam/resources/resource_warning.rb +0 -9
- data/lib/seam/resources/resource_warnings_support.rb +0 -9
- data/lib/seam/resources/service_health.rb +0 -7
- data/lib/seam/resources/unmanaged_access_code.rb +0 -12
- data/lib/seam/resources/unmanaged_device.rb +0 -12
- data/lib/seam/resources/user_identity.rb +0 -9
- data/lib/seam/resources/webhook.rb +0 -7
- data/lib/seam/resources/workspace.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f62e294d25f9d5ed9508e9b5d240197d5a92809dbbbb31719722fb6075fecf85
|
4
|
+
data.tar.gz: 51621ca4919764d502838e432d7722949ef504e1629bdb224a103d432cfc94ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc17fcb3c4583ccedf6aed31be275ca76ad721ed2364ac3820580ecd5954f4bb778a85e66eb26a804cc20ede4dd2aad8db1a7206ad5d829f3bfd40de6187e520
|
7
|
+
data.tar.gz: 15de1ddba2b3b0d727aca93235634fa2fb60aece82a6238f06474c8795af1f7f8cd3b4f240d1facfe9d6ee0bc665bc91cae4af9ed8903a14da1b81f58c4190c2
|
data/Gemfile.lock
CHANGED
@@ -1,117 +1,120 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
seam (2.0.
|
5
|
-
|
4
|
+
seam (2.0.0b0)
|
5
|
+
faraday (~> 2.7)
|
6
|
+
faraday-retry (~> 2.2)
|
7
|
+
svix (~> 1.30)
|
6
8
|
|
7
9
|
GEM
|
8
10
|
remote: https://rubygems.org/
|
9
11
|
specs:
|
10
|
-
addressable (2.8.
|
11
|
-
public_suffix (>= 2.0.2, <
|
12
|
+
addressable (2.8.7)
|
13
|
+
public_suffix (>= 2.0.2, < 7.0)
|
12
14
|
ansi (1.5.0)
|
13
15
|
ast (2.4.2)
|
14
|
-
|
15
|
-
bigdecimal (3.1.7)
|
16
|
+
bigdecimal (3.1.8)
|
16
17
|
crack (1.0.0)
|
17
18
|
bigdecimal
|
18
19
|
rexml
|
19
20
|
diff-lcs (1.5.1)
|
20
|
-
docile (1.4.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
docile (1.4.1)
|
22
|
+
ethon (0.16.0)
|
23
|
+
ffi (>= 1.15.0)
|
24
|
+
faraday (2.12.0)
|
25
|
+
faraday-net_http (>= 2.0, < 3.4)
|
26
|
+
json
|
27
|
+
logger
|
28
|
+
faraday-net_http (3.3.0)
|
29
|
+
net-http
|
30
|
+
faraday-retry (2.2.1)
|
31
|
+
faraday (~> 2.0)
|
32
|
+
ffi (1.17.0)
|
33
|
+
ffi (1.17.0-x86_64-linux-gnu)
|
26
34
|
gem-release (2.2.2)
|
27
|
-
hashdiff (1.1.
|
28
|
-
http (5.2.0)
|
29
|
-
addressable (~> 2.8)
|
30
|
-
base64 (~> 0.1)
|
31
|
-
http-cookie (~> 1.0)
|
32
|
-
http-form_data (~> 2.2)
|
33
|
-
llhttp-ffi (~> 0.5.0)
|
34
|
-
http-cookie (1.0.5)
|
35
|
-
domain_name (~> 0.5)
|
36
|
-
http-form_data (2.3.0)
|
35
|
+
hashdiff (1.1.1)
|
37
36
|
json (2.7.2)
|
38
37
|
language_server-protocol (3.17.0.3)
|
39
38
|
lint_roller (1.1.0)
|
40
|
-
|
41
|
-
ffi-compiler (~> 1.0)
|
42
|
-
rake (~> 13.0)
|
39
|
+
logger (1.6.1)
|
43
40
|
multi_json (1.15.0)
|
44
|
-
|
41
|
+
net-http (0.4.1)
|
42
|
+
uri
|
43
|
+
parallel (1.26.3)
|
45
44
|
parse_gemspec (1.0.0)
|
46
45
|
parse_gemspec-cli (1.0.0)
|
47
46
|
multi_json
|
48
47
|
parse_gemspec
|
49
48
|
thor
|
50
|
-
parser (3.3.0
|
49
|
+
parser (3.3.5.0)
|
51
50
|
ast (~> 2.4.1)
|
52
51
|
racc
|
53
|
-
public_suffix (
|
54
|
-
racc (1.
|
52
|
+
public_suffix (6.0.1)
|
53
|
+
racc (1.8.1)
|
55
54
|
rainbow (3.1.1)
|
56
55
|
rake (13.2.1)
|
57
|
-
regexp_parser (2.9.
|
58
|
-
rexml (3.
|
56
|
+
regexp_parser (2.9.2)
|
57
|
+
rexml (3.3.8)
|
59
58
|
rspec (3.13.0)
|
60
59
|
rspec-core (~> 3.13.0)
|
61
60
|
rspec-expectations (~> 3.13.0)
|
62
61
|
rspec-mocks (~> 3.13.0)
|
63
|
-
rspec-core (3.13.
|
62
|
+
rspec-core (3.13.2)
|
64
63
|
rspec-support (~> 3.13.0)
|
65
|
-
rspec-expectations (3.13.
|
64
|
+
rspec-expectations (3.13.3)
|
66
65
|
diff-lcs (>= 1.2.0, < 2.0)
|
67
66
|
rspec-support (~> 3.13.0)
|
68
|
-
rspec-mocks (3.13.
|
67
|
+
rspec-mocks (3.13.2)
|
69
68
|
diff-lcs (>= 1.2.0, < 2.0)
|
70
69
|
rspec-support (~> 3.13.0)
|
71
70
|
rspec-support (3.13.1)
|
72
|
-
rubocop (1.
|
71
|
+
rubocop (1.66.1)
|
73
72
|
json (~> 2.3)
|
74
73
|
language_server-protocol (>= 3.17.0)
|
75
74
|
parallel (~> 1.10)
|
76
75
|
parser (>= 3.3.0.2)
|
77
76
|
rainbow (>= 2.2.2, < 4.0)
|
78
|
-
regexp_parser (>=
|
79
|
-
|
80
|
-
rubocop-ast (>= 1.31.1, < 2.0)
|
77
|
+
regexp_parser (>= 2.4, < 3.0)
|
78
|
+
rubocop-ast (>= 1.32.2, < 2.0)
|
81
79
|
ruby-progressbar (~> 1.7)
|
82
80
|
unicode-display_width (>= 2.4.0, < 3.0)
|
83
|
-
rubocop-ast (1.
|
84
|
-
parser (>= 3.3.0
|
85
|
-
rubocop-performance (1.
|
81
|
+
rubocop-ast (1.32.3)
|
82
|
+
parser (>= 3.3.1.0)
|
83
|
+
rubocop-performance (1.22.1)
|
86
84
|
rubocop (>= 1.48.1, < 2.0)
|
87
|
-
rubocop-ast (>= 1.
|
85
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
88
86
|
ruby-progressbar (1.13.0)
|
89
87
|
simplecov (0.22.0)
|
90
88
|
docile (~> 1.1)
|
91
89
|
simplecov-html (~> 0.11)
|
92
90
|
simplecov_json_formatter (~> 0.1)
|
93
|
-
simplecov-console (0.9.
|
91
|
+
simplecov-console (0.9.2)
|
94
92
|
ansi
|
95
93
|
simplecov
|
96
94
|
terminal-table
|
97
|
-
simplecov-html (0.
|
95
|
+
simplecov-html (0.13.1)
|
98
96
|
simplecov_json_formatter (0.1.4)
|
99
|
-
standard (1.
|
97
|
+
standard (1.41.1)
|
100
98
|
language_server-protocol (~> 3.17.0.2)
|
101
99
|
lint_roller (~> 1.0)
|
102
|
-
rubocop (~> 1.
|
100
|
+
rubocop (~> 1.66.0)
|
103
101
|
standard-custom (~> 1.0.0)
|
104
|
-
standard-performance (~> 1.
|
102
|
+
standard-performance (~> 1.5)
|
105
103
|
standard-custom (1.0.2)
|
106
104
|
lint_roller (~> 1.0)
|
107
105
|
rubocop (~> 1.50)
|
108
|
-
standard-performance (1.
|
106
|
+
standard-performance (1.5.0)
|
109
107
|
lint_roller (~> 1.1)
|
110
|
-
rubocop-performance (~> 1.
|
108
|
+
rubocop-performance (~> 1.22.0)
|
109
|
+
svix (1.38.0)
|
110
|
+
typhoeus (~> 1.0, >= 1.0.1)
|
111
111
|
terminal-table (3.0.2)
|
112
112
|
unicode-display_width (>= 1.1.1, < 3)
|
113
|
-
thor (1.3.
|
114
|
-
|
113
|
+
thor (1.3.2)
|
114
|
+
typhoeus (1.4.1)
|
115
|
+
ethon (>= 0.9.0)
|
116
|
+
unicode-display_width (2.6.0)
|
117
|
+
uri (0.13.1)
|
115
118
|
webmock (3.0.1)
|
116
119
|
addressable (>= 2.3.6)
|
117
120
|
crack (>= 0.3.2)
|
data/README.md
CHANGED
@@ -7,17 +7,337 @@ SDK for the Seam API written in Ruby.
|
|
7
7
|
|
8
8
|
## Description
|
9
9
|
|
10
|
-
|
10
|
+
[Seam](https://seam.co) makes it easy to integrate IoT devices with your applications.
|
11
|
+
This is an official SDK for the Seam API.
|
12
|
+
Please refer to the official [Seam Docs](https://docs.seam.co/latest/) to get started.
|
13
|
+
|
14
|
+
Parts of this SDK are generated from always up-to-date type information
|
15
|
+
provided by [@seamapi/types](https://github.com/seamapi/types/).
|
16
|
+
This ensures all API methods, request shapes, and response shapes are
|
17
|
+
accurate and fully typed.
|
18
|
+
|
19
|
+
<!-- toc -->
|
20
|
+
|
21
|
+
- [Installation](#installation)
|
22
|
+
- [Usage](#usage)
|
23
|
+
- [Examples](#examples)
|
24
|
+
- [List devices](#list-devices)
|
25
|
+
- [Unlock a door](#unlock-a-door)
|
26
|
+
- [Authentication Method](#authentication-method)
|
27
|
+
- [API Key](#api-key)
|
28
|
+
- [Personal Access Token](#personal-access-token)
|
29
|
+
- [Action Attempts](#action-attempts)
|
30
|
+
- [Interacting with Multiple Workspaces](#interacting-with-multiple-workspaces)
|
31
|
+
- [Webhooks](#webhooks)
|
32
|
+
- [Advanced Usage](#advanced-usage)
|
33
|
+
- [Additional Options](#additional-options)
|
34
|
+
- [Setting the endpoint](#setting-the-endpoint)
|
35
|
+
- [Configuring the Faraday Client](#configuring-the-faraday-client)
|
36
|
+
- [Using the Faraday Client](#using-the-faraday-client)
|
37
|
+
- [Overriding the Client](#overriding-the-client)
|
38
|
+
- [Development and Testing](#development-and-testing)
|
39
|
+
- [Quickstart](#quickstart)
|
40
|
+
- [Source code](#source-code)
|
41
|
+
- [Requirements](#requirements)
|
42
|
+
- [Publishing](#publishing)
|
43
|
+
- [Automatic](#automatic)
|
44
|
+
- [Manual](#manual)
|
45
|
+
- [GitHub Actions](#github-actions)
|
46
|
+
- [Secrets for Optional GitHub Actions](#secrets-for-optional-github-actions)
|
47
|
+
- [Contributing](#contributing)
|
48
|
+
- [License](#license)
|
49
|
+
- [Warranty](#warranty)
|
50
|
+
|
51
|
+
<!-- tocstop -->
|
11
52
|
|
12
53
|
## Installation
|
13
54
|
|
14
|
-
Add this as a dependency to your project using [Bundler] with
|
55
|
+
Add this as a dependency to your project using [Bundler] with:
|
15
56
|
|
16
57
|
```
|
17
58
|
$ bundle add seam
|
18
59
|
```
|
19
60
|
|
20
|
-
[
|
61
|
+
[Bundler]: https://bundler.io/
|
62
|
+
|
63
|
+
## Usage
|
64
|
+
|
65
|
+
### Examples
|
66
|
+
|
67
|
+
> [!NOTE]
|
68
|
+
> These examples assume `SEAM_API_KEY` is set in your environment.
|
69
|
+
|
70
|
+
#### List devices
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require "seam"
|
74
|
+
|
75
|
+
seam = Seam.new
|
76
|
+
devices = seam.devices.list
|
77
|
+
```
|
78
|
+
|
79
|
+
#### Unlock a door
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
require "seam"
|
83
|
+
|
84
|
+
seam = Seam.new
|
85
|
+
lock = seam.locks.get(name: "Front Door")
|
86
|
+
seam.locks.unlock_door(device_id: lock.device_id)
|
87
|
+
```
|
88
|
+
|
89
|
+
### Authentication Method
|
90
|
+
|
91
|
+
The SDK supports API key and personal access token authentication mechanisms.
|
92
|
+
Authentication may be configured by passing the corresponding options directly to the `Seam` constructor, or with the more ergonomic static factory methods.
|
93
|
+
|
94
|
+
#### API Key
|
95
|
+
|
96
|
+
An API key is scoped to a single workspace and should only be used on the server.
|
97
|
+
Obtain one from the Seam Console.
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
# Set the `SEAM_API_KEY` environment variable
|
101
|
+
seam = Seam.new
|
102
|
+
|
103
|
+
# Pass as a keyword argument to the constructor
|
104
|
+
seam = Seam.new(api_key: "your-api-key")
|
105
|
+
|
106
|
+
# Use the factory method
|
107
|
+
seam = Seam.from_api_key("your-api-key")
|
108
|
+
```
|
109
|
+
|
110
|
+
#### Personal Access Token
|
111
|
+
|
112
|
+
A Personal Access Token is scoped to a Seam Console user.
|
113
|
+
Obtain one from the Seam Console.
|
114
|
+
A workspace ID must be provided when using this method and all requests will be scoped to that workspace.
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
# Pass as an option to the constructor
|
118
|
+
seam = Seam.new(
|
119
|
+
personal_access_token: "your-personal-access-token",
|
120
|
+
workspace_id: "your-workspace-id"
|
121
|
+
)
|
122
|
+
|
123
|
+
# Use the factory method
|
124
|
+
seam = Seam.from_personal_access_token(
|
125
|
+
"your-personal-access-token",
|
126
|
+
"your-workspace-id"
|
127
|
+
)
|
128
|
+
```
|
129
|
+
|
130
|
+
### Action Attempts
|
131
|
+
|
132
|
+
Some asynchronous operations, e.g., unlocking a door, return an
|
133
|
+
[action attempt](https://docs.seam.co/latest/core-concepts/action-attempts).
|
134
|
+
Seam tracks the progress of the requested operation and updates the action attempt
|
135
|
+
when it succeeds or fails.
|
136
|
+
|
137
|
+
To make working with action attempts more convenient for applications,
|
138
|
+
this library provides the `wait_for_action_attempt` option and enables it by default.
|
139
|
+
|
140
|
+
When the `wait_for_action_attempt` option is enabled, the SDK:
|
141
|
+
|
142
|
+
- Polls the action attempt up to the `timeout`
|
143
|
+
at the `polling_interval` (both in seconds).
|
144
|
+
- Resolves with a fresh copy of the successful action attempt.
|
145
|
+
- Raises a `Seam::ActionAttemptFailedError` if the action attempt is unsuccessful.
|
146
|
+
- Raises a `Seam::ActionAttemptTimeoutError` if the action attempt is still pending when the `timeout` is reached.
|
147
|
+
- Both errors expose an `action_attempt` property.
|
148
|
+
|
149
|
+
If you already have an action attempt ID
|
150
|
+
and want to wait for it to resolve, simply use:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
seam.action_attempts.get(action_attempt_id: action_attempt_id)
|
154
|
+
```
|
155
|
+
|
156
|
+
Or, to get the current state of an action attempt by ID without waiting:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
seam.action_attempts.get(
|
160
|
+
action_attempt_id: action_attempt_id,
|
161
|
+
wait_for_action_attempt: false
|
162
|
+
)
|
163
|
+
```
|
164
|
+
|
165
|
+
To disable this behavior, set the default option for the client:
|
166
|
+
|
167
|
+
```ruby
|
168
|
+
seam = Seam.new(
|
169
|
+
api_key: "your-api-key",
|
170
|
+
wait_for_action_attempt: false
|
171
|
+
)
|
172
|
+
|
173
|
+
seam.locks.unlock_door(device_id: device_id)
|
174
|
+
```
|
175
|
+
|
176
|
+
or the behavior may be configured per-request:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
seam.locks.unlock_door(
|
180
|
+
device_id: device_id,
|
181
|
+
wait_for_action_attempt: false
|
182
|
+
)
|
183
|
+
```
|
184
|
+
|
185
|
+
The `polling_interval` and `timeout` may be configured for the client or per-request.
|
186
|
+
For example:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
require "seam"
|
190
|
+
|
191
|
+
seam = Seam.new("your-api-key")
|
192
|
+
|
193
|
+
locks = seam.locks.list
|
194
|
+
|
195
|
+
if locks.empty?
|
196
|
+
raise "No locks in this workspace"
|
197
|
+
end
|
198
|
+
|
199
|
+
lock = locks.first
|
200
|
+
|
201
|
+
begin
|
202
|
+
seam.locks.unlock_door(
|
203
|
+
device_id: lock.device_id,
|
204
|
+
wait_for_action_attempt: {
|
205
|
+
timeout: 5.0,
|
206
|
+
polling_interval: 1.0
|
207
|
+
}
|
208
|
+
)
|
209
|
+
|
210
|
+
puts "Door unlocked"
|
211
|
+
rescue Seam::ActionAttemptFailedError
|
212
|
+
puts "Could not unlock the door"
|
213
|
+
rescue Seam::ActionAttemptTimeoutError
|
214
|
+
puts "Door took too long to unlock"
|
215
|
+
end
|
216
|
+
```
|
217
|
+
|
218
|
+
### Interacting with Multiple Workspaces
|
219
|
+
|
220
|
+
Some Seam API endpoints interact with multiple workspaces. The `Seam::Http::SeamMultiWorkspace` client is not bound to a specific workspace and may use those endpoints with a personal access token authentication method.
|
221
|
+
|
222
|
+
A Personal Access Token is scoped to a Seam Console user. Obtain one from the Seam Console.
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
# Pass as an option to the constructor
|
226
|
+
seam = Seam::Http::SeamMultiWorkspace.new(personal_access_token: "your-personal-access-token")
|
227
|
+
|
228
|
+
# Use the factory method
|
229
|
+
seam = Seam::Http::SeamMultiWorkspace.from_personal_access_token("your-personal-access-token")
|
230
|
+
|
231
|
+
# List workspaces authorized for this Personal Access Token
|
232
|
+
workspaces = seam.workspaces.list
|
233
|
+
```
|
234
|
+
|
235
|
+
### Webhooks
|
236
|
+
|
237
|
+
The Seam API implements webhooks using [Svix](https://www.svix.com).This SDK exports a thin wrapper `Seam::Webhook` around the svix package.
|
238
|
+
Use it to parse and validate Seam webhook events.
|
239
|
+
|
240
|
+
> [!TIP]
|
241
|
+
> This example is for [Sinatra](https://sinatrarb.com/), see the [Svix docs for more examples in specific frameworks](https://docs.svix.com/receiving/verifying-payloads/how).
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
require "sinatra"
|
245
|
+
require "seam"
|
246
|
+
|
247
|
+
webhook = Seam::Webhook.new(ENV["SEAM_WEBHOOK_SECRET"])
|
248
|
+
|
249
|
+
post "/webhook" do
|
250
|
+
begin
|
251
|
+
headers = {
|
252
|
+
"svix-id" => request.env["HTTP_SVIX_ID"],
|
253
|
+
"svix-signature" => request.env["HTTP_SVIX_SIGNATURE"],
|
254
|
+
"svix-timestamp" => request.env["HTTP_SVIX_TIMESTAMP"]
|
255
|
+
}
|
256
|
+
data = webhook.verify(request.body.read, headers)
|
257
|
+
rescue Seam::WebhookVerificationError
|
258
|
+
halt 400, "Bad Request"
|
259
|
+
end
|
260
|
+
|
261
|
+
begin
|
262
|
+
store_event(data)
|
263
|
+
rescue
|
264
|
+
halt 500, "Internal Server Error"
|
265
|
+
end
|
266
|
+
|
267
|
+
204
|
268
|
+
end
|
269
|
+
|
270
|
+
def store_event(data)
|
271
|
+
puts data
|
272
|
+
end
|
273
|
+
```
|
274
|
+
|
275
|
+
### Advanced Usage
|
276
|
+
|
277
|
+
#### Additional Options
|
278
|
+
|
279
|
+
In addition to the various authentication options,
|
280
|
+
the constructor takes some advanced options that affect behavior.
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
seam = Seam.new(
|
284
|
+
api_key: "your-api-key",
|
285
|
+
endpoint: "https://example.com",
|
286
|
+
faraday_options: {},
|
287
|
+
faraday_retry_options: {}
|
288
|
+
)
|
289
|
+
```
|
290
|
+
|
291
|
+
When using the static factory methods,
|
292
|
+
these options may be passed in as keyword arguments.
|
293
|
+
|
294
|
+
```ruby
|
295
|
+
seam = Seam.from_api_key("some-api-key",
|
296
|
+
endpoint: "https://example.com",
|
297
|
+
faraday_options: {},
|
298
|
+
faraday_retry_options: {})
|
299
|
+
```
|
300
|
+
|
301
|
+
#### Setting the endpoint
|
302
|
+
|
303
|
+
Some contexts may need to override the API endpoint,
|
304
|
+
e.g., testing or proxy setups. This option corresponds to the [Faraday](https://lostisland.github.io/faraday/#/) `url` setting.
|
305
|
+
|
306
|
+
Either pass the `endpoint` option, or set the `SEAM_ENDPOINT` environment variable.
|
307
|
+
|
308
|
+
#### Configuring the Faraday Client
|
309
|
+
|
310
|
+
The Faraday client and retry behavior may be configured with custom initiation options
|
311
|
+
via [`faraday_option`][faraday_option] and [`faraday_retry_option`][faraday_retry_option].
|
312
|
+
|
313
|
+
[faraday_option]: https://lostisland.github.io/faraday/#/customization/connection-options?id=connection-options
|
314
|
+
[faraday_retry_option]: https://github.com/lostisland/faraday-retry
|
315
|
+
|
316
|
+
#### Using the Faraday Client
|
317
|
+
|
318
|
+
The Faraday client is exposed and may be used or configured directly:
|
319
|
+
|
320
|
+
```ruby
|
321
|
+
require "seam"
|
322
|
+
require "faraday"
|
323
|
+
|
324
|
+
class MyMiddleware < Faraday::Middleware
|
325
|
+
def on_complete(env)
|
326
|
+
puts env.response.inspect
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
seam = Seam.new
|
331
|
+
|
332
|
+
seam.client.builder.use MyMiddleware
|
333
|
+
|
334
|
+
devices = seam.client.get("/devices/list").body["devices"]
|
335
|
+
```
|
336
|
+
|
337
|
+
#### Overriding the Client
|
338
|
+
|
339
|
+
A Faraday compatible client may be provided to create a `Seam` instance.
|
340
|
+
This API is used internally and is not directly supported.
|
21
341
|
|
22
342
|
## Development and Testing
|
23
343
|
|
data/Rakefile
CHANGED
data/lib/seam/auth.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "options"
|
4
|
+
require_relative "token"
|
5
|
+
|
6
|
+
module Seam
|
7
|
+
module Http
|
8
|
+
module Auth
|
9
|
+
class SeamInvalidTokenError < StandardError
|
10
|
+
def initialize(message)
|
11
|
+
super("Seam received an invalid token: #{message}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.get_auth_headers(api_key: nil, personal_access_token: nil, workspace_id: nil)
|
16
|
+
if Http::Options.seam_http_options_with_api_key?(api_key: api_key, personal_access_token: personal_access_token)
|
17
|
+
return get_auth_headers_for_api_key(api_key)
|
18
|
+
end
|
19
|
+
|
20
|
+
if Http::Options.seam_http_options_with_personal_access_token?(personal_access_token: personal_access_token, api_key: api_key,
|
21
|
+
workspace_id: workspace_id)
|
22
|
+
return get_auth_headers_for_personal_access_token(personal_access_token, workspace_id)
|
23
|
+
end
|
24
|
+
|
25
|
+
raise Http::Options::SeamInvalidOptionsError.new(
|
26
|
+
"Must specify an api_key or personal_access_token. " \
|
27
|
+
"Attempted reading configuration from the environment, " \
|
28
|
+
"but the environment variable SEAM_API_KEY is not set."
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.get_auth_headers_for_api_key(api_key)
|
33
|
+
if Auth.client_session_token?(api_key)
|
34
|
+
raise SeamInvalidTokenError.new(
|
35
|
+
"A Client Session Token cannot be used as an api_key"
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
raise SeamInvalidTokenError.new("A JWT cannot be used as an api_key") if Auth.jwt?(api_key)
|
40
|
+
|
41
|
+
raise SeamInvalidTokenError.new("An Access Token cannot be used as an api_key") if Auth.access_token?(api_key)
|
42
|
+
|
43
|
+
if Auth.publishable_key?(api_key)
|
44
|
+
raise SeamInvalidTokenError.new(
|
45
|
+
"A Publishable Key cannot be used as an api_key"
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
unless Auth.seam_token?(api_key)
|
50
|
+
raise SeamInvalidTokenError.new(
|
51
|
+
"Unknown or invalid api_key format, expected token to start with #{Auth::TOKEN_PREFIX}"
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
{"authorization" => "Bearer #{api_key}"}
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.get_auth_headers_for_personal_access_token(personal_access_token, workspace_id)
|
59
|
+
if Auth.jwt?(personal_access_token)
|
60
|
+
raise SeamInvalidTokenError.new(
|
61
|
+
"A JWT cannot be used as a personal_access_token"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
if Auth.client_session_token?(personal_access_token)
|
66
|
+
raise SeamInvalidTokenError.new(
|
67
|
+
"A Client Session Token cannot be used as a personal_access_token"
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
if Auth.publishable_key?(personal_access_token)
|
72
|
+
raise SeamInvalidTokenError.new(
|
73
|
+
"A Publishable Key cannot be used as a personal_access_token"
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
unless Auth.access_token?(personal_access_token)
|
78
|
+
raise SeamInvalidTokenError.new(
|
79
|
+
"Unknown or invalid personal_access_token format, expected token to start with #{Auth::ACCESS_TOKEN_PREFIX}"
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
{
|
84
|
+
"authorization" => "Bearer #{personal_access_token}",
|
85
|
+
"seam-workspace" => workspace_id
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.get_auth_headers_for_multi_workspace_personal_access_token(personal_access_token)
|
90
|
+
if Auth.jwt?(personal_access_token)
|
91
|
+
raise SeamInvalidTokenError.new(
|
92
|
+
"A JWT cannot be used as a personal_access_token"
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
if Auth.client_session_token?(personal_access_token)
|
97
|
+
raise SeamInvalidTokenError.new(
|
98
|
+
"A Client Session Token cannot be used as a personal_access_token"
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
if Auth.publishable_key?(personal_access_token)
|
103
|
+
raise SeamInvalidTokenError.new(
|
104
|
+
"A Publishable Key cannot be used as a personal_access_token"
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
unless Auth.access_token?(personal_access_token)
|
109
|
+
raise SeamInvalidTokenError.new(
|
110
|
+
"Unknown or invalid personal_access_token format, expected token to start with #{Auth::ACCESS_TOKEN_PREFIX}"
|
111
|
+
)
|
112
|
+
end
|
113
|
+
|
114
|
+
{"authorization" => "Bearer #{personal_access_token}"}
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|