basecamp-sdk 0.18.0 → 0.19.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/basecamp/api_error.rb +5 -3
  4. data/lib/basecamp/bucket_mismatch_error.rb +41 -0
  5. data/lib/basecamp/campfire_discovery_incomplete_error.rb +57 -0
  6. data/lib/basecamp/campfire_index.rb +398 -0
  7. data/lib/basecamp/client.rb +47 -4
  8. data/lib/basecamp/generated/metadata.json +728 -1
  9. data/lib/basecamp/generated/services/account_service.rb +2 -2
  10. data/lib/basecamp/generated/services/attachments_service.rb +1 -1
  11. data/lib/basecamp/generated/services/automation_service.rb +1 -1
  12. data/lib/basecamp/generated/services/bookmarks_service.rb +2 -2
  13. data/lib/basecamp/generated/services/boosts_service.rb +3 -3
  14. data/lib/basecamp/generated/services/calendars_service.rb +2 -2
  15. data/lib/basecamp/generated/services/campfires_service.rb +7 -7
  16. data/lib/basecamp/generated/services/card_columns_service.rb +6 -6
  17. data/lib/basecamp/generated/services/card_steps_service.rb +4 -4
  18. data/lib/basecamp/generated/services/card_tables_service.rb +1 -1
  19. data/lib/basecamp/generated/services/cards_service.rb +3 -3
  20. data/lib/basecamp/generated/services/checkins_service.rb +9 -9
  21. data/lib/basecamp/generated/services/client_approvals_service.rb +1 -1
  22. data/lib/basecamp/generated/services/client_correspondences_service.rb +1 -1
  23. data/lib/basecamp/generated/services/client_replies_service.rb +1 -1
  24. data/lib/basecamp/generated/services/client_visibility_service.rb +1 -1
  25. data/lib/basecamp/generated/services/cloud_files_service.rb +3 -3
  26. data/lib/basecamp/generated/services/comments_service.rb +3 -3
  27. data/lib/basecamp/generated/services/documents_service.rb +3 -3
  28. data/lib/basecamp/generated/services/event_feed_service.rb +58 -0
  29. data/lib/basecamp/generated/services/everything_service.rb +2 -2
  30. data/lib/basecamp/generated/services/folders_service.rb +4 -4
  31. data/lib/basecamp/generated/services/forwards_service.rb +3 -3
  32. data/lib/basecamp/generated/services/gauges_service.rb +10 -6
  33. data/lib/basecamp/generated/services/google_documents_service.rb +3 -3
  34. data/lib/basecamp/generated/services/hill_charts_service.rb +2 -2
  35. data/lib/basecamp/generated/services/message_boards_service.rb +1 -1
  36. data/lib/basecamp/generated/services/message_types_service.rb +3 -3
  37. data/lib/basecamp/generated/services/messages_service.rb +3 -3
  38. data/lib/basecamp/generated/services/my_assignments_service.rb +3 -3
  39. data/lib/basecamp/generated/services/my_notes_service.rb +2 -2
  40. data/lib/basecamp/generated/services/my_notifications_service.rb +1 -1
  41. data/lib/basecamp/generated/services/people_service.rb +11 -11
  42. data/lib/basecamp/generated/services/projects_service.rb +4 -4
  43. data/lib/basecamp/generated/services/recordings_service.rb +1 -1
  44. data/lib/basecamp/generated/services/reports_service.rb +3 -3
  45. data/lib/basecamp/generated/services/schedules_service.rb +6 -6
  46. data/lib/basecamp/generated/services/search_service.rb +1 -1
  47. data/lib/basecamp/generated/services/subscriptions_service.rb +3 -3
  48. data/lib/basecamp/generated/services/templates_service.rb +8 -8
  49. data/lib/basecamp/generated/services/timesheets_service.rb +4 -4
  50. data/lib/basecamp/generated/services/todolist_groups_service.rb +1 -1
  51. data/lib/basecamp/generated/services/todolists_service.rb +3 -3
  52. data/lib/basecamp/generated/services/todos_service.rb +4 -4
  53. data/lib/basecamp/generated/services/todosets_service.rb +1 -1
  54. data/lib/basecamp/generated/services/tools_service.rb +3 -3
  55. data/lib/basecamp/generated/services/uploads_service.rb +4 -4
  56. data/lib/basecamp/generated/services/vaults_service.rb +3 -3
  57. data/lib/basecamp/generated/services/webhooks_service.rb +3 -3
  58. data/lib/basecamp/generated/services/wormholes_service.rb +2 -2
  59. data/lib/basecamp/generated/types.rb +108 -6
  60. data/lib/basecamp/http.rb +383 -60
  61. data/lib/basecamp/ids.rb +277 -0
  62. data/lib/basecamp/mentions.rb +1119 -0
  63. data/lib/basecamp/person_id_sites.rb +184 -0
  64. data/lib/basecamp/recording_routing_error.rb +50 -0
  65. data/lib/basecamp/recording_summary_error.rb +33 -0
  66. data/lib/basecamp/services/comments_extensions.rb +121 -0
  67. data/lib/basecamp/services/merge_safe.rb +37 -13
  68. data/lib/basecamp/services/recordings_extensions.rb +1305 -0
  69. data/lib/basecamp/services/todolists_extensions.rb +4 -3
  70. data/lib/basecamp/text.rb +94 -0
  71. data/lib/basecamp/unresolved_recording_error.rb +68 -0
  72. data/lib/basecamp/version.rb +1 -1
  73. data/lib/basecamp/webhooks/event.rb +4 -1
  74. data/lib/basecamp.rb +22 -4
  75. data/scripts/generate-metadata.rb +75 -2
  76. data/scripts/generate-services.rb +35 -8
  77. data/scripts/generate-types.rb +19 -0
  78. metadata +15 -2
@@ -12,7 +12,7 @@ module Basecamp
12
12
  # @return [Hash] response data
13
13
  def get(id:)
14
14
  with_operation(service: "todolists", operation: "get", is_mutation: false, resource_id: id) do
15
- http_get("/todolists/#{id}", operation: "GetTodolistOrGroup").json
15
+ http_get("/todolists/#{id}", operation: "GetTodolistOrGroup").json(operation: "GetTodolistOrGroup")
16
16
  end
17
17
  end
18
18
 
@@ -23,7 +23,7 @@ module Basecamp
23
23
  # @return [Hash] response data
24
24
  def replace(id:, name:, description: nil)
25
25
  with_operation(service: "todolists", operation: "replace", is_mutation: true, resource_id: id) do
26
- http_put("/todolists/#{id}", body: compact_params(name: name, description: description)).json
26
+ http_put("/todolists/#{id}", body: compact_params(name: name, description: description)).json(operation: "UpdateTodolistOrGroup")
27
27
  end
28
28
  end
29
29
 
@@ -59,7 +59,7 @@ module Basecamp
59
59
  # @return [Hash] response data
60
60
  def create(todoset_id:, name:, description: nil, visible_to_clients: nil)
61
61
  with_operation(service: "todolists", operation: "create", is_mutation: true, resource_id: todoset_id) do
62
- http_post("/todosets/#{todoset_id}/todolists.json", body: compact_params(name: name, description: description, visible_to_clients: visible_to_clients)).json
62
+ http_post("/todosets/#{todoset_id}/todolists.json", body: compact_params(name: name, description: description, visible_to_clients: visible_to_clients)).json(operation: "CreateTodolist")
63
63
  end
64
64
  end
65
65
  end
@@ -20,7 +20,7 @@ module Basecamp
20
20
  # @return [Hash] response data
21
21
  def create_todoset_todo(bucket_id:, todoset_id:, content:, description: nil, assignee_ids: nil, completion_subscriber_ids: nil, notify: nil, due_on: nil, starts_on: nil)
22
22
  with_operation(service: "todos", operation: "create_todoset_todo", is_mutation: true, project_id: bucket_id, resource_id: todoset_id) do
23
- http_post("/buckets/#{bucket_id}/todosets/#{todoset_id}/todos.json", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json
23
+ http_post("/buckets/#{bucket_id}/todosets/#{todoset_id}/todos.json", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json(operation: "CreateTodosetTodo")
24
24
  end
25
25
  end
26
26
 
@@ -50,7 +50,7 @@ module Basecamp
50
50
  # @return [Hash] response data
51
51
  def create(todolist_id:, content:, description: nil, assignee_ids: nil, completion_subscriber_ids: nil, notify: nil, due_on: nil, starts_on: nil)
52
52
  with_operation(service: "todos", operation: "create", is_mutation: true, resource_id: todolist_id) do
53
- http_post("/todolists/#{todolist_id}/todos.json", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json
53
+ http_post("/todolists/#{todolist_id}/todos.json", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json(operation: "CreateTodo")
54
54
  end
55
55
  end
56
56
 
@@ -59,7 +59,7 @@ module Basecamp
59
59
  # @return [Hash] response data
60
60
  def get(todo_id:)
61
61
  with_operation(service: "todos", operation: "get", is_mutation: false, resource_id: todo_id) do
62
- http_get("/todos/#{todo_id}", operation: "GetTodo").json
62
+ http_get("/todos/#{todo_id}", operation: "GetTodo").json(operation: "GetTodo")
63
63
  end
64
64
  end
65
65
 
@@ -75,7 +75,7 @@ module Basecamp
75
75
  # @return [Hash] response data
76
76
  def replace(todo_id:, content:, description: nil, assignee_ids: nil, completion_subscriber_ids: nil, notify: nil, due_on: nil, starts_on: nil)
77
77
  with_operation(service: "todos", operation: "replace", is_mutation: true, resource_id: todo_id) do
78
- http_put("/todos/#{todo_id}", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json
78
+ http_put("/todos/#{todo_id}", body: compact_params(content: content, description: description, assignee_ids: assignee_ids, completion_subscriber_ids: completion_subscriber_ids, notify: notify, due_on: due_on, starts_on: starts_on)).json(operation: "ReplaceTodo")
79
79
  end
80
80
  end
81
81
 
@@ -12,7 +12,7 @@ module Basecamp
12
12
  # @return [Hash] response data
13
13
  def get(todoset_id:)
14
14
  with_operation(service: "todosets", operation: "get", is_mutation: false, resource_id: todoset_id) do
15
- http_get("/todosets/#{todoset_id}", operation: "GetTodoset").json
15
+ http_get("/todosets/#{todoset_id}", operation: "GetTodoset").json(operation: "GetTodoset")
16
16
  end
17
17
  end
18
18
  end
@@ -15,7 +15,7 @@ module Basecamp
15
15
  # @return [Hash] response data
16
16
  def create(bucket_id:, tool_type:, title: nil, visible_to_clients: nil)
17
17
  with_operation(service: "tools", operation: "create", is_mutation: true, project_id: bucket_id) do
18
- http_post("/buckets/#{bucket_id}/dock/tools.json", body: compact_params(tool_type: tool_type, title: title, visible_to_clients: visible_to_clients)).json
18
+ http_post("/buckets/#{bucket_id}/dock/tools.json", body: compact_params(tool_type: tool_type, title: title, visible_to_clients: visible_to_clients)).json(operation: "CreateTool")
19
19
  end
20
20
  end
21
21
 
@@ -24,7 +24,7 @@ module Basecamp
24
24
  # @return [Hash] response data
25
25
  def get(tool_id:)
26
26
  with_operation(service: "tools", operation: "get", is_mutation: false, resource_id: tool_id) do
27
- http_get("/dock/tools/#{tool_id}", operation: "GetTool").json
27
+ http_get("/dock/tools/#{tool_id}", operation: "GetTool").json(operation: "GetTool")
28
28
  end
29
29
  end
30
30
 
@@ -34,7 +34,7 @@ module Basecamp
34
34
  # @return [Hash] response data
35
35
  def update(tool_id:, title:)
36
36
  with_operation(service: "tools", operation: "update", is_mutation: true, resource_id: tool_id) do
37
- http_put("/dock/tools/#{tool_id}", body: compact_params(title: title)).json
37
+ http_put("/dock/tools/#{tool_id}", body: compact_params(title: title)).json(operation: "UpdateTool")
38
38
  end
39
39
  end
40
40
 
@@ -12,7 +12,7 @@ module Basecamp
12
12
  # @return [Hash] response data
13
13
  def get(upload_id:)
14
14
  with_operation(service: "uploads", operation: "get", is_mutation: false, resource_id: upload_id) do
15
- http_get("/uploads/#{upload_id}", operation: "GetUpload").json
15
+ http_get("/uploads/#{upload_id}", operation: "GetUpload").json(operation: "GetUpload")
16
16
  end
17
17
  end
18
18
 
@@ -23,7 +23,7 @@ module Basecamp
23
23
  # @return [Hash] response data
24
24
  def update(upload_id:, description: nil, base_name: nil)
25
25
  with_operation(service: "uploads", operation: "update", is_mutation: true, resource_id: upload_id) do
26
- http_put("/uploads/#{upload_id}", body: compact_params(description: description, base_name: base_name)).json
26
+ http_put("/uploads/#{upload_id}", body: compact_params(description: description, base_name: base_name)).json(operation: "UpdateUpload")
27
27
  end
28
28
  end
29
29
 
@@ -51,7 +51,7 @@ module Basecamp
51
51
  # @return [Hash] response data
52
52
  def create_version(upload_id:, attachable_sgid:, base_name: nil, description: nil, notify: nil, subscriptions: nil)
53
53
  with_operation(service: "uploads", operation: "create_version", is_mutation: true, resource_id: upload_id) do
54
- http_post("/uploads/#{upload_id}/versions.json", body: compact_params(attachable_sgid: attachable_sgid, base_name: base_name, description: description, notify: notify, subscriptions: subscriptions)).json
54
+ http_post("/uploads/#{upload_id}/versions.json", body: compact_params(attachable_sgid: attachable_sgid, base_name: base_name, description: description, notify: notify, subscriptions: subscriptions)).json(operation: "CreateUploadVersion")
55
55
  end
56
56
  end
57
57
 
@@ -77,7 +77,7 @@ module Basecamp
77
77
  # @return [Hash] response data
78
78
  def create(vault_id:, attachable_sgid:, description: nil, base_name: nil, subscriptions: nil, visible_to_clients: nil)
79
79
  with_operation(service: "uploads", operation: "create", is_mutation: true, resource_id: vault_id) do
80
- http_post("/vaults/#{vault_id}/uploads.json", body: compact_params(attachable_sgid: attachable_sgid, description: description, base_name: base_name, subscriptions: subscriptions, visible_to_clients: visible_to_clients)).json
80
+ http_post("/vaults/#{vault_id}/uploads.json", body: compact_params(attachable_sgid: attachable_sgid, description: description, base_name: base_name, subscriptions: subscriptions, visible_to_clients: visible_to_clients)).json(operation: "CreateUpload")
81
81
  end
82
82
  end
83
83
 
@@ -12,7 +12,7 @@ module Basecamp
12
12
  # @return [Hash] response data
13
13
  def get(vault_id:)
14
14
  with_operation(service: "vaults", operation: "get", is_mutation: false, resource_id: vault_id) do
15
- http_get("/vaults/#{vault_id}", operation: "GetVault").json
15
+ http_get("/vaults/#{vault_id}", operation: "GetVault").json(operation: "GetVault")
16
16
  end
17
17
  end
18
18
 
@@ -22,7 +22,7 @@ module Basecamp
22
22
  # @return [Hash] response data
23
23
  def update(vault_id:, title: nil)
24
24
  with_operation(service: "vaults", operation: "update", is_mutation: true, resource_id: vault_id) do
25
- http_put("/vaults/#{vault_id}", body: compact_params(title: title)).json
25
+ http_put("/vaults/#{vault_id}", body: compact_params(title: title)).json(operation: "UpdateVault")
26
26
  end
27
27
  end
28
28
 
@@ -44,7 +44,7 @@ module Basecamp
44
44
  # @return [Hash] response data
45
45
  def create(vault_id:, title:)
46
46
  with_operation(service: "vaults", operation: "create", is_mutation: true, resource_id: vault_id) do
47
- http_post("/vaults/#{vault_id}/vaults.json", body: compact_params(title: title)).json
47
+ http_post("/vaults/#{vault_id}/vaults.json", body: compact_params(title: title)).json(operation: "CreateVault")
48
48
  end
49
49
  end
50
50
  end
@@ -25,7 +25,7 @@ module Basecamp
25
25
  # @return [Hash] response data
26
26
  def create(bucket_id:, payload_url:, types:, active: nil)
27
27
  with_operation(service: "webhooks", operation: "create", is_mutation: true, project_id: bucket_id) do
28
- http_post("/buckets/#{bucket_id}/webhooks.json", body: compact_params(payload_url: payload_url, types: types, active: active)).json
28
+ http_post("/buckets/#{bucket_id}/webhooks.json", body: compact_params(payload_url: payload_url, types: types, active: active)).json(operation: "CreateWebhook")
29
29
  end
30
30
  end
31
31
 
@@ -34,7 +34,7 @@ module Basecamp
34
34
  # @return [Hash] response data
35
35
  def get(webhook_id:)
36
36
  with_operation(service: "webhooks", operation: "get", is_mutation: false, resource_id: webhook_id) do
37
- http_get("/webhooks/#{webhook_id}", operation: "GetWebhook").json
37
+ http_get("/webhooks/#{webhook_id}", operation: "GetWebhook").json(operation: "GetWebhook")
38
38
  end
39
39
  end
40
40
 
@@ -46,7 +46,7 @@ module Basecamp
46
46
  # @return [Hash] response data
47
47
  def update(webhook_id:, payload_url: nil, types: nil, active: nil)
48
48
  with_operation(service: "webhooks", operation: "update", is_mutation: true, resource_id: webhook_id) do
49
- http_put("/webhooks/#{webhook_id}", body: compact_params(payload_url: payload_url, types: types, active: active)).json
49
+ http_put("/webhooks/#{webhook_id}", body: compact_params(payload_url: payload_url, types: types, active: active)).json(operation: "UpdateWebhook")
50
50
  end
51
51
  end
52
52
 
@@ -14,7 +14,7 @@ module Basecamp
14
14
  # @return [Hash] response data
15
15
  def update(bucket_id:, wormhole_id:, destination_recording_id:)
16
16
  with_operation(service: "wormholes", operation: "update", is_mutation: true, project_id: bucket_id, resource_id: wormhole_id) do
17
- http_put("/buckets/#{bucket_id}/card_tables/wormholes/#{wormhole_id}", body: compact_params(destination_recording_id: destination_recording_id)).json
17
+ http_put("/buckets/#{bucket_id}/card_tables/wormholes/#{wormhole_id}", body: compact_params(destination_recording_id: destination_recording_id)).json(operation: "UpdateWormhole")
18
18
  end
19
19
  end
20
20
 
@@ -36,7 +36,7 @@ module Basecamp
36
36
  # @return [Hash] response data
37
37
  def create(bucket_id:, card_table_id:, destination_recording_id:)
38
38
  with_operation(service: "wormholes", operation: "create", is_mutation: true, project_id: bucket_id, resource_id: card_table_id) do
39
- http_post("/buckets/#{bucket_id}/card_tables/#{card_table_id}/wormholes.json", body: compact_params(destination_recording_id: destination_recording_id)).json
39
+ http_post("/buckets/#{bucket_id}/card_tables/#{card_table_id}/wormholes.json", body: compact_params(destination_recording_id: destination_recording_id)).json(operation: "CreateWormhole")
40
40
  end
41
41
  end
42
42
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Auto-generated from OpenAPI spec. Do not edit manually.
4
- # Generated: 2026-09-10T03:48:29Z
4
+ # Generated: 2026-09-16T11:13:05Z
5
5
 
6
6
  require "json"
7
7
  require "time"
@@ -19,6 +19,23 @@ module TypeHelpers
19
19
  value.to_i
20
20
  end
21
21
 
22
+ # A PERSON's id: the one field in this model the reference decodes
23
+ # flexibly (x-go-type: types.FlexibleInt64), and the only one that may
24
+ # arrive as a JSON string.
25
+ #
26
+ # Read with Basecamp::Ids.person_from_wire, which is Go's
27
+ # strconv.ParseInt(s, 10, 64) and is already the rule at the other two
28
+ # person-id sites (the pre-decode normalizer in Basecamp::Http and the
29
+ # flexible reader itself). NOT parse_integer, whose to_i answers 0 for
30
+ # "basecamp" without recording the label, 8 for "010", and — since the
31
+ # normalizer now leaves an out-of-range id as a String for the reader to
32
+ # refuse — a bignum for "18446744073709551616x", which is not an id any
33
+ # API can hold. A refused id is nil here, the same nil a malformed value
34
+ # of any other type gets.
35
+ def parse_flexible_person_id(value)
36
+ Basecamp::Ids.person_from_wire(value)
37
+ end
38
+
22
39
  def parse_float(value)
23
40
  return nil if value.nil?
24
41
  value.to_f
@@ -1724,7 +1741,7 @@ module Basecamp
1724
1741
  # Event
1725
1742
  class Event
1726
1743
  include TypeHelpers
1727
- attr_accessor :action, :created_at, :creator, :id, :recording_id, :boosts_count, :boosts_url, :details
1744
+ attr_accessor :action, :created_at, :creator, :id, :recording_id, :boosts_count, :boosts_url, :details, :performed_by
1728
1745
 
1729
1746
  # @return [Array<Symbol>]
1730
1747
  def self.required_fields
@@ -1740,6 +1757,7 @@ module Basecamp
1740
1757
  @boosts_count = parse_integer(data["boosts_count"])
1741
1758
  @boosts_url = data["boosts_url"]
1742
1759
  @details = parse_type(data["details"], "EventDetails")
1760
+ @performed_by = parse_type(data["performed_by"], "Person")
1743
1761
  end
1744
1762
 
1745
1763
  def to_h
@@ -1752,6 +1770,7 @@ module Basecamp
1752
1770
  "boosts_count" => @boosts_count,
1753
1771
  "boosts_url" => @boosts_url,
1754
1772
  "details" => @details,
1773
+ "performed_by" => @performed_by,
1755
1774
  }.compact
1756
1775
  end
1757
1776
 
@@ -1866,6 +1885,49 @@ module Basecamp
1866
1885
  end
1867
1886
  end
1868
1887
 
1888
+ # FeedEvent
1889
+ class FeedEvent
1890
+ include TypeHelpers
1891
+ attr_accessor :action, :bucket_id, :created_at, :creator_id, :event_type, :id, :kind, :recording_id, :details, :performed_by_id
1892
+
1893
+ # @return [Array<Symbol>]
1894
+ def self.required_fields
1895
+ %i[action bucket_id created_at creator_id event_type id kind recording_id].freeze
1896
+ end
1897
+
1898
+ def initialize(data = {})
1899
+ @action = data["action"]
1900
+ @bucket_id = parse_integer(data["bucket_id"])
1901
+ @created_at = parse_datetime(data["created_at"])
1902
+ @creator_id = parse_integer(data["creator_id"])
1903
+ @event_type = data["event_type"]
1904
+ @id = parse_integer(data["id"])
1905
+ @kind = data["kind"]
1906
+ @recording_id = parse_integer(data["recording_id"])
1907
+ @details = data["details"]
1908
+ @performed_by_id = data["performed_by_id"]
1909
+ end
1910
+
1911
+ def to_h
1912
+ {
1913
+ "action" => @action,
1914
+ "bucket_id" => @bucket_id,
1915
+ "created_at" => @created_at,
1916
+ "creator_id" => @creator_id,
1917
+ "event_type" => @event_type,
1918
+ "id" => @id,
1919
+ "kind" => @kind,
1920
+ "recording_id" => @recording_id,
1921
+ "details" => @details,
1922
+ "performed_by_id" => @performed_by_id,
1923
+ }.compact
1924
+ end
1925
+
1926
+ def to_json(*args)
1927
+ to_h.to_json(*args)
1928
+ end
1929
+ end
1930
+
1869
1931
  # FieldKeyedErrors
1870
1932
  class FieldKeyedErrors
1871
1933
  include TypeHelpers
@@ -2175,14 +2237,15 @@ module Basecamp
2175
2237
  # GaugeNeedle
2176
2238
  class GaugeNeedle
2177
2239
  include TypeHelpers
2178
- attr_accessor :created_at, :description_attachments, :id, :updated_at, :app_url, :bookmark_url, :boosts_count, :boosts_url, :bucket, :color, :comments_count, :comments_url, :creator, :description, :inherits_status, :parent, :position, :status, :subscription_url, :title, :type, :url, :visible_to_clients
2240
+ attr_accessor :comment_count, :created_at, :description_attachments, :id, :updated_at, :app_url, :bookmark_url, :boosts_count, :boosts_url, :bucket, :color, :comments_count, :comments_url, :creator, :description, :inherits_status, :parent, :position, :status, :subscription_url, :title, :type, :url, :visible_to_clients
2179
2241
 
2180
2242
  # @return [Array<Symbol>]
2181
2243
  def self.required_fields
2182
- %i[created_at description_attachments id updated_at].freeze
2244
+ %i[comment_count created_at description_attachments id updated_at].freeze
2183
2245
  end
2184
2246
 
2185
2247
  def initialize(data = {})
2248
+ @comment_count = parse_integer(data["comment_count"])
2186
2249
  @created_at = parse_datetime(data["created_at"])
2187
2250
  @description_attachments = parse_array(data["description_attachments"], "RichTextAttachment")
2188
2251
  @id = parse_integer(data["id"])
@@ -2210,6 +2273,7 @@ module Basecamp
2210
2273
 
2211
2274
  def to_h
2212
2275
  {
2276
+ "comment_count" => @comment_count,
2213
2277
  "created_at" => @created_at,
2214
2278
  "description_attachments" => @description_attachments,
2215
2279
  "id" => @id,
@@ -2275,6 +2339,11 @@ module Basecamp
2275
2339
  include TypeHelpers
2276
2340
  attr_accessor :description
2277
2341
 
2342
+ # @return [Array<Symbol>]
2343
+ def self.required_fields
2344
+ %i[description].freeze
2345
+ end
2346
+
2278
2347
  def initialize(data = {})
2279
2348
  @description = data["description"]
2280
2349
  end
@@ -2509,6 +2578,37 @@ module Basecamp
2509
2578
  end
2510
2579
  end
2511
2580
 
2581
+ # InboxItem
2582
+ class InboxItem
2583
+ include TypeHelpers
2584
+ attr_accessor :addressed_at, :addressing_id, :event, :reason
2585
+
2586
+ # @return [Array<Symbol>]
2587
+ def self.required_fields
2588
+ %i[addressed_at addressing_id event reason].freeze
2589
+ end
2590
+
2591
+ def initialize(data = {})
2592
+ @addressed_at = parse_datetime(data["addressed_at"])
2593
+ @addressing_id = parse_integer(data["addressing_id"])
2594
+ @event = parse_type(data["event"], "FeedEvent")
2595
+ @reason = data["reason"]
2596
+ end
2597
+
2598
+ def to_h
2599
+ {
2600
+ "addressed_at" => @addressed_at,
2601
+ "addressing_id" => @addressing_id,
2602
+ "event" => @event,
2603
+ "reason" => @reason,
2604
+ }.compact
2605
+ end
2606
+
2607
+ def to_json(*args)
2608
+ to_h.to_json(*args)
2609
+ end
2610
+ end
2611
+
2512
2612
  # LineupMarker
2513
2613
  class LineupMarker
2514
2614
  include TypeHelpers
@@ -3075,7 +3175,7 @@ module Basecamp
3075
3175
  end
3076
3176
 
3077
3177
  def initialize(data = {})
3078
- @id = parse_integer(data["id"])
3178
+ @id = parse_flexible_person_id(data["id"])
3079
3179
  @system_label = data["system_label"]
3080
3180
  @name = data["name"]
3081
3181
  @admin = parse_boolean(data["admin"])
@@ -5688,7 +5788,7 @@ module Basecamp
5688
5788
  # WebhookEvent
5689
5789
  class WebhookEvent
5690
5790
  include TypeHelpers
5691
- attr_accessor :copy, :created_at, :creator, :details, :id, :kind, :recording
5791
+ attr_accessor :copy, :created_at, :creator, :details, :id, :kind, :performed_by, :recording
5692
5792
 
5693
5793
  def initialize(data = {})
5694
5794
  @copy = parse_type(data["copy"], "WebhookCopy")
@@ -5697,6 +5797,7 @@ module Basecamp
5697
5797
  @details = data["details"]
5698
5798
  @id = parse_integer(data["id"])
5699
5799
  @kind = data["kind"]
5800
+ @performed_by = parse_type(data["performed_by"], "Person")
5700
5801
  @recording = parse_type(data["recording"], "Recording")
5701
5802
  end
5702
5803
 
@@ -5708,6 +5809,7 @@ module Basecamp
5708
5809
  "details" => @details,
5709
5810
  "id" => @id,
5710
5811
  "kind" => @kind,
5812
+ "performed_by" => @performed_by,
5711
5813
  "recording" => @recording,
5712
5814
  }.compact
5713
5815
  end