postproxy-sdk 1.7.0 → 1.8.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/README.md +64 -1
- data/lib/postproxy/client.rb +6 -0
- data/lib/postproxy/constants.rb +19 -1
- data/lib/postproxy/resources/profile_groups.rb +20 -3
- data/lib/postproxy/resources/profiles.rb +14 -0
- data/lib/postproxy/types.rb +60 -2
- data/lib/postproxy/version.rb +1 -1
- data/lib/postproxy/webhook_events.rb +113 -0
- data/lib/postproxy.rb +1 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d2f9ae8cbbc2ca3cd324b5dc522226c9d7a77cd93430abb309b31efc210a293
|
|
4
|
+
data.tar.gz: 26c58e5f9b7ea1af4eccb3935ef8c71bf202bf5bff93898d0b30a5450114bb1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 906800719560c2e37351c958fa72449d1411b351c1cad4deb0d312e9b6fcaa3af3be3dcb504eeef045a3d24737815afb4e7f772edae4687e102e2f9d4bd605cc
|
|
7
|
+
data.tar.gz: b6ee51b608b91a9d31ed2891b7bba87df996006be1795504f540e275dd54c8ff3b7ef7e5f1994a7aa495a02f67ec8f3921e9017baadb3e1e8d3c5550d6959b06
|
data/README.md
CHANGED
|
@@ -260,6 +260,26 @@ PostProxy::WebhookSignature.verify(
|
|
|
260
260
|
)
|
|
261
261
|
```
|
|
262
262
|
|
|
263
|
+
### Event types and typed payloads
|
|
264
|
+
|
|
265
|
+
Subscribe to any of these events (or pass `["*"]` for all):
|
|
266
|
+
|
|
267
|
+
`post.processed`, `post.imported`, `platform_post.published`, `platform_post.failed`, `platform_post.failed_waiting_for_retry`, `platform_post.insights`, `profile.connected`, `profile.disconnected`, `profile.stats`, `media.failed`, `comment.created`.
|
|
268
|
+
|
|
269
|
+
`PostProxy::WebhookEvents.parse` validates the envelope and returns a typed `Event` — `event.data` is the right model for the event:
|
|
270
|
+
|
|
271
|
+
```ruby
|
|
272
|
+
event = PostProxy::WebhookEvents.parse(request.body.read)
|
|
273
|
+
case event.type
|
|
274
|
+
when "profile.stats"
|
|
275
|
+
puts "#{event.data.profile_id}: #{event.data.stats}"
|
|
276
|
+
when "platform_post.published"
|
|
277
|
+
puts "Published: #{event.data.platform_id}"
|
|
278
|
+
when "comment.created"
|
|
279
|
+
puts "#{event.data.author_username}: #{event.data.body}"
|
|
280
|
+
end
|
|
281
|
+
```
|
|
282
|
+
|
|
263
283
|
## Comments
|
|
264
284
|
|
|
265
285
|
```ruby
|
|
@@ -311,6 +331,19 @@ placements = client.profiles.placements("prof-id").data
|
|
|
311
331
|
|
|
312
332
|
# Delete a profile
|
|
313
333
|
client.profiles.delete("prof-id")
|
|
334
|
+
|
|
335
|
+
# Profile stats timeseries — placement_id required for facebook, linkedin, telegram
|
|
336
|
+
stats = client.profiles.get_profile_stats("prof_li_001",
|
|
337
|
+
placement_id: "108520199",
|
|
338
|
+
from: "2026-04-01T00:00:00Z"
|
|
339
|
+
)
|
|
340
|
+
stats.data.records.each do |r|
|
|
341
|
+
puts "#{r.recorded_at}: #{r.stats[:followerCount]}"
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# Bluesky — no placements
|
|
345
|
+
bsky = client.profiles.get_profile_stats("prof_bsky_001")
|
|
346
|
+
puts bsky.data.records.last.stats[:followersCount]
|
|
314
347
|
```
|
|
315
348
|
|
|
316
349
|
## Profile Groups
|
|
@@ -335,6 +368,28 @@ connection = client.profile_groups.initialize_connection(
|
|
|
335
368
|
redirect_url: "https://myapp.com/callback"
|
|
336
369
|
)
|
|
337
370
|
# Redirect user to connection.url
|
|
371
|
+
|
|
372
|
+
# BlueSky — app password (synchronous, no OAuth)
|
|
373
|
+
bsky = client.profile_groups.connect_bluesky("pg-id",
|
|
374
|
+
identifier: "yourname.bsky.social",
|
|
375
|
+
app_password: "xxxx-xxxx-xxxx-xxxx"
|
|
376
|
+
)
|
|
377
|
+
puts bsky.profile.id
|
|
378
|
+
|
|
379
|
+
# Telegram — bring-your-own-bot. Channels populate asynchronously; poll
|
|
380
|
+
# placements until non-empty.
|
|
381
|
+
tg = client.profile_groups.connect_telegram("pg-id",
|
|
382
|
+
bot_token: "123456789:ABCdef-GhIJklMnOpQrStUvWxYz"
|
|
383
|
+
)
|
|
384
|
+
puts tg.next_step
|
|
385
|
+
|
|
386
|
+
placements = []
|
|
387
|
+
loop do
|
|
388
|
+
placements = client.profiles.placements(tg.profile.id).data
|
|
389
|
+
break unless placements.empty?
|
|
390
|
+
sleep 3
|
|
391
|
+
end
|
|
392
|
+
puts "Channels: #{placements.map { |p| [p.id, p.name] }}"
|
|
338
393
|
```
|
|
339
394
|
|
|
340
395
|
## Platform Parameters
|
|
@@ -364,7 +419,13 @@ platforms = PostProxy::PlatformParams.new(
|
|
|
364
419
|
board_id: "board-123"
|
|
365
420
|
),
|
|
366
421
|
threads: PostProxy::ThreadsParams.new(format: "post"),
|
|
367
|
-
twitter: PostProxy::TwitterParams.new(format: "post")
|
|
422
|
+
twitter: PostProxy::TwitterParams.new(format: "post"),
|
|
423
|
+
bluesky: PostProxy::BlueskyParams.new(format: "post"),
|
|
424
|
+
telegram: PostProxy::TelegramParams.new(
|
|
425
|
+
chat_id: "-1001234567890",
|
|
426
|
+
parse_mode: "HTML",
|
|
427
|
+
disable_link_preview: true
|
|
428
|
+
)
|
|
368
429
|
)
|
|
369
430
|
|
|
370
431
|
post = client.posts.create(
|
|
@@ -374,6 +435,8 @@ post = client.posts.create(
|
|
|
374
435
|
)
|
|
375
436
|
```
|
|
376
437
|
|
|
438
|
+
Supported platforms: `facebook`, `instagram`, `tiktok`, `linkedin`, `youtube`, `twitter`, `threads`, `pinterest`, `bluesky`, `telegram`. Telegram requires a `chat_id` per post — list channels with `client.profiles.placements(profile_id)`.
|
|
439
|
+
|
|
377
440
|
## Error Handling
|
|
378
441
|
|
|
379
442
|
```ruby
|
data/lib/postproxy/client.rb
CHANGED
|
@@ -99,11 +99,16 @@ module PostProxy
|
|
|
99
99
|
|
|
100
100
|
private
|
|
101
101
|
|
|
102
|
+
def user_agent
|
|
103
|
+
@user_agent ||= "postproxy-ruby/#{PostProxy::VERSION} (ruby/#{RUBY_VERSION})"
|
|
104
|
+
end
|
|
105
|
+
|
|
102
106
|
def json_connection
|
|
103
107
|
@faraday_client || Faraday.new(url: @base_url) do |f|
|
|
104
108
|
f.request :url_encoded
|
|
105
109
|
f.headers["Authorization"] = "Bearer #{@api_key}"
|
|
106
110
|
f.headers["Content-Type"] = "application/json"
|
|
111
|
+
f.headers["User-Agent"] = user_agent
|
|
107
112
|
f.adapter Faraday.default_adapter
|
|
108
113
|
end
|
|
109
114
|
end
|
|
@@ -112,6 +117,7 @@ module PostProxy
|
|
|
112
117
|
@faraday_client || Faraday.new(url: @base_url) do |f|
|
|
113
118
|
f.request :multipart
|
|
114
119
|
f.headers["Authorization"] = "Bearer #{@api_key}"
|
|
120
|
+
f.headers["User-Agent"] = user_agent
|
|
115
121
|
f.adapter Faraday.default_adapter
|
|
116
122
|
end
|
|
117
123
|
end
|
data/lib/postproxy/constants.rb
CHANGED
|
@@ -2,7 +2,7 @@ module PostProxy
|
|
|
2
2
|
DEFAULT_BASE_URL = "https://api.postproxy.dev"
|
|
3
3
|
|
|
4
4
|
PLATFORMS = %w[
|
|
5
|
-
facebook instagram tiktok linkedin youtube twitter threads pinterest
|
|
5
|
+
facebook instagram tiktok linkedin youtube twitter threads pinterest bluesky telegram
|
|
6
6
|
].freeze
|
|
7
7
|
|
|
8
8
|
PROFILE_STATUSES = %w[active expired inactive].freeze
|
|
@@ -21,10 +21,28 @@ module PostProxy
|
|
|
21
21
|
PINTEREST_FORMATS = %w[pin].freeze
|
|
22
22
|
THREADS_FORMATS = %w[post].freeze
|
|
23
23
|
TWITTER_FORMATS = %w[post].freeze
|
|
24
|
+
BLUESKY_FORMATS = %w[post].freeze
|
|
25
|
+
TELEGRAM_FORMATS = %w[post].freeze
|
|
24
26
|
|
|
25
27
|
TIKTOK_PRIVACIES = %w[
|
|
26
28
|
PUBLIC_TO_EVERYONE MUTUAL_FOLLOW_FRIENDS FOLLOWER_OF_CREATOR SELF_ONLY
|
|
27
29
|
].freeze
|
|
28
30
|
|
|
29
31
|
YOUTUBE_PRIVACIES = %w[public unlisted private].freeze
|
|
32
|
+
|
|
33
|
+
TELEGRAM_PARSE_MODES = %w[HTML MarkdownV2].freeze
|
|
34
|
+
|
|
35
|
+
WEBHOOK_EVENT_TYPES = %w[
|
|
36
|
+
post.processed
|
|
37
|
+
post.imported
|
|
38
|
+
platform_post.published
|
|
39
|
+
platform_post.failed
|
|
40
|
+
platform_post.failed_waiting_for_retry
|
|
41
|
+
platform_post.insights
|
|
42
|
+
profile.connected
|
|
43
|
+
profile.disconnected
|
|
44
|
+
profile.stats
|
|
45
|
+
media.failed
|
|
46
|
+
comment.created
|
|
47
|
+
].freeze
|
|
30
48
|
end
|
|
@@ -26,11 +26,28 @@ module PostProxy
|
|
|
26
26
|
DeleteResponse.new(**result)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
# OAuth flow. BlueSky and Telegram use their dedicated helpers below.
|
|
30
|
+
def initialize_connection(id, platform:, redirect_url: nil)
|
|
31
|
+
body = { platform: platform }
|
|
32
|
+
body[:redirect_url] = redirect_url if redirect_url
|
|
33
|
+
result = @client.request(:post, "/profile_groups/#{id}/initialize_connection", json: body)
|
|
34
|
+
ConnectionResponse.new(**result)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def connect_bluesky(id, identifier:, app_password:)
|
|
30
38
|
result = @client.request(:post, "/profile_groups/#{id}/initialize_connection",
|
|
31
|
-
json: { platform:
|
|
39
|
+
json: { platform: "bluesky", identifier: identifier, app_password: app_password }
|
|
32
40
|
)
|
|
33
|
-
|
|
41
|
+
BlueskyConnectionResponse.new(**result)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# After this call, poll `client.profiles.placements(profile.id)` until non-empty —
|
|
45
|
+
# the bot must be added as administrator to a channel in Telegram first.
|
|
46
|
+
def connect_telegram(id, bot_token:)
|
|
47
|
+
result = @client.request(:post, "/profile_groups/#{id}/initialize_connection",
|
|
48
|
+
json: { platform: "telegram", bot_token: bot_token }
|
|
49
|
+
)
|
|
50
|
+
TelegramConnectionResponse.new(**result)
|
|
34
51
|
end
|
|
35
52
|
end
|
|
36
53
|
end
|
|
@@ -22,6 +22,20 @@ module PostProxy
|
|
|
22
22
|
ListResponse.new(data: items)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# `placement_id` is required for facebook, linkedin, and telegram profiles.
|
|
26
|
+
def get_profile_stats(id, placement_id: nil, from: nil, to: nil, profile_group_id: nil)
|
|
27
|
+
params = {}
|
|
28
|
+
params[:placement_id] = placement_id if placement_id
|
|
29
|
+
params[:from] = from if from
|
|
30
|
+
params[:to] = to if to
|
|
31
|
+
|
|
32
|
+
result = @client.request(:get, "/profiles/#{id}/stats",
|
|
33
|
+
params: params.empty? ? nil : params,
|
|
34
|
+
profile_group_id: profile_group_id
|
|
35
|
+
)
|
|
36
|
+
ProfileStatsResponse.new(data: result[:data])
|
|
37
|
+
end
|
|
38
|
+
|
|
25
39
|
def delete(id, profile_group_id: nil)
|
|
26
40
|
result = @client.request(:delete, "/profiles/#{id}", profile_group_id: profile_group_id)
|
|
27
41
|
SuccessResponse.new(**result)
|
data/lib/postproxy/types.rb
CHANGED
|
@@ -350,10 +350,60 @@ module PostProxy
|
|
|
350
350
|
attr_accessor :success
|
|
351
351
|
end
|
|
352
352
|
|
|
353
|
+
# OAuth-style connection response (facebook, instagram, twitter, etc.).
|
|
353
354
|
class ConnectionResponse < Model
|
|
354
355
|
attr_accessor :url, :success
|
|
355
356
|
end
|
|
356
357
|
|
|
358
|
+
# Alias for clarity at call sites; same shape as ConnectionResponse.
|
|
359
|
+
OAuthConnectionResponse = ConnectionResponse
|
|
360
|
+
|
|
361
|
+
class SyncProfile < Model
|
|
362
|
+
attr_accessor :id, :network, :name, :external_username
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
class BlueskyConnectionResponse < Model
|
|
366
|
+
attr_accessor :success, :profile
|
|
367
|
+
|
|
368
|
+
def initialize(**attrs)
|
|
369
|
+
@profile = nil
|
|
370
|
+
super
|
|
371
|
+
@profile = SyncProfile.new(**@profile.transform_keys(&:to_sym)) if @profile.is_a?(Hash)
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
class TelegramConnectionResponse < Model
|
|
376
|
+
attr_accessor :success, :profile, :next_step
|
|
377
|
+
|
|
378
|
+
def initialize(**attrs)
|
|
379
|
+
@profile = nil
|
|
380
|
+
@next_step = nil
|
|
381
|
+
super
|
|
382
|
+
@profile = SyncProfile.new(**@profile.transform_keys(&:to_sym)) if @profile.is_a?(Hash)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
class ProfileStats < Model
|
|
387
|
+
attr_accessor :profile_id, :platform, :placement_id, :records
|
|
388
|
+
|
|
389
|
+
def initialize(**attrs)
|
|
390
|
+
@placement_id = nil
|
|
391
|
+
@records = []
|
|
392
|
+
super
|
|
393
|
+
@records = (@records || []).map do |r|
|
|
394
|
+
r.is_a?(StatsRecord) ? r : StatsRecord.new(**r.transform_keys(&:to_sym))
|
|
395
|
+
end
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
class ProfileStatsResponse
|
|
400
|
+
attr_reader :data
|
|
401
|
+
|
|
402
|
+
def initialize(data:)
|
|
403
|
+
@data = data.is_a?(ProfileStats) ? data : ProfileStats.new(**data.transform_keys(&:to_sym))
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
357
407
|
# Platform-specific parameter structs
|
|
358
408
|
|
|
359
409
|
class FacebookParams < Model
|
|
@@ -392,13 +442,21 @@ module PostProxy
|
|
|
392
442
|
attr_accessor :format
|
|
393
443
|
end
|
|
394
444
|
|
|
445
|
+
class BlueskyParams < Model
|
|
446
|
+
attr_accessor :format
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
class TelegramParams < Model
|
|
450
|
+
attr_accessor :format, :chat_id, :parse_mode, :disable_link_preview, :disable_notification
|
|
451
|
+
end
|
|
452
|
+
|
|
395
453
|
class PlatformParams < Model
|
|
396
454
|
attr_accessor :facebook, :instagram, :tiktok, :linkedin, :youtube,
|
|
397
|
-
:pinterest, :threads, :twitter
|
|
455
|
+
:pinterest, :threads, :twitter, :bluesky, :telegram
|
|
398
456
|
|
|
399
457
|
def to_h
|
|
400
458
|
result = {}
|
|
401
|
-
%i[facebook instagram tiktok linkedin youtube pinterest threads twitter].each do |platform|
|
|
459
|
+
%i[facebook instagram tiktok linkedin youtube pinterest threads twitter bluesky telegram].each do |platform|
|
|
402
460
|
value = send(platform)
|
|
403
461
|
next if value.nil?
|
|
404
462
|
|
data/lib/postproxy/version.rb
CHANGED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module PostProxy
|
|
4
|
+
class WebhookParseError < StandardError; end
|
|
5
|
+
|
|
6
|
+
module WebhookEvents
|
|
7
|
+
class Event < Model
|
|
8
|
+
attr_accessor :id, :type, :created_at, :data
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class PostProcessedPlatform < Model
|
|
12
|
+
attr_accessor :id, :platform, :name
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class PostProcessedData < Model
|
|
16
|
+
attr_accessor :id, :body, :status, :scheduled_at, :created_at, :platforms
|
|
17
|
+
|
|
18
|
+
def initialize(**attrs)
|
|
19
|
+
@platforms = []
|
|
20
|
+
super
|
|
21
|
+
@platforms = (@platforms || []).map do |p|
|
|
22
|
+
p.is_a?(PostProcessedPlatform) ? p : PostProcessedPlatform.new(**p.transform_keys(&:to_sym))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class ImportedProfile < Model
|
|
28
|
+
attr_accessor :id, :name, :platform
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
class PostImportedData < Model
|
|
32
|
+
attr_accessor :id, :body, :source, :posted_at, :created_at,
|
|
33
|
+
:platform, :profile, :platform_post_id, :public_id
|
|
34
|
+
|
|
35
|
+
def initialize(**attrs)
|
|
36
|
+
@profile = nil
|
|
37
|
+
super
|
|
38
|
+
@profile = ImportedProfile.new(**@profile.transform_keys(&:to_sym)) if @profile.is_a?(Hash)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class PlatformPostData < Model
|
|
43
|
+
attr_accessor :id, :post_id, :platform, :profile_id, :profile_name,
|
|
44
|
+
:status, :error, :error_details, :platform_id, :insights
|
|
45
|
+
|
|
46
|
+
def initialize(**attrs)
|
|
47
|
+
@error_details = nil
|
|
48
|
+
@insights = nil
|
|
49
|
+
super
|
|
50
|
+
@error_details = ErrorDetails.new(**@error_details.transform_keys(&:to_sym)) if @error_details.is_a?(Hash)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class ProfileEventData < Model
|
|
55
|
+
attr_accessor :id, :name, :platform, :profile_group_id, :status, :uid, :username
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class ProfileStatsData < Model
|
|
59
|
+
attr_accessor :profile_id, :platform, :placement_id, :stats, :recorded_at
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
class MediaFailedData < Model
|
|
63
|
+
attr_accessor :id, :post_id, :content_type, :status, :error_message
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
class CommentCreatedData < Model
|
|
67
|
+
attr_accessor :id, :post_id, :platform_post_id, :platform, :external_id,
|
|
68
|
+
:parent_external_id, :body, :status, :author_external_id,
|
|
69
|
+
:author_name, :author_username, :author_avatar_url,
|
|
70
|
+
:like_count, :reply_count, :is_hidden, :permalink,
|
|
71
|
+
:platform_data, :posted_at, :created_at
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
DATA_CLASSES = {
|
|
75
|
+
"post.processed" => PostProcessedData,
|
|
76
|
+
"post.imported" => PostImportedData,
|
|
77
|
+
"platform_post.published" => PlatformPostData,
|
|
78
|
+
"platform_post.failed" => PlatformPostData,
|
|
79
|
+
"platform_post.failed_waiting_for_retry" => PlatformPostData,
|
|
80
|
+
"platform_post.insights" => PlatformPostData,
|
|
81
|
+
"profile.connected" => ProfileEventData,
|
|
82
|
+
"profile.disconnected" => ProfileEventData,
|
|
83
|
+
"profile.stats" => ProfileStatsData,
|
|
84
|
+
"media.failed" => MediaFailedData,
|
|
85
|
+
"comment.created" => CommentCreatedData
|
|
86
|
+
}.freeze
|
|
87
|
+
|
|
88
|
+
# Parse a webhook body and return a typed Event. `data` is parsed into the
|
|
89
|
+
# appropriate model based on `type`. Raises WebhookParseError on bad input.
|
|
90
|
+
def self.parse(body)
|
|
91
|
+
parsed =
|
|
92
|
+
case body
|
|
93
|
+
when String then JSON.parse(body, symbolize_names: true)
|
|
94
|
+
when Hash then body.transform_keys(&:to_sym)
|
|
95
|
+
else raise WebhookParseError, "Webhook body must be a String or Hash"
|
|
96
|
+
end
|
|
97
|
+
rescue JSON::ParserError => e
|
|
98
|
+
raise WebhookParseError, "Invalid JSON: #{e.message}"
|
|
99
|
+
else
|
|
100
|
+
type = parsed[:type].to_s
|
|
101
|
+
raise WebhookParseError, "Unknown webhook event type: #{type.inspect}" unless DATA_CLASSES.key?(type)
|
|
102
|
+
|
|
103
|
+
data_class = DATA_CLASSES[type]
|
|
104
|
+
data_hash = (parsed[:data] || {}).transform_keys(&:to_sym)
|
|
105
|
+
Event.new(
|
|
106
|
+
id: parsed[:id],
|
|
107
|
+
type: type,
|
|
108
|
+
created_at: parsed[:created_at],
|
|
109
|
+
data: data_class.new(**data_hash)
|
|
110
|
+
)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
data/lib/postproxy.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: postproxy-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- PostProxy
|
|
@@ -86,6 +86,7 @@ files:
|
|
|
86
86
|
- lib/postproxy/resources/webhooks.rb
|
|
87
87
|
- lib/postproxy/types.rb
|
|
88
88
|
- lib/postproxy/version.rb
|
|
89
|
+
- lib/postproxy/webhook_events.rb
|
|
89
90
|
- lib/postproxy/webhook_signature.rb
|
|
90
91
|
homepage: https://postproxy.dev
|
|
91
92
|
licenses:
|