vortex-ruby-sdk 1.1.3 → 1.5.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/CHANGELOG.md +12 -0
- data/README.md +5 -17
- data/lib/vortex/client.rb +107 -1
- data/lib/vortex/types.rb +32 -2
- data/lib/vortex/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ac2c594fa0a88757da59e6df7f87e0d232b25e53035b560bce733c582d953320
|
|
4
|
+
data.tar.gz: 356960f55a08e9c475bf4be6b126510d36ad8251d2988d44c3ede9f3d00598e4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5b8fd2f00a23144c21d87a3cd127bef7dc25d935d78e9a0120048e075c756a5e5db1f3bf6b0a466e7788c626a75e1f91b019acadf2f334ddb9da811ee37fcd0
|
|
7
|
+
data.tar.gz: b4c4a42a681f9cd772cd2310b00692f149e48171ce5c0659f94dc3995a307a5d6c986aa96984aaf403a0ed610c0491718c8c0323771ba308c25a09f586724265
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to the Vortex Ruby SDK will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.2.0] - 2026-01-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **Internal Invitations**: New `'internal'` delivery type for customer-managed invitations
|
|
12
|
+
- Support for `deliveryTypes: ['internal']`
|
|
13
|
+
- No email/SMS communication triggered by Vortex
|
|
14
|
+
- Target value can be any customer-defined identifier
|
|
15
|
+
- Useful for in-app invitation flows managed by customer's application
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- Updated `deliveryTypes` field documentation to include `'internal'` as a valid value
|
|
19
|
+
|
|
8
20
|
## [1.1.3] - 2025-01-29
|
|
9
21
|
|
|
10
22
|
### Added
|
data/README.md
CHANGED
|
@@ -12,6 +12,8 @@ A Ruby SDK for the Vortex invitation system, providing seamless integration with
|
|
|
12
12
|
- **Same Route Structure**: Ensures React provider compatibility
|
|
13
13
|
- **Comprehensive Testing**: Full test coverage with RSpec
|
|
14
14
|
- **Type Safety**: Clear method signatures and documentation
|
|
15
|
+
- **Multiple Delivery Types**: Support for `email`, `phone`, `share`, and `internal` invitation delivery
|
|
16
|
+
- `internal` invitations allow for customer-managed, in-app invitation flows with no external communication
|
|
15
17
|
|
|
16
18
|
## Installation
|
|
17
19
|
|
|
@@ -45,7 +47,9 @@ client = Vortex::Client.new(ENV['VORTEX_API_KEY'])
|
|
|
45
47
|
user = {
|
|
46
48
|
id: 'user-123',
|
|
47
49
|
email: 'user@example.com',
|
|
48
|
-
|
|
50
|
+
user_name: 'Jane Doe', # Optional: user's display name
|
|
51
|
+
user_avatar_url: 'https://example.com/avatars/jane.jpg', # Optional: user's avatar URL
|
|
52
|
+
admin_scopes: ['autojoin'] # Optional: grants autojoin admin privileges
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
# Generate JWT
|
|
@@ -61,22 +65,6 @@ client.accept_invitations(['inv1', 'inv2'], { type: 'email', value: 'user@exampl
|
|
|
61
65
|
group_invitations = client.get_invitations_by_group('team', 'team1')
|
|
62
66
|
```
|
|
63
67
|
|
|
64
|
-
### Generate JWT with Additional Properties
|
|
65
|
-
|
|
66
|
-
```ruby
|
|
67
|
-
user = {
|
|
68
|
-
id: 'user-123',
|
|
69
|
-
email: 'user@example.com'
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
extra = {
|
|
73
|
-
role: 'admin',
|
|
74
|
-
department: 'Engineering'
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
jwt = client.generate_jwt(user: user, extra: extra)
|
|
78
|
-
```
|
|
79
|
-
|
|
80
68
|
## Rails Integration
|
|
81
69
|
|
|
82
70
|
Create a controller with Vortex routes:
|
data/lib/vortex/client.rb
CHANGED
|
@@ -80,6 +80,16 @@ module Vortex
|
|
|
80
80
|
expires: expires
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
# Add name if present (convert snake_case to camelCase for JWT)
|
|
84
|
+
if user[:user_name]
|
|
85
|
+
payload[:userName] = user[:user_name]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Add userAvatarUrl if present (convert snake_case to camelCase for JWT)
|
|
89
|
+
if user[:user_avatar_url]
|
|
90
|
+
payload[:userAvatarUrl] = user[:user_avatar_url]
|
|
91
|
+
end
|
|
92
|
+
|
|
83
93
|
# Add adminScopes if present
|
|
84
94
|
if user[:admin_scopes]
|
|
85
95
|
payload[:adminScopes] = user[:admin_scopes]
|
|
@@ -204,7 +214,7 @@ module Vortex
|
|
|
204
214
|
case target_type
|
|
205
215
|
when 'email'
|
|
206
216
|
user[:email] = target_value
|
|
207
|
-
when '
|
|
217
|
+
when 'phone', 'phoneNumber'
|
|
208
218
|
user[:phone] = target_value
|
|
209
219
|
else
|
|
210
220
|
# For other types, try to use as email
|
|
@@ -277,6 +287,102 @@ module Vortex
|
|
|
277
287
|
raise VortexError, "Failed to reinvite: #{e.message}"
|
|
278
288
|
end
|
|
279
289
|
|
|
290
|
+
# Create an invitation from your backend
|
|
291
|
+
#
|
|
292
|
+
# This method allows you to create invitations programmatically using your API key,
|
|
293
|
+
# without requiring a user JWT token. Useful for server-side invitation creation,
|
|
294
|
+
# such as "People You May Know" flows or admin-initiated invitations.
|
|
295
|
+
#
|
|
296
|
+
# Target types:
|
|
297
|
+
# - 'email': Send an email invitation
|
|
298
|
+
# - 'phone': Create a phone invitation (short link returned for you to send)
|
|
299
|
+
# - 'internal': Create an internal invitation for PYMK flows (no email sent)
|
|
300
|
+
#
|
|
301
|
+
# @param widget_configuration_id [String] The widget configuration ID to use
|
|
302
|
+
# @param target [Hash] The invitation target: { type: 'email|sms|internal', value: '...' }
|
|
303
|
+
# @param inviter [Hash] The inviter info: { user_id: '...', user_email: '...', name: '...' }
|
|
304
|
+
# @param groups [Array<Hash>, nil] Optional groups: [{ type: '...', group_id: '...', name: '...' }]
|
|
305
|
+
# @param source [String, nil] Optional source for analytics (defaults to 'api')
|
|
306
|
+
# @param subtype [String, nil] Optional subtype for analytics segmentation (e.g., 'pymk', 'find-friends')
|
|
307
|
+
# @param template_variables [Hash, nil] Optional template variables for email customization
|
|
308
|
+
# @param metadata [Hash, nil] Optional metadata passed through to webhooks
|
|
309
|
+
# @param unfurl_config [Hash, nil] Optional link unfurl (Open Graph) config: { title: '...', description: '...', image: '...', type: '...', site_name: '...' }
|
|
310
|
+
# @return [Hash] Created invitation with :id, :short_link, :status, :created_at
|
|
311
|
+
# @raise [VortexError] If the request fails
|
|
312
|
+
#
|
|
313
|
+
# @example Create an email invitation with custom link preview
|
|
314
|
+
# result = client.create_invitation(
|
|
315
|
+
# 'widget-config-123',
|
|
316
|
+
# { type: 'email', value: 'invitee@example.com' },
|
|
317
|
+
# { user_id: 'user-456', user_email: 'inviter@example.com', name: 'John Doe' },
|
|
318
|
+
# [{ type: 'team', group_id: 'team-789', name: 'Engineering' }],
|
|
319
|
+
# nil,
|
|
320
|
+
# nil,
|
|
321
|
+
# nil,
|
|
322
|
+
# { title: 'Join the team!', description: 'You have been invited', image: 'https://example.com/og.png' }
|
|
323
|
+
# )
|
|
324
|
+
#
|
|
325
|
+
# @example Create an internal invitation (PYMK flow - no email sent)
|
|
326
|
+
# result = client.create_invitation(
|
|
327
|
+
# 'widget-config-123',
|
|
328
|
+
# { type: 'internal', value: 'internal-user-abc' },
|
|
329
|
+
# { user_id: 'user-456' },
|
|
330
|
+
# nil,
|
|
331
|
+
# 'pymk'
|
|
332
|
+
# )
|
|
333
|
+
def create_invitation(widget_configuration_id, target, inviter, groups = nil, source = nil, subtype = nil, template_variables = nil, metadata = nil, unfurl_config = nil)
|
|
334
|
+
raise VortexError, 'widget_configuration_id is required' if widget_configuration_id.nil? || widget_configuration_id.empty?
|
|
335
|
+
raise VortexError, 'target must have type and value' if target[:type].nil? || target[:value].nil?
|
|
336
|
+
raise VortexError, 'inviter must have user_id' if inviter[:user_id].nil?
|
|
337
|
+
|
|
338
|
+
# Build request body with camelCase keys for the API
|
|
339
|
+
body = {
|
|
340
|
+
widgetConfigurationId: widget_configuration_id,
|
|
341
|
+
target: target,
|
|
342
|
+
inviter: {
|
|
343
|
+
userId: inviter[:user_id],
|
|
344
|
+
userEmail: inviter[:user_email],
|
|
345
|
+
userName: inviter[:user_name],
|
|
346
|
+
userAvatarUrl: inviter[:user_avatar_url]
|
|
347
|
+
}.compact
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if groups && !groups.empty?
|
|
351
|
+
body[:groups] = groups.map do |g|
|
|
352
|
+
{
|
|
353
|
+
type: g[:type],
|
|
354
|
+
groupId: g[:group_id],
|
|
355
|
+
name: g[:name]
|
|
356
|
+
}
|
|
357
|
+
end
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
body[:source] = source if source
|
|
361
|
+
body[:subtype] = subtype if subtype
|
|
362
|
+
body[:templateVariables] = template_variables if template_variables
|
|
363
|
+
body[:metadata] = metadata if metadata
|
|
364
|
+
if unfurl_config
|
|
365
|
+
body[:unfurlConfig] = {
|
|
366
|
+
title: unfurl_config[:title],
|
|
367
|
+
description: unfurl_config[:description],
|
|
368
|
+
image: unfurl_config[:image],
|
|
369
|
+
type: unfurl_config[:type],
|
|
370
|
+
siteName: unfurl_config[:site_name]
|
|
371
|
+
}.compact
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
response = @connection.post('/api/v1/invitations') do |req|
|
|
375
|
+
req.headers['Content-Type'] = 'application/json'
|
|
376
|
+
req.body = JSON.generate(body)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
handle_response(response)
|
|
380
|
+
rescue VortexError
|
|
381
|
+
raise
|
|
382
|
+
rescue => e
|
|
383
|
+
raise VortexError, "Failed to create invitation: #{e.message}"
|
|
384
|
+
end
|
|
385
|
+
|
|
280
386
|
private
|
|
281
387
|
|
|
282
388
|
def build_connection
|
data/lib/vortex/types.rb
CHANGED
|
@@ -60,6 +60,21 @@ module Vortex
|
|
|
60
60
|
# groups: [INVITATION_GROUP, ...],
|
|
61
61
|
# # ... other fields
|
|
62
62
|
# }
|
|
63
|
+
# InvitationTarget represents the target of an invitation
|
|
64
|
+
# @example
|
|
65
|
+
# {
|
|
66
|
+
# type: 'email', # 'email', 'phone', 'share', or 'internal'
|
|
67
|
+
# value: 'user@example.com',
|
|
68
|
+
# name: 'Jane Smith', # Optional: Display name of the person being invited
|
|
69
|
+
# avatarUrl: 'https://...' # Optional: Avatar URL for display in invitation lists
|
|
70
|
+
# }
|
|
71
|
+
INVITATION_TARGET = {
|
|
72
|
+
type: String, # Required: 'email', 'phone', 'share', or 'internal'
|
|
73
|
+
value: String, # Required: Email, phone, or internal ID
|
|
74
|
+
name: String, # Optional: Display name of the person being invited
|
|
75
|
+
avatarUrl: String # Optional: Avatar URL for the person being invited
|
|
76
|
+
}.freeze
|
|
77
|
+
|
|
63
78
|
INVITATION = {
|
|
64
79
|
id: String,
|
|
65
80
|
accountId: String,
|
|
@@ -69,12 +84,12 @@ module Vortex
|
|
|
69
84
|
createdAt: String,
|
|
70
85
|
deactivated: :boolean,
|
|
71
86
|
deliveryCount: Integer,
|
|
72
|
-
deliveryTypes: Array, # of String
|
|
87
|
+
deliveryTypes: Array, # of String - valid values: "email", "phone", "share", "internal"
|
|
73
88
|
foreignCreatorId: String,
|
|
74
89
|
invitationType: String,
|
|
75
90
|
modifiedAt: String,
|
|
76
91
|
status: String,
|
|
77
|
-
target: Array, # of
|
|
92
|
+
target: Array, # of INVITATION_TARGET structures
|
|
78
93
|
views: Integer,
|
|
79
94
|
widgetConfigurationId: String,
|
|
80
95
|
projectId: String,
|
|
@@ -83,5 +98,20 @@ module Vortex
|
|
|
83
98
|
expired: :boolean,
|
|
84
99
|
expires: String # ISO 8601 timestamp (optional)
|
|
85
100
|
}.freeze
|
|
101
|
+
|
|
102
|
+
# CreateInvitationTarget for creating invitations
|
|
103
|
+
# @example
|
|
104
|
+
# {
|
|
105
|
+
# type: 'email',
|
|
106
|
+
# value: 'invitee@example.com',
|
|
107
|
+
# name: 'Jane Smith', # Optional
|
|
108
|
+
# avatarUrl: 'https://...' # Optional
|
|
109
|
+
# }
|
|
110
|
+
CREATE_INVITATION_TARGET = {
|
|
111
|
+
type: String, # Required: 'email', 'phone', or 'internal'
|
|
112
|
+
value: String, # Required: Email, phone, or internal ID
|
|
113
|
+
name: String, # Optional: Display name of the person being invited
|
|
114
|
+
avatarUrl: String # Optional: Avatar URL for the person being invited
|
|
115
|
+
}.freeze
|
|
86
116
|
end
|
|
87
117
|
end
|
data/lib/vortex/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: vortex-ruby-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Vortex Software
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-02-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|