kit-rb 0.0.0 → 0.2.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/README.md +56 -5
  4. data/Rakefile +17 -0
  5. data/lib/kit/client.rb +56 -0
  6. data/lib/kit/configuration.rb +7 -2
  7. data/lib/kit/connection.rb +37 -11
  8. data/lib/kit/errors.rb +15 -0
  9. data/lib/kit/oauth/client.rb +132 -0
  10. data/lib/kit/oauth/pkce.rb +42 -0
  11. data/lib/kit/oauth/token.rb +38 -0
  12. data/lib/kit/objects/broadcast.rb +26 -0
  13. data/lib/kit/objects/broadcast_click.rb +17 -0
  14. data/lib/kit/objects/broadcast_stats.rb +30 -0
  15. data/lib/kit/objects/creator_profile.rb +13 -0
  16. data/lib/kit/objects/custom_field.rb +14 -0
  17. data/lib/kit/objects/email_stats.rb +25 -0
  18. data/lib/kit/objects/email_template.rb +14 -0
  19. data/lib/kit/objects/form.rb +22 -0
  20. data/lib/kit/objects/growth_stats.rb +20 -0
  21. data/lib/kit/objects/post.rb +24 -0
  22. data/lib/kit/objects/purchase.rb +24 -0
  23. data/lib/kit/objects/segment.rb +12 -0
  24. data/lib/kit/objects/sequence.rb +26 -0
  25. data/lib/kit/objects/sequence_email.rb +23 -0
  26. data/lib/kit/objects/snippet.rb +21 -0
  27. data/lib/kit/objects/subscriber.rb +25 -0
  28. data/lib/kit/objects/subscriber_stats.rb +26 -0
  29. data/lib/kit/objects/tag.rb +17 -0
  30. data/lib/kit/objects/webhook.rb +15 -0
  31. data/lib/kit/objects/webhook_endpoint.rb +22 -0
  32. data/lib/kit/pagination.rb +66 -0
  33. data/lib/kit/resources/account.rb +27 -1
  34. data/lib/kit/resources/base.rb +38 -6
  35. data/lib/kit/resources/broadcasts.rb +56 -0
  36. data/lib/kit/resources/bulk.rb +63 -0
  37. data/lib/kit/resources/custom_fields.rb +29 -0
  38. data/lib/kit/resources/email_templates.rb +13 -0
  39. data/lib/kit/resources/forms.rb +31 -0
  40. data/lib/kit/resources/posts.rb +18 -0
  41. data/lib/kit/resources/purchases.rb +26 -0
  42. data/lib/kit/resources/segments.rb +13 -0
  43. data/lib/kit/resources/sequences.rb +78 -0
  44. data/lib/kit/resources/snippets.rb +29 -0
  45. data/lib/kit/resources/subscribers.rb +67 -0
  46. data/lib/kit/resources/tags.rb +52 -0
  47. data/lib/kit/resources/webhook_endpoints.rb +46 -0
  48. data/lib/kit/resources/webhooks.rb +24 -0
  49. data/lib/kit/version.rb +1 -1
  50. data/lib/kit-rb.rb +38 -0
  51. data/sig/kit-rb.rbs +429 -1
  52. metadata +43 -5
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/custom_fields endpoints.
6
+ class CustomFields < Base
7
+ # GET /v4/custom_fields
8
+ def list(**params)
9
+ collection("/v4/custom_fields", "custom_fields", Objects::CustomField, params)
10
+ end
11
+
12
+ # POST /v4/custom_fields
13
+ def create(label:)
14
+ one(:post, "/v4/custom_fields", "custom_field", Objects::CustomField, body: { label: label })
15
+ end
16
+
17
+ # PUT /v4/custom_fields/:id
18
+ def update(id, label:)
19
+ one(:put, "/v4/custom_fields/#{id}", "custom_field", Objects::CustomField, body: { label: label })
20
+ end
21
+
22
+ # DELETE /v4/custom_fields/:id
23
+ def delete(id)
24
+ http_delete("/v4/custom_fields/#{id}")
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/email_templates endpoints.
6
+ class EmailTemplates < Base
7
+ # GET /v4/email_templates
8
+ def list(**params)
9
+ collection("/v4/email_templates", "email_templates", Objects::EmailTemplate, params)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/forms endpoints. Forms themselves are created in the Kit UI, so
6
+ # this resource lists them and manages their subscribers.
7
+ class Forms < Base
8
+ # GET /v4/forms
9
+ def list(**params)
10
+ collection("/v4/forms", "forms", Objects::Form, params)
11
+ end
12
+
13
+ # GET /v4/forms/:form_id/subscribers
14
+ def subscribers(form_id, **params)
15
+ collection("/v4/forms/#{form_id}/subscribers", "subscribers", Objects::Subscriber, params)
16
+ end
17
+
18
+ # POST /v4/forms/:form_id/subscribers/:subscriber_id
19
+ def add_subscriber(form_id, subscriber_id, referrer: nil)
20
+ one(:post, "/v4/forms/#{form_id}/subscribers/#{subscriber_id}", "subscriber",
21
+ Objects::Subscriber, body: { referrer: referrer }.compact)
22
+ end
23
+
24
+ # POST /v4/forms/:form_id/subscribers
25
+ def add_subscriber_by_email(form_id, email_address:, referrer: nil)
26
+ one(:post, "/v4/forms/#{form_id}/subscribers", "subscriber", Objects::Subscriber,
27
+ body: { email_address: email_address, referrer: referrer }.compact)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/posts endpoints — broadcasts published to the web.
6
+ class Posts < Base
7
+ # GET /v4/posts
8
+ def list(**params)
9
+ collection("/v4/posts", "posts", Objects::Post, params)
10
+ end
11
+
12
+ # GET /v4/posts/:id
13
+ def get(id)
14
+ one(:get, "/v4/posts/#{id}", "post", Objects::Post)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/purchases endpoints. All three require OAuth (the API key is not
6
+ # accepted here); create records an external purchase.
7
+ class Purchases < Base
8
+ # GET /v4/purchases
9
+ def list(**params)
10
+ collection("/v4/purchases", "purchases", Objects::Purchase, params)
11
+ end
12
+
13
+ # GET /v4/purchases/:id
14
+ def get(id)
15
+ one(:get, "/v4/purchases/#{id}", "purchase", Objects::Purchase)
16
+ end
17
+
18
+ # POST /v4/purchases — the request wraps the fields under a "purchase" key.
19
+ # Pass email_address/transaction_id/status/currency/transaction_time,
20
+ # the monetary totals, and a products array.
21
+ def create(**attributes)
22
+ one(:post, "/v4/purchases", "purchase", Objects::Purchase, body: { purchase: attributes })
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/segments endpoints.
6
+ class Segments < Base
7
+ # GET /v4/segments
8
+ def list(**params)
9
+ collection("/v4/segments", "segments", Objects::Segment, params)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/sequences endpoints. Sequences (formerly "courses"), their
6
+ # subscribers, and the emails that make up each sequence.
7
+ class Sequences < Base
8
+ # GET /v4/sequences
9
+ def list(**params)
10
+ collection("/v4/sequences", "sequences", Objects::Sequence, params)
11
+ end
12
+
13
+ # GET /v4/sequences/:id
14
+ def get(id)
15
+ one(:get, "/v4/sequences/#{id}", "sequence", Objects::Sequence)
16
+ end
17
+
18
+ # GET /v4/sequences/:sequence_id/subscribers
19
+ def subscribers(sequence_id, **params)
20
+ collection("/v4/sequences/#{sequence_id}/subscribers", "subscribers", Objects::Subscriber, params)
21
+ end
22
+
23
+ # POST /v4/sequences
24
+ def create(name:, **attributes)
25
+ one(:post, "/v4/sequences", "sequence", Objects::Sequence, body: { name: name }.merge(attributes))
26
+ end
27
+
28
+ # PUT /v4/sequences/:id
29
+ def update(id, **attributes)
30
+ one(:put, "/v4/sequences/#{id}", "sequence", Objects::Sequence, body: attributes)
31
+ end
32
+
33
+ # DELETE /v4/sequences/:id
34
+ def delete(id)
35
+ http_delete("/v4/sequences/#{id}")
36
+ nil
37
+ end
38
+
39
+ # POST /v4/sequences/:sequence_id/subscribers/:subscriber_id
40
+ def add_subscriber(sequence_id, subscriber_id)
41
+ one(:post, "/v4/sequences/#{sequence_id}/subscribers/#{subscriber_id}", "subscriber", Objects::Subscriber)
42
+ end
43
+
44
+ # POST /v4/sequences/:sequence_id/subscribers
45
+ def add_subscriber_by_email(sequence_id, email_address:)
46
+ one(:post, "/v4/sequences/#{sequence_id}/subscribers", "subscriber", Objects::Subscriber,
47
+ body: { email_address: email_address })
48
+ end
49
+
50
+ # GET /v4/sequences/:sequence_id/emails
51
+ def emails(sequence_id, **params)
52
+ collection("/v4/sequences/#{sequence_id}/emails", "emails", Objects::SequenceEmail, params)
53
+ end
54
+
55
+ # GET /v4/sequences/:sequence_id/emails/:id
56
+ def email(sequence_id, id)
57
+ one(:get, "/v4/sequences/#{sequence_id}/emails/#{id}", "email", Objects::SequenceEmail)
58
+ end
59
+
60
+ # POST /v4/sequences/:sequence_id/emails — subject/delay_value/delay_unit
61
+ # are required; content/position/send_days and the rest are optional.
62
+ def create_email(sequence_id, **attributes)
63
+ one(:post, "/v4/sequences/#{sequence_id}/emails", "email", Objects::SequenceEmail, body: attributes)
64
+ end
65
+
66
+ # PUT /v4/sequences/:sequence_id/emails/:id
67
+ def update_email(sequence_id, id, **attributes)
68
+ one(:put, "/v4/sequences/#{sequence_id}/emails/#{id}", "email", Objects::SequenceEmail, body: attributes)
69
+ end
70
+
71
+ # DELETE /v4/sequences/:sequence_id/emails/:id
72
+ def delete_email(sequence_id, id)
73
+ http_delete("/v4/sequences/#{sequence_id}/emails/#{id}")
74
+ nil
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/snippets endpoints — reusable inline/document content.
6
+ class Snippets < Base
7
+ # GET /v4/snippets
8
+ def list(**params)
9
+ collection("/v4/snippets", "snippets", Objects::Snippet, params)
10
+ end
11
+
12
+ # GET /v4/snippets/:id
13
+ def get(id)
14
+ one(:get, "/v4/snippets/#{id}", "snippet", Objects::Snippet)
15
+ end
16
+
17
+ # POST /v4/snippets — pass name/snippet_type and content (inline) or
18
+ # document (document); the API validates the combination.
19
+ def create(**attributes)
20
+ one(:post, "/v4/snippets", "snippet", Objects::Snippet, body: attributes)
21
+ end
22
+
23
+ # PUT /v4/snippets/:id
24
+ def update(id, **attributes)
25
+ one(:put, "/v4/snippets/#{id}", "snippet", Objects::Snippet, body: attributes)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/subscribers endpoints.
6
+ class Subscribers < Base
7
+ # GET /v4/subscribers — a cursor-paginated Collection of Subscriber.
8
+ # Accepts filters as params: after, before, per_page, email_address,
9
+ # status, created_after, created_before, sort_field, sort_order.
10
+ def list(**params)
11
+ collection("/v4/subscribers", "subscribers", Objects::Subscriber, params)
12
+ end
13
+
14
+ # GET /v4/subscribers/:id
15
+ def get(id)
16
+ one(:get, "/v4/subscribers/#{id}", "subscriber", Objects::Subscriber)
17
+ end
18
+
19
+ # POST /v4/subscribers — email_address required; first_name, state, fields optional.
20
+ def create(email_address:, first_name: nil, state: nil, fields: nil)
21
+ body = { email_address: email_address, first_name: first_name,
22
+ state: state, fields: fields }.compact
23
+ one(:post, "/v4/subscribers", "subscriber", Objects::Subscriber, body: body)
24
+ end
25
+
26
+ # PUT /v4/subscribers/:id
27
+ def update(id, first_name: nil, email_address: nil, fields: nil)
28
+ body = { first_name: first_name, email_address: email_address, fields: fields }.compact
29
+ one(:put, "/v4/subscribers/#{id}", "subscriber", Objects::Subscriber, body: body)
30
+ end
31
+
32
+ # POST /v4/subscribers/:id/unsubscribe
33
+ def unsubscribe(id)
34
+ one(:post, "/v4/subscribers/#{id}/unsubscribe", "subscriber", Objects::Subscriber)
35
+ end
36
+
37
+ # POST /v4/subscribers/filter — the same filters as #list, sent in the
38
+ # request rather than the query string; returns a cursor-paginated Collection.
39
+ def filter(**params)
40
+ collection("/v4/subscribers/filter", "subscribers", Objects::Subscriber, params, verb: :post)
41
+ end
42
+
43
+ # GET /v4/subscribers/:id/tags — the tags applied to a subscriber.
44
+ def tags(id, **params)
45
+ collection("/v4/subscribers/#{id}/tags", "tags", Objects::Tag, params)
46
+ end
47
+
48
+ # GET /v4/subscribers/:id/stats — the subscriber's engagement stats.
49
+ def stats(id)
50
+ one(:get, "/v4/subscribers/#{id}/stats", "subscriber", Objects::SubscriberStats)
51
+ end
52
+
53
+ # POST /v4/subscribers/:id/location — set the subscriber's location
54
+ # (a hash of city/state_province/country_code/latitude/longitude/timezone).
55
+ def set_location(id, location:)
56
+ one(:post, "/v4/subscribers/#{id}/location", "subscriber", Objects::Subscriber,
57
+ body: { location: location })
58
+ end
59
+
60
+ # DELETE /v4/subscribers/:id/location
61
+ def remove_location(id)
62
+ http_delete("/v4/subscribers/#{id}/location")
63
+ nil
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/tags endpoints.
6
+ class Tags < Base
7
+ # GET /v4/tags
8
+ def list(**params)
9
+ collection("/v4/tags", "tags", Objects::Tag, params)
10
+ end
11
+
12
+ # POST /v4/tags
13
+ def create(name:)
14
+ one(:post, "/v4/tags", "tag", Objects::Tag, body: { name: name })
15
+ end
16
+
17
+ # PUT /v4/tags/:id
18
+ def update(id, name:)
19
+ one(:put, "/v4/tags/#{id}", "tag", Objects::Tag, body: { name: name })
20
+ end
21
+
22
+ # POST /v4/tags/:tag_id/subscribers/:id
23
+ def tag_subscriber(tag_id, subscriber_id)
24
+ one(:post, "/v4/tags/#{tag_id}/subscribers/#{subscriber_id}", "subscriber", Objects::Subscriber)
25
+ end
26
+
27
+ # DELETE /v4/tags/:tag_id/subscribers/:id
28
+ def remove_subscriber(tag_id, subscriber_id)
29
+ http_delete("/v4/tags/#{tag_id}/subscribers/#{subscriber_id}")
30
+ nil
31
+ end
32
+
33
+ # POST /v4/tags/:tag_id/subscribers — tag a subscriber by email address.
34
+ def tag_subscriber_by_email(tag_id, email_address:)
35
+ one(:post, "/v4/tags/#{tag_id}/subscribers", "subscriber", Objects::Subscriber,
36
+ body: { email_address: email_address })
37
+ end
38
+
39
+ # DELETE /v4/tags/:tag_id/subscribers — remove a tag from a subscriber by
40
+ # email address (passed as a query parameter).
41
+ def remove_subscriber_by_email(tag_id, email_address:)
42
+ http_delete("/v4/tags/#{tag_id}/subscribers", params: { email_address: email_address })
43
+ nil
44
+ end
45
+
46
+ # GET /v4/tags/:tag_id/subscribers
47
+ def subscribers(tag_id, **params)
48
+ collection("/v4/tags/#{tag_id}/subscribers", "subscribers", Objects::Subscriber, params)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/webhook_endpoints endpoints — signed webhook delivery, with a
6
+ # rotatable secret.
7
+ #
8
+ # Note: although the OpenAPI spec lists API Key as accepted, the live API
9
+ # rejected an API key here with 401 while /v4/webhooks accepted the same key
10
+ # (verified 2026-09-04) — these endpoints appear to require OAuth in practice.
11
+ class WebhookEndpoints < Base
12
+ # GET /v4/webhook_endpoints
13
+ def list(**params)
14
+ collection("/v4/webhook_endpoints", "webhook_endpoints", Objects::WebhookEndpoint, params)
15
+ end
16
+
17
+ # GET /v4/webhook_endpoints/:id
18
+ def get(id)
19
+ one(:get, "/v4/webhook_endpoints/#{id}", "webhook_endpoint", Objects::WebhookEndpoint)
20
+ end
21
+
22
+ # POST /v4/webhook_endpoints
23
+ def create(url:, events:, name: nil, description: nil)
24
+ one(:post, "/v4/webhook_endpoints", "webhook_endpoint", Objects::WebhookEndpoint,
25
+ body: { url: url, events: events, name: name, description: description }.compact)
26
+ end
27
+
28
+ # DELETE /v4/webhook_endpoints/:id
29
+ def delete(id)
30
+ http_delete("/v4/webhook_endpoints/#{id}")
31
+ nil
32
+ end
33
+
34
+ # POST /v4/webhook_endpoints/:id/rotate_secret
35
+ def rotate_secret(id, force: nil)
36
+ one(:post, "/v4/webhook_endpoints/#{id}/rotate_secret", "webhook_endpoint", Objects::WebhookEndpoint,
37
+ body: { force: force }.compact)
38
+ end
39
+
40
+ # POST /v4/webhook_endpoints/:id/revoke_previous_secret
41
+ def revoke_previous_secret(id)
42
+ one(:post, "/v4/webhook_endpoints/#{id}/revoke_previous_secret", "webhook_endpoint", Objects::WebhookEndpoint)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kit
4
+ module Resources
5
+ # The /v4/webhooks endpoints — automation rules that POST to a target URL.
6
+ class Webhooks < Base
7
+ # GET /v4/webhooks
8
+ def list(**params)
9
+ collection("/v4/webhooks", "webhooks", Objects::Webhook, params)
10
+ end
11
+
12
+ # POST /v4/webhooks
13
+ def create(target_url:, event:)
14
+ one(:post, "/v4/webhooks", "webhook", Objects::Webhook, body: { target_url: target_url, event: event })
15
+ end
16
+
17
+ # DELETE /v4/webhooks/:id
18
+ def delete(id)
19
+ http_delete("/v4/webhooks/#{id}")
20
+ nil
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/kit/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kit
4
- VERSION = "0.0.0"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/kit-rb.rb CHANGED
@@ -18,7 +18,45 @@ require "kit/configuration"
18
18
  require "kit/auth/api_key"
19
19
  require "kit/auth/oauth"
20
20
  require "kit/connection"
21
+ require "kit/pagination"
22
+ require "kit/oauth/pkce"
23
+ require "kit/oauth/token"
24
+ require "kit/oauth/client"
21
25
  require "kit/objects/account"
26
+ require "kit/objects/creator_profile"
27
+ require "kit/objects/subscriber"
28
+ require "kit/objects/tag"
29
+ require "kit/objects/custom_field"
30
+ require "kit/objects/form"
31
+ require "kit/objects/sequence"
32
+ require "kit/objects/sequence_email"
33
+ require "kit/objects/broadcast"
34
+ require "kit/objects/broadcast_stats"
35
+ require "kit/objects/broadcast_click"
36
+ require "kit/objects/subscriber_stats"
37
+ require "kit/objects/email_stats"
38
+ require "kit/objects/growth_stats"
39
+ require "kit/objects/webhook"
40
+ require "kit/objects/webhook_endpoint"
41
+ require "kit/objects/email_template"
42
+ require "kit/objects/segment"
43
+ require "kit/objects/post"
44
+ require "kit/objects/snippet"
45
+ require "kit/objects/purchase"
22
46
  require "kit/resources/base"
23
47
  require "kit/resources/account"
48
+ require "kit/resources/subscribers"
49
+ require "kit/resources/tags"
50
+ require "kit/resources/custom_fields"
51
+ require "kit/resources/forms"
52
+ require "kit/resources/sequences"
53
+ require "kit/resources/broadcasts"
54
+ require "kit/resources/webhooks"
55
+ require "kit/resources/webhook_endpoints"
56
+ require "kit/resources/email_templates"
57
+ require "kit/resources/segments"
58
+ require "kit/resources/posts"
59
+ require "kit/resources/snippets"
60
+ require "kit/resources/purchases"
61
+ require "kit/resources/bulk"
24
62
  require "kit/client"