fopost 0.2.0 → 0.3.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 +169 -0
- data/README.md +593 -3
- data/lib/fopost/client.rb +29 -1
- data/lib/fopost/errors.rb +25 -0
- data/lib/fopost/file_part.rb +73 -0
- data/lib/fopost/http/client.rb +36 -4
- data/lib/fopost/http/multipart.rb +38 -0
- data/lib/fopost/models.rb +1855 -28
- data/lib/fopost/platforms.rb +27 -0
- data/lib/fopost/resources/account_groups.rb +37 -0
- data/lib/fopost/resources/accounts.rb +445 -3
- data/lib/fopost/resources/activity.rb +27 -0
- data/lib/fopost/resources/ads.rb +910 -7
- data/lib/fopost/resources/analytics.rb +63 -0
- data/lib/fopost/resources/blog.rb +206 -0
- data/lib/fopost/resources/blogs.rb +115 -0
- data/lib/fopost/resources/broadcasts.rb +189 -0
- data/lib/fopost/resources/contacts.rb +136 -0
- data/lib/fopost/resources/google_ads.rb +346 -0
- data/lib/fopost/resources/google_business.rb +166 -0
- data/lib/fopost/resources/inbox.rb +73 -7
- data/lib/fopost/resources/knowledge.rb +74 -0
- data/lib/fopost/resources/media.rb +56 -0
- data/lib/fopost/resources/posts.rb +75 -4
- data/lib/fopost/resources/validate.rb +37 -0
- data/lib/fopost/resources/whatsapp.rb +255 -0
- data/lib/fopost/version.rb +1 -1
- data/lib/fopost/webhooks.rb +97 -0
- data/lib/fopost.rb +2 -0
- metadata +17 -1
data/lib/fopost/models.rb
CHANGED
|
@@ -4,12 +4,44 @@ require 'fopost/model'
|
|
|
4
4
|
|
|
5
5
|
module Fopost
|
|
6
6
|
class MediaItem < Model
|
|
7
|
+
attribute :id
|
|
7
8
|
attribute :type
|
|
8
9
|
attribute :name
|
|
9
10
|
attribute :url
|
|
10
11
|
attribute :size
|
|
11
12
|
attribute :alt
|
|
12
13
|
attribute :thumbnail
|
|
14
|
+
attribute :preview_url
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Where and how to PUT the bytes of a direct upload.
|
|
18
|
+
class PresignedUpload < Model
|
|
19
|
+
attribute :upload_id
|
|
20
|
+
attribute :upload_url
|
|
21
|
+
attribute :method
|
|
22
|
+
attribute :headers, :hash
|
|
23
|
+
attribute :expires_at, :time
|
|
24
|
+
attribute :max_file_bytes
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The next connected-accounts tier and the ceiling it unlocks.
|
|
28
|
+
class UploadLimitTier < Model
|
|
29
|
+
attribute :up_to_accounts
|
|
30
|
+
attribute :max_file_bytes
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# What the workspace may upload: the ceiling by any route, the multipart
|
|
34
|
+
# ceiling per file, and how many files one request takes.
|
|
35
|
+
class UploadLimits < Model
|
|
36
|
+
attribute :max_file_bytes
|
|
37
|
+
attribute :source
|
|
38
|
+
attribute :connected_accounts
|
|
39
|
+
attribute :large_uploads_enabled
|
|
40
|
+
attribute :next_tier, UploadLimitTier
|
|
41
|
+
attribute :multipart_max_file_bytes
|
|
42
|
+
attribute :max_files_per_upload
|
|
43
|
+
attribute :direct_upload_available
|
|
44
|
+
attribute :allowed_types
|
|
13
45
|
end
|
|
14
46
|
|
|
15
47
|
# One block of a post. A thread is several blocks in order.
|
|
@@ -32,6 +64,487 @@ module Fopost
|
|
|
32
64
|
attribute :is_primary
|
|
33
65
|
attribute :health_status
|
|
34
66
|
attribute :last_health_check, :time
|
|
67
|
+
attribute :platform_name
|
|
68
|
+
# True when the account was connected before a permission it now needs was asked for.
|
|
69
|
+
attribute :reconnect_required
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The result of renaming an account; `name` is the override when set, else the platform name.
|
|
73
|
+
class AccountRename < Model
|
|
74
|
+
attribute :id
|
|
75
|
+
attribute :name
|
|
76
|
+
attribute :platform_name
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The result of moving an account to another workspace.
|
|
80
|
+
class AccountMove < Model
|
|
81
|
+
attribute :id
|
|
82
|
+
attribute :workspace_id
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# A one-time code that connects a Telegram chat; send `command` to the bot there.
|
|
86
|
+
class TelegramConnectCode < Model
|
|
87
|
+
attribute :code
|
|
88
|
+
attribute :command
|
|
89
|
+
attribute :bot_username
|
|
90
|
+
attribute :deep_link
|
|
91
|
+
attribute :group_link
|
|
92
|
+
attribute :expires_at, :time
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Where a connect code stands: `pending`, `connected`, `failed` or `expired`.
|
|
96
|
+
class TelegramConnectStatus < Model
|
|
97
|
+
attribute :status
|
|
98
|
+
attribute :account_id
|
|
99
|
+
attribute :reason
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# One entry in the bot's command menu.
|
|
103
|
+
class TelegramBotCommand < Model
|
|
104
|
+
attribute :command
|
|
105
|
+
attribute :description
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# The command menu the bot shows in a connected chat.
|
|
109
|
+
class TelegramBotCommands < Model
|
|
110
|
+
attribute :commands, [TelegramBotCommand]
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# A tappable prompt Messenger or Instagram shows before the first message.
|
|
114
|
+
class MetaIceBreaker < Model
|
|
115
|
+
attribute :question
|
|
116
|
+
attribute :payload
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# The ice breakers set on one account.
|
|
120
|
+
class MetaIceBreakers < Model
|
|
121
|
+
attribute :ice_breakers, [MetaIceBreaker]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# A menu item: a `postback` with a payload, or a `web_url` with a link.
|
|
125
|
+
class MetaMenuItem < Model
|
|
126
|
+
attribute :type
|
|
127
|
+
attribute :title
|
|
128
|
+
attribute :payload
|
|
129
|
+
attribute :url
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# One locale's menu; `default` is the fallback every language uses.
|
|
133
|
+
class MetaPersistentMenuEntry < Model
|
|
134
|
+
attribute :locale
|
|
135
|
+
attribute :call_to_actions, [MetaMenuItem]
|
|
136
|
+
attribute :composer_input_disabled
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# The persistent menu set on one account, one entry per locale.
|
|
140
|
+
class MetaPersistentMenu < Model
|
|
141
|
+
attribute :persistent_menu, [MetaPersistentMenuEntry]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# One locale's greeting, up to 160 characters.
|
|
145
|
+
class MetaGreetingText < Model
|
|
146
|
+
attribute :locale
|
|
147
|
+
attribute :text
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# The greeting set on one account, one entry per locale.
|
|
151
|
+
class MetaGreeting < Model
|
|
152
|
+
attribute :greeting, [MetaGreetingText]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# What the network delivers to the FoPost webhook for one account.
|
|
156
|
+
class WebhookSubscription < Model
|
|
157
|
+
attribute :subscribed
|
|
158
|
+
attribute :fields
|
|
159
|
+
attribute :missing_fields
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# The outcome of a Messenger thread hand-over; `app_id` is nil when control was taken back.
|
|
163
|
+
class InboxHandover < Model
|
|
164
|
+
attribute :app_id
|
|
165
|
+
attribute :control
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# A Pinterest board; `id` travels as the `board_id` platform setting to pin to it.
|
|
169
|
+
class PinterestBoard < Model
|
|
170
|
+
attribute :id
|
|
171
|
+
attribute :name
|
|
172
|
+
attribute :privacy
|
|
173
|
+
attribute :description
|
|
174
|
+
attribute :image
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# A playlist on the channel; `is_default` marks the one a new video joins by default.
|
|
178
|
+
class YouTubePlaylist < Model
|
|
179
|
+
attribute :id
|
|
180
|
+
attribute :title
|
|
181
|
+
attribute :description
|
|
182
|
+
attribute :privacy
|
|
183
|
+
attribute :item_count
|
|
184
|
+
attribute :thumbnail_url
|
|
185
|
+
attribute :is_default
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# A caption track on one of the channel's videos.
|
|
189
|
+
class YouTubeCaptionTrack < Model
|
|
190
|
+
attribute :id
|
|
191
|
+
attribute :language
|
|
192
|
+
attribute :name
|
|
193
|
+
attribute :track_kind
|
|
194
|
+
attribute :is_draft
|
|
195
|
+
attribute :is_auto_synced
|
|
196
|
+
attribute :last_updated
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# One caption track read back as text; `transcript` is SRT.
|
|
200
|
+
class YouTubeTranscript < Model
|
|
201
|
+
attribute :caption_id
|
|
202
|
+
attribute :transcript
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# The default post languages for a connection; up to three BCP-47 tags.
|
|
206
|
+
class BlueskyLanguages < Model
|
|
207
|
+
attribute :languages
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# The switches TikTok enforces at publish time, set on the account itself.
|
|
211
|
+
class TikTokCreatorInfo < Model
|
|
212
|
+
attribute :username
|
|
213
|
+
attribute :nickname
|
|
214
|
+
attribute :avatar_url
|
|
215
|
+
attribute :privacy_level_options
|
|
216
|
+
attribute :comment_disabled
|
|
217
|
+
attribute :duet_disabled
|
|
218
|
+
attribute :stitch_disabled
|
|
219
|
+
attribute :max_video_post_duration_sec
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# A track from TikTok's Commercial Music Library; `id` travels as the
|
|
223
|
+
# `music_id` platform setting.
|
|
224
|
+
class TikTokMusic < Model
|
|
225
|
+
attribute :id
|
|
226
|
+
attribute :title
|
|
227
|
+
attribute :author
|
|
228
|
+
attribute :duration_sec
|
|
229
|
+
attribute :cover_url
|
|
230
|
+
attribute :preview_url
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# A place a post can be tagged with; `id` travels as the `location_id`
|
|
234
|
+
# platform setting.
|
|
235
|
+
class TikTokPlace < Model
|
|
236
|
+
attribute :id
|
|
237
|
+
attribute :name
|
|
238
|
+
attribute :address
|
|
239
|
+
attribute :city
|
|
240
|
+
attribute :country
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# One of the account's own videos, resolved from a share link. TikTok serves
|
|
244
|
+
# no raw media file, so `download_url` is the share address.
|
|
245
|
+
class TikTokVideoSource < Model
|
|
246
|
+
attribute :video_id
|
|
247
|
+
attribute :title
|
|
248
|
+
attribute :description
|
|
249
|
+
attribute :duration_sec
|
|
250
|
+
attribute :cover_image_url
|
|
251
|
+
attribute :share_url
|
|
252
|
+
attribute :embed_link
|
|
253
|
+
attribute :download_url
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# A track a Reel can carry; `id` travels as the `audio_id` platform setting.
|
|
257
|
+
class InstagramAudio < Model
|
|
258
|
+
attribute :id
|
|
259
|
+
attribute :title
|
|
260
|
+
attribute :artist
|
|
261
|
+
attribute :duration_ms
|
|
262
|
+
attribute :audio_type
|
|
263
|
+
attribute :cover_artwork_url
|
|
264
|
+
attribute :preview_url
|
|
265
|
+
attribute :username
|
|
266
|
+
attribute :is_ads_eligible
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# What this account has published in the rolling window, and what is left.
|
|
270
|
+
class InstagramPublishingLimit < Model
|
|
271
|
+
attribute :quota_usage
|
|
272
|
+
attribute :quota_total
|
|
273
|
+
attribute :quota_duration_sec
|
|
274
|
+
attribute :remaining
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# A story still inside its 24 hours; `insights` is present only when asked for.
|
|
278
|
+
class InstagramStory < Model
|
|
279
|
+
attribute :id
|
|
280
|
+
attribute :media_type
|
|
281
|
+
attribute :media_product_type
|
|
282
|
+
attribute :permalink
|
|
283
|
+
attribute :media_url
|
|
284
|
+
attribute :thumbnail_url
|
|
285
|
+
attribute :caption
|
|
286
|
+
attribute :timestamp
|
|
287
|
+
attribute :insights
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Insights for one story.
|
|
291
|
+
class InstagramStoryInsights < Model
|
|
292
|
+
attribute :story_id
|
|
293
|
+
attribute :insights
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
# An entity a post can mention; `annotation` is what the post text carries.
|
|
297
|
+
class LinkedInMention < Model
|
|
298
|
+
attribute :urn
|
|
299
|
+
attribute :name
|
|
300
|
+
attribute :vanity_name
|
|
301
|
+
attribute :logo_url
|
|
302
|
+
attribute :type
|
|
303
|
+
attribute :annotation
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# A channel the Slack app can post to; `is_current` marks the one this account posts to.
|
|
307
|
+
# A blog on a connected site. `id` is the platform's own id, never a FoPost
|
|
308
|
+
# one. Shopify reports every blog on the store; WordPress has one implicit
|
|
309
|
+
# blog and reports it under the id `default`, so both answer the same shape.
|
|
310
|
+
class RemoteBlog < Model
|
|
311
|
+
attribute :id
|
|
312
|
+
attribute :title
|
|
313
|
+
attribute :handle
|
|
314
|
+
attribute :url
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# An article that already lives on a connected site.
|
|
318
|
+
class RemoteArticle < Model
|
|
319
|
+
attribute :id
|
|
320
|
+
attribute :blog_id
|
|
321
|
+
attribute :title
|
|
322
|
+
attribute :body_html
|
|
323
|
+
attribute :excerpt
|
|
324
|
+
# published, draft, pending or scheduled.
|
|
325
|
+
attribute :status
|
|
326
|
+
attribute :author_name
|
|
327
|
+
attribute :tags
|
|
328
|
+
attribute :image_url
|
|
329
|
+
attribute :url
|
|
330
|
+
attribute :published_at, :time
|
|
331
|
+
attribute :updated_at, :time
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# A product on a connected store. `price` is the lowest variant price.
|
|
335
|
+
class RemoteProduct < Model
|
|
336
|
+
attribute :id
|
|
337
|
+
attribute :title
|
|
338
|
+
attribute :handle
|
|
339
|
+
# active, draft or archived.
|
|
340
|
+
attribute :status
|
|
341
|
+
attribute :description
|
|
342
|
+
attribute :vendor
|
|
343
|
+
attribute :product_type
|
|
344
|
+
attribute :tags
|
|
345
|
+
attribute :image_url
|
|
346
|
+
attribute :url
|
|
347
|
+
attribute :price
|
|
348
|
+
attribute :currency
|
|
349
|
+
attribute :updated_at, :time
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
class SlackChannel < Model
|
|
353
|
+
attribute :id
|
|
354
|
+
attribute :name
|
|
355
|
+
attribute :is_private
|
|
356
|
+
attribute :is_member
|
|
357
|
+
attribute :is_current
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
# A person in the connected Slack workspace; `id` is the handle for starting a DM.
|
|
361
|
+
class SlackMember < Model
|
|
362
|
+
attribute :id
|
|
363
|
+
attribute :name
|
|
364
|
+
attribute :real_name
|
|
365
|
+
attribute :display_name
|
|
366
|
+
attribute :avatar
|
|
367
|
+
attribute :is_bot
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
# The name and icon a Slack account posts under; nil means the app default.
|
|
371
|
+
class SlackIdentity < Model
|
|
372
|
+
attribute :username
|
|
373
|
+
attribute :icon_url
|
|
374
|
+
attribute :icon_emoji
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
# A Discord text channel the bot can post to; `is_current` marks this account's.
|
|
378
|
+
class DiscordChannel < Model
|
|
379
|
+
attribute :id
|
|
380
|
+
attribute :name
|
|
381
|
+
# Discord's channel type: 0 text, 5 announcement, 15 forum.
|
|
382
|
+
attribute :type
|
|
383
|
+
attribute :parent_id
|
|
384
|
+
attribute :nsfw
|
|
385
|
+
# False when a channel permission in Discord shuts the bot out.
|
|
386
|
+
attribute :can_post
|
|
387
|
+
attribute :is_current
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
# The nickname and avatar the bot wears in the server; nil means its own.
|
|
391
|
+
class DiscordIdentity < Model
|
|
392
|
+
attribute :username
|
|
393
|
+
attribute :avatar_url
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# A message in the connected channel.
|
|
397
|
+
class DiscordMessage < Model
|
|
398
|
+
attribute :id
|
|
399
|
+
attribute :channel_id
|
|
400
|
+
attribute :content
|
|
401
|
+
attribute :author_id
|
|
402
|
+
attribute :author_name
|
|
403
|
+
attribute :pinned
|
|
404
|
+
attribute :created_at
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# A message the bot put somewhere.
|
|
408
|
+
class DiscordMessageRef < Model
|
|
409
|
+
attribute :id
|
|
410
|
+
attribute :channel_id
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
# A thread started on a message.
|
|
414
|
+
class DiscordThread < Model
|
|
415
|
+
attribute :id
|
|
416
|
+
attribute :name
|
|
417
|
+
attribute :parent_id
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# An event on the server's calendar; `channel_id` is a voice or stage channel,
|
|
421
|
+
# otherwise `location` says where it happens.
|
|
422
|
+
class DiscordScheduledEvent < Model
|
|
423
|
+
attribute :id
|
|
424
|
+
attribute :name
|
|
425
|
+
attribute :description
|
|
426
|
+
attribute :channel_id
|
|
427
|
+
attribute :location
|
|
428
|
+
attribute :start_time
|
|
429
|
+
attribute :end_time
|
|
430
|
+
# One of scheduled, active, completed, canceled.
|
|
431
|
+
attribute :status
|
|
432
|
+
attribute :user_count
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
# A person in the connected server; `id` is the member id for a DM or a role.
|
|
436
|
+
class DiscordMember < Model
|
|
437
|
+
attribute :id
|
|
438
|
+
attribute :username
|
|
439
|
+
attribute :display_name
|
|
440
|
+
attribute :nick
|
|
441
|
+
attribute :avatar
|
|
442
|
+
attribute :is_bot
|
|
443
|
+
attribute :roles
|
|
444
|
+
attribute :joined_at
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# A role in the connected server; `permissions` is Discord's bitfield as a decimal string.
|
|
448
|
+
class DiscordRole < Model
|
|
449
|
+
attribute :id
|
|
450
|
+
attribute :name
|
|
451
|
+
attribute :color
|
|
452
|
+
attribute :hoist
|
|
453
|
+
attribute :mentionable
|
|
454
|
+
# A managed role belongs to an integration and cannot be edited.
|
|
455
|
+
attribute :managed
|
|
456
|
+
attribute :position
|
|
457
|
+
attribute :permissions
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# One metric a network reports under its own name. `key` is the platform's own
|
|
461
|
+
# name and is stable; `label` is ours and may be reworded. `value` is a number
|
|
462
|
+
# for every kind but `series`, which is an array of points.
|
|
463
|
+
class PlatformMetricRow < Model
|
|
464
|
+
attribute :key
|
|
465
|
+
attribute :label
|
|
466
|
+
attribute :kind
|
|
467
|
+
attribute :value
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
# One side of a per-network metric set: the account itself, or its newest
|
|
471
|
+
# measured post. `external_post_id` is nil on the account side.
|
|
472
|
+
class PlatformMetricsBlock < Model
|
|
473
|
+
attribute :fetched_at
|
|
474
|
+
attribute :external_post_id
|
|
475
|
+
attribute :metrics, [PlatformMetricRow]
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
# What only this network reports, in its own vocabulary.
|
|
479
|
+
class AccountPlatformMetrics < Model
|
|
480
|
+
attribute :platform
|
|
481
|
+
attribute :account, PlatformMetricsBlock
|
|
482
|
+
attribute :post, PlatformMetricsBlock
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# A subreddit the account is in, or its own profile page. `can_post` is false
|
|
486
|
+
# where it may read but not submit.
|
|
487
|
+
class RedditSubreddit < Model
|
|
488
|
+
attribute :name
|
|
489
|
+
attribute :title
|
|
490
|
+
attribute :subscribers
|
|
491
|
+
attribute :over18
|
|
492
|
+
attribute :can_post
|
|
493
|
+
attribute :flair_enabled
|
|
494
|
+
attribute :icon_url
|
|
495
|
+
attribute :is_default
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# One rule a subreddit publishes; `applies_to` is 'link', 'comment' or 'all'.
|
|
499
|
+
class RedditSubredditRule < Model
|
|
500
|
+
attribute :name
|
|
501
|
+
attribute :description
|
|
502
|
+
attribute :applies_to
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
# The rules a subreddit publishes, in its own order.
|
|
506
|
+
class RedditSubredditRules < Model
|
|
507
|
+
attribute :subreddit
|
|
508
|
+
attribute :rules, [RedditSubredditRule]
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# A post flair, valid only in the subreddit it came from.
|
|
512
|
+
class RedditFlair < Model
|
|
513
|
+
attribute :id
|
|
514
|
+
attribute :text
|
|
515
|
+
# Whether the label may be replaced with your own text.
|
|
516
|
+
attribute :editable
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
# Post flairs one subreddit offers.
|
|
520
|
+
class RedditFlairs < Model
|
|
521
|
+
attribute :subreddit
|
|
522
|
+
attribute :flairs, [RedditFlair]
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# Where posts go when a post names none; nil means the account's own profile page.
|
|
526
|
+
class RedditDefaultSubreddit < Model
|
|
527
|
+
attribute :subreddit
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
# `ok` is true when the subreddit exists and takes a post from this account.
|
|
531
|
+
class SubredditCheck < Model
|
|
532
|
+
attribute :subreddit
|
|
533
|
+
attribute :exists
|
|
534
|
+
attribute :can_post
|
|
535
|
+
# The API field is over_18.
|
|
536
|
+
attribute :over_18 # rubocop:disable Naming/VariableNumber
|
|
537
|
+
attribute :flair_enabled
|
|
538
|
+
attribute :ok
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
# A named set of connected accounts in one workspace.
|
|
542
|
+
class AccountGroup < Model
|
|
543
|
+
attribute :id
|
|
544
|
+
attribute :name
|
|
545
|
+
attribute :account_ids
|
|
546
|
+
attribute :created_at, :time
|
|
547
|
+
attribute :updated_at, :time
|
|
35
548
|
end
|
|
36
549
|
|
|
37
550
|
# An account a post is targeted at, plus its per-account delivery state.
|
|
@@ -123,41 +636,195 @@ module Fopost
|
|
|
123
636
|
attribute :external_url
|
|
124
637
|
end
|
|
125
638
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
attribute :
|
|
131
|
-
attribute :
|
|
132
|
-
|
|
639
|
+
# ── Analytics ────────────────────────────────────────────────────
|
|
640
|
+
|
|
641
|
+
# One age band of GET /analytics/decay.
|
|
642
|
+
class DecayBand < Model
|
|
643
|
+
attribute :bucket
|
|
644
|
+
attribute :label
|
|
645
|
+
# Posts with at least one reading in this band.
|
|
646
|
+
attribute :posts
|
|
647
|
+
attribute :avg_engagements
|
|
648
|
+
attribute :avg_impressions
|
|
649
|
+
# Mean share of the post's final engagement reached by this age, 0-1.
|
|
650
|
+
attribute :share_of_final
|
|
133
651
|
end
|
|
134
652
|
|
|
135
|
-
#
|
|
136
|
-
class
|
|
137
|
-
|
|
653
|
+
# How engagement accumulates as a post ages.
|
|
654
|
+
class ContentDecay < Model
|
|
655
|
+
attribute :days
|
|
656
|
+
attribute :posts_measured
|
|
657
|
+
# First band where the average post had passed half its final engagement.
|
|
658
|
+
attribute :half_life_bucket
|
|
659
|
+
attribute :bands, [DecayBand]
|
|
660
|
+
end
|
|
138
661
|
|
|
139
|
-
|
|
662
|
+
class FrequencyWeek < Model
|
|
663
|
+
# Monday of the week, UTC, as YYYY-MM-DD.
|
|
664
|
+
attribute :week_start
|
|
665
|
+
attribute :posts
|
|
666
|
+
attribute :engagements
|
|
667
|
+
attribute :avg_engagements_per_post
|
|
668
|
+
end
|
|
140
669
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
670
|
+
class FrequencyBand < Model
|
|
671
|
+
attribute :band
|
|
672
|
+
attribute :label
|
|
673
|
+
attribute :weeks
|
|
674
|
+
attribute :posts
|
|
675
|
+
attribute :avg_posts_per_week
|
|
676
|
+
attribute :avg_engagements_per_post
|
|
677
|
+
# Engagements over reach, impressions as the stand-in; nil with neither.
|
|
678
|
+
attribute :engagement_rate
|
|
679
|
+
end
|
|
145
680
|
|
|
146
|
-
|
|
147
|
-
|
|
681
|
+
# Weekly cadence set against what each cadence earned per post.
|
|
682
|
+
class PostingFrequency < Model
|
|
683
|
+
attribute :days
|
|
684
|
+
attribute :weeks, [FrequencyWeek]
|
|
685
|
+
attribute :bands, [FrequencyBand]
|
|
686
|
+
# The cadence that earned the most per post; nil without posts.
|
|
687
|
+
attribute :best, FrequencyBand
|
|
688
|
+
end
|
|
148
689
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
690
|
+
# What moved between one timeline point and the one before it.
|
|
691
|
+
class TimelineDelta < Model
|
|
692
|
+
attribute :impressions
|
|
693
|
+
attribute :reach
|
|
694
|
+
attribute :engagements
|
|
695
|
+
attribute :likes
|
|
696
|
+
attribute :comments
|
|
697
|
+
attribute :shares
|
|
698
|
+
end
|
|
152
699
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
700
|
+
class TimelinePoint < Model
|
|
701
|
+
attribute :at, :time
|
|
702
|
+
# Minutes since publication; nil when the network never said when.
|
|
703
|
+
attribute :age_minutes
|
|
704
|
+
attribute :impressions
|
|
705
|
+
attribute :reach
|
|
706
|
+
attribute :engagements
|
|
707
|
+
attribute :likes
|
|
708
|
+
attribute :comments
|
|
709
|
+
attribute :shares
|
|
710
|
+
attribute :video_views
|
|
711
|
+
attribute :delta, TimelineDelta
|
|
712
|
+
end
|
|
156
713
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
714
|
+
# One delivery's readings: the same post on two networks decays differently.
|
|
715
|
+
class TimelineDelivery < Model
|
|
716
|
+
attribute :account_id
|
|
717
|
+
attribute :platform
|
|
718
|
+
attribute :username
|
|
719
|
+
attribute :external_post_id
|
|
720
|
+
attribute :posted_at, :time
|
|
721
|
+
attribute :points, [TimelinePoint]
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
# Every reading held for one post, one timeline per delivery.
|
|
725
|
+
class PostTimeline < Model
|
|
726
|
+
# nil when the post was made natively on the network.
|
|
727
|
+
attribute :post_id
|
|
728
|
+
attribute :deliveries, [TimelineDelivery]
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
class MetricChange < Model
|
|
732
|
+
attribute :account_id
|
|
733
|
+
attribute :platform
|
|
734
|
+
attribute :external_post_id
|
|
735
|
+
# nil for a post made natively on the network.
|
|
736
|
+
attribute :post_id
|
|
737
|
+
attribute :posted_at, :time
|
|
738
|
+
attribute :fetched_at, :time
|
|
739
|
+
attribute :impressions
|
|
740
|
+
attribute :reach
|
|
741
|
+
attribute :engagements
|
|
742
|
+
attribute :likes
|
|
743
|
+
attribute :comments
|
|
744
|
+
attribute :shares
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
# Readings since a cursor, with the cursor to pass next time.
|
|
748
|
+
class MetricChangePage < Model
|
|
749
|
+
attribute :since, :time
|
|
750
|
+
# Feed back as `since` to continue; nil when nothing changed.
|
|
751
|
+
attribute :cursor, :time
|
|
752
|
+
attribute :has_more
|
|
753
|
+
attribute :changes, [MetricChange]
|
|
754
|
+
end
|
|
755
|
+
|
|
756
|
+
class CollectPostDelivery < Model
|
|
757
|
+
attribute :account_id
|
|
758
|
+
attribute :platform
|
|
759
|
+
attribute :external_post_id
|
|
760
|
+
attribute :collected
|
|
761
|
+
attribute :fetched_at, :time
|
|
762
|
+
# Why the refresh did not happen.
|
|
763
|
+
attribute :message
|
|
764
|
+
end
|
|
765
|
+
|
|
766
|
+
class CollectPostResult < Model
|
|
767
|
+
attribute :collected
|
|
768
|
+
attribute :deliveries, [CollectPostDelivery]
|
|
769
|
+
end
|
|
770
|
+
|
|
771
|
+
class NativePostMetrics < Model
|
|
772
|
+
attribute :impressions
|
|
773
|
+
attribute :reach
|
|
774
|
+
attribute :engagements
|
|
775
|
+
attribute :likes
|
|
776
|
+
attribute :comments
|
|
777
|
+
attribute :shares
|
|
778
|
+
attribute :video_views
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
# A post on the account that never went out through FoPost.
|
|
782
|
+
class NativePost < Model
|
|
783
|
+
attribute :external_post_id
|
|
784
|
+
attribute :text
|
|
785
|
+
attribute :permalink
|
|
786
|
+
attribute :thumbnail_url
|
|
787
|
+
attribute :media_type
|
|
788
|
+
attribute :posted_at, :time
|
|
789
|
+
attribute :fetched_at, :time
|
|
790
|
+
attribute :metrics, NativePostMetrics
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
class PageMeta < Model
|
|
794
|
+
attribute :current_page
|
|
795
|
+
attribute :per_page
|
|
796
|
+
attribute :total
|
|
797
|
+
attribute :last_page
|
|
798
|
+
attribute :from
|
|
799
|
+
attribute :to
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
# One page of a list endpoint: its items plus the pagination meta.
|
|
803
|
+
class Page
|
|
804
|
+
include Enumerable
|
|
805
|
+
|
|
806
|
+
attr_reader :items, :meta
|
|
807
|
+
|
|
808
|
+
def initialize(items: [], meta: PageMeta.new)
|
|
809
|
+
@items = items
|
|
810
|
+
@meta = meta
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def each(&block)
|
|
814
|
+
return items.each unless block
|
|
815
|
+
|
|
816
|
+
items.each(&block)
|
|
817
|
+
self
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
def [](index)
|
|
821
|
+
items[index]
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
def size
|
|
825
|
+
items.size
|
|
826
|
+
end
|
|
827
|
+
alias length size
|
|
161
828
|
alias count size
|
|
162
829
|
|
|
163
830
|
def empty?
|
|
@@ -206,6 +873,49 @@ module Fopost
|
|
|
206
873
|
attribute :credits, AiCredits
|
|
207
874
|
end
|
|
208
875
|
|
|
876
|
+
# Advisory note from a validate call; never blocks publishing.
|
|
877
|
+
class ValidateSignal < Model
|
|
878
|
+
attribute :level
|
|
879
|
+
attribute :code
|
|
880
|
+
attribute :message
|
|
881
|
+
end
|
|
882
|
+
|
|
883
|
+
class ValidatePostPlatform < Model
|
|
884
|
+
attribute :platform
|
|
885
|
+
attribute :ready
|
|
886
|
+
attribute :issues
|
|
887
|
+
attribute :score
|
|
888
|
+
attribute :signals, [ValidateSignal]
|
|
889
|
+
end
|
|
890
|
+
|
|
891
|
+
class ValidatePostResult < Model
|
|
892
|
+
attribute :ready
|
|
893
|
+
attribute :platforms, [ValidatePostPlatform]
|
|
894
|
+
end
|
|
895
|
+
|
|
896
|
+
class ValidateLengthPlatform < Model
|
|
897
|
+
attribute :platform
|
|
898
|
+
attribute :length
|
|
899
|
+
attribute :limit
|
|
900
|
+
attribute :unit
|
|
901
|
+
attribute :ok
|
|
902
|
+
attribute :signals, [ValidateSignal]
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
class ValidateLengthResult < Model
|
|
906
|
+
attribute :ok
|
|
907
|
+
attribute :platforms, [ValidateLengthPlatform]
|
|
908
|
+
end
|
|
909
|
+
|
|
910
|
+
class ValidateMediaResult < Model
|
|
911
|
+
attribute :ok
|
|
912
|
+
attribute :issues
|
|
913
|
+
attribute :name
|
|
914
|
+
attribute :size
|
|
915
|
+
attribute :mime_type
|
|
916
|
+
attribute :type
|
|
917
|
+
end
|
|
918
|
+
|
|
209
919
|
# `page`, `per_page`, `total` on the inbox list endpoints.
|
|
210
920
|
class InboxPageMeta < Model
|
|
211
921
|
attribute :page
|
|
@@ -245,7 +955,7 @@ module Fopost
|
|
|
245
955
|
attribute :published, :hash
|
|
246
956
|
end
|
|
247
957
|
|
|
248
|
-
# A comment, mention or direct message on a connected account.
|
|
958
|
+
# A comment, mention, review or direct message on a connected account.
|
|
249
959
|
class InboxItem < Model
|
|
250
960
|
attribute :id
|
|
251
961
|
attribute :workspace_id
|
|
@@ -258,6 +968,8 @@ module Fopost
|
|
|
258
968
|
attribute :author_handle
|
|
259
969
|
attribute :author_avatar_url
|
|
260
970
|
attribute :text
|
|
971
|
+
# Stars on a review, 1-5. Nil on every other type.
|
|
972
|
+
attribute :rating
|
|
261
973
|
attribute :attachments, [InboxAttachment]
|
|
262
974
|
attribute :permalink
|
|
263
975
|
attribute :post_external_id
|
|
@@ -268,8 +980,24 @@ module Fopost
|
|
|
268
980
|
attribute :created_at, :time
|
|
269
981
|
attribute :can_reply
|
|
270
982
|
attribute :hidden
|
|
983
|
+
attribute :liked
|
|
984
|
+
# How the account voted where the network ranks by votes: 'up', 'down' or nil.
|
|
985
|
+
attribute :vote
|
|
986
|
+
attribute :pinned
|
|
987
|
+
attribute :reaction
|
|
988
|
+
attribute :edited_at, :time
|
|
271
989
|
attribute :can_hide
|
|
272
990
|
attribute :can_delete
|
|
991
|
+
attribute :can_like
|
|
992
|
+
attribute :can_vote
|
|
993
|
+
attribute :can_pin
|
|
994
|
+
attribute :can_edit
|
|
995
|
+
attribute :can_react
|
|
996
|
+
attribute :can_send_media
|
|
997
|
+
attribute :can_quick_reply
|
|
998
|
+
attribute :can_private_reply
|
|
999
|
+
# The platform's own state: published, held, spam or rejected.
|
|
1000
|
+
attribute :moderation_status
|
|
273
1001
|
attribute :post, :hash
|
|
274
1002
|
attribute :post_context, InboxPostContext
|
|
275
1003
|
attribute :account, InboxAccountRef
|
|
@@ -285,6 +1013,8 @@ module Fopost
|
|
|
285
1013
|
attribute :last_comment_at, :time
|
|
286
1014
|
attribute :last_comment_text
|
|
287
1015
|
attribute :last_comment_author
|
|
1016
|
+
# Stars, on a review thread. Nil on comments and mentions.
|
|
1017
|
+
attribute :rating
|
|
288
1018
|
attribute :post, InboxPostContext
|
|
289
1019
|
attribute :account, InboxAccountRef
|
|
290
1020
|
end
|
|
@@ -314,6 +1044,46 @@ module Fopost
|
|
|
314
1044
|
attribute :pending_reason
|
|
315
1045
|
attribute :dm_supported
|
|
316
1046
|
attribute :dm_pending_reason
|
|
1047
|
+
attribute :can_start_conversation
|
|
1048
|
+
# The grant predates a permission the inbox needs; reconnect the account once.
|
|
1049
|
+
attribute :reconnect_required
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
# One thing the workspace has told FoPost about itself: an FAQ, a note, a page
|
|
1053
|
+
# on its own site, or a plain-text/CSV file from the media library.
|
|
1054
|
+
class KnowledgeSource < Model
|
|
1055
|
+
attribute :id
|
|
1056
|
+
# `faq`, `text`, `url` or `file`.
|
|
1057
|
+
attribute :kind
|
|
1058
|
+
attribute :title
|
|
1059
|
+
# Only a `ready` source is searched.
|
|
1060
|
+
attribute :status
|
|
1061
|
+
# Why the last sync failed, in plain words.
|
|
1062
|
+
attribute :status_message
|
|
1063
|
+
# Set for `url` sources.
|
|
1064
|
+
attribute :url
|
|
1065
|
+
# Set for `file` sources: the media library item read.
|
|
1066
|
+
attribute :media_id
|
|
1067
|
+
# nil means the source serves the whole workspace.
|
|
1068
|
+
attribute :brand_voice_id
|
|
1069
|
+
# Searchable passages the last sync produced.
|
|
1070
|
+
attribute :chunk_count
|
|
1071
|
+
# The typed text, for `faq` and `text` sources only.
|
|
1072
|
+
attribute :content
|
|
1073
|
+
attribute :last_synced_at, :time
|
|
1074
|
+
attribute :created_at, :time
|
|
1075
|
+
attribute :updated_at, :time
|
|
1076
|
+
end
|
|
1077
|
+
|
|
1078
|
+
# One retrieved passage, with the source it came from so a reply can cite it.
|
|
1079
|
+
class KnowledgeMatch < Model
|
|
1080
|
+
attribute :source_id
|
|
1081
|
+
attribute :source_title
|
|
1082
|
+
attribute :source_kind
|
|
1083
|
+
attribute :source_url
|
|
1084
|
+
attribute :text
|
|
1085
|
+
# Similarity to the question, 0-1.
|
|
1086
|
+
attribute :score
|
|
317
1087
|
end
|
|
318
1088
|
|
|
319
1089
|
class InboxPlatform < Model
|
|
@@ -337,6 +1107,12 @@ module Fopost
|
|
|
337
1107
|
attribute :reply, :hash
|
|
338
1108
|
end
|
|
339
1109
|
|
|
1110
|
+
# A DM opened by handle or as a private reply to a comment.
|
|
1111
|
+
class InboxStartedConversation < Model
|
|
1112
|
+
attribute :conversation_id
|
|
1113
|
+
attribute :item, InboxItem
|
|
1114
|
+
end
|
|
1115
|
+
|
|
340
1116
|
class InboxRefreshResult < Model
|
|
341
1117
|
attribute :accounts_polled
|
|
342
1118
|
attribute :new_items
|
|
@@ -408,8 +1184,21 @@ module Fopost
|
|
|
408
1184
|
end
|
|
409
1185
|
|
|
410
1186
|
# A connection with the ad accounts and Pages its grant reaches.
|
|
1187
|
+
# An ad network from the API's registry. `configured` false cannot be connected yet.
|
|
1188
|
+
class AdProvider < Model
|
|
1189
|
+
attribute :id
|
|
1190
|
+
attribute :name
|
|
1191
|
+
attribute :logo
|
|
1192
|
+
attribute :configured
|
|
1193
|
+
attribute :connect_methods
|
|
1194
|
+
attribute :capabilities
|
|
1195
|
+
attribute :targeting_facets
|
|
1196
|
+
attribute :tracking_macros
|
|
1197
|
+
end
|
|
1198
|
+
|
|
411
1199
|
class AdSource < Model
|
|
412
1200
|
attribute :connection_id
|
|
1201
|
+
attribute :provider
|
|
413
1202
|
attribute :name
|
|
414
1203
|
attribute :workspace_id
|
|
415
1204
|
attribute :ad_accounts
|
|
@@ -448,6 +1237,51 @@ module Fopost
|
|
|
448
1237
|
attribute :detail
|
|
449
1238
|
end
|
|
450
1239
|
|
|
1240
|
+
# A Business Center, or the network's equivalent grouping of ad accounts.
|
|
1241
|
+
class AdBusinessCenter < Model
|
|
1242
|
+
attribute :id
|
|
1243
|
+
attribute :name
|
|
1244
|
+
attribute :role
|
|
1245
|
+
end
|
|
1246
|
+
|
|
1247
|
+
# The account an ad runs as. Meta calls it a Page, TikTok an identity.
|
|
1248
|
+
class AdIdentity < Model
|
|
1249
|
+
attribute :id
|
|
1250
|
+
attribute :type
|
|
1251
|
+
attribute :name
|
|
1252
|
+
attribute :avatar_url
|
|
1253
|
+
end
|
|
1254
|
+
|
|
1255
|
+
# A post already live on the network, offered as the source of a Spark ad.
|
|
1256
|
+
class SparkPost < Model
|
|
1257
|
+
attribute :id
|
|
1258
|
+
attribute :identity_id
|
|
1259
|
+
attribute :caption
|
|
1260
|
+
attribute :thumbnail_url
|
|
1261
|
+
attribute :created_at
|
|
1262
|
+
attribute :views
|
|
1263
|
+
end
|
|
1264
|
+
|
|
1265
|
+
# A comment on an ad, read live from the network and never stored.
|
|
1266
|
+
class AdComment < Model
|
|
1267
|
+
attribute :id
|
|
1268
|
+
attribute :ad_id
|
|
1269
|
+
attribute :text
|
|
1270
|
+
attribute :author_name
|
|
1271
|
+
attribute :author_avatar_url
|
|
1272
|
+
attribute :created_at
|
|
1273
|
+
attribute :likes
|
|
1274
|
+
attribute :reply_count
|
|
1275
|
+
attribute :hidden
|
|
1276
|
+
attribute :parent_id
|
|
1277
|
+
end
|
|
1278
|
+
|
|
1279
|
+
# One page of an ad's comments; pass `next_cursor` back as `after`.
|
|
1280
|
+
class AdCommentsPage < Model
|
|
1281
|
+
attribute :comments, [AdComment]
|
|
1282
|
+
attribute :next_cursor
|
|
1283
|
+
end
|
|
1284
|
+
|
|
451
1285
|
class LeadForm < Model
|
|
452
1286
|
attribute :id
|
|
453
1287
|
attribute :name
|
|
@@ -482,4 +1316,997 @@ module Fopost
|
|
|
482
1316
|
attribute :leads, [Lead]
|
|
483
1317
|
attribute :next_cursor
|
|
484
1318
|
end
|
|
1319
|
+
|
|
1320
|
+
# A Meta ad inside an ad set. Read live from Meta, never stored.
|
|
1321
|
+
class NetworkAd < Model
|
|
1322
|
+
attribute :id
|
|
1323
|
+
attribute :name
|
|
1324
|
+
attribute :campaign_id
|
|
1325
|
+
attribute :ad_set_id
|
|
1326
|
+
attribute :creative_id
|
|
1327
|
+
attribute :status
|
|
1328
|
+
attribute :effective_status
|
|
1329
|
+
attribute :created_at, :time
|
|
1330
|
+
end
|
|
1331
|
+
|
|
1332
|
+
class AdSet < Model
|
|
1333
|
+
attribute :id
|
|
1334
|
+
attribute :name
|
|
1335
|
+
attribute :campaign_id
|
|
1336
|
+
attribute :status
|
|
1337
|
+
attribute :effective_status
|
|
1338
|
+
attribute :budget_minor
|
|
1339
|
+
attribute :budget_type
|
|
1340
|
+
attribute :end_at, :time
|
|
1341
|
+
attribute :optimization_goal
|
|
1342
|
+
attribute :created_at, :time
|
|
1343
|
+
attribute :ads, [NetworkAd]
|
|
1344
|
+
end
|
|
1345
|
+
|
|
1346
|
+
class AdCampaign < Model
|
|
1347
|
+
attribute :id
|
|
1348
|
+
attribute :name
|
|
1349
|
+
attribute :status
|
|
1350
|
+
attribute :effective_status
|
|
1351
|
+
attribute :objective
|
|
1352
|
+
attribute :budget_minor
|
|
1353
|
+
attribute :budget_type
|
|
1354
|
+
attribute :created_at, :time
|
|
1355
|
+
attribute :ad_sets, [AdSet]
|
|
1356
|
+
end
|
|
1357
|
+
|
|
1358
|
+
# Campaigns with their ad sets and ads, read live from Meta.
|
|
1359
|
+
class AdAccountTree < Model
|
|
1360
|
+
attribute :ad_account_id
|
|
1361
|
+
attribute :currency
|
|
1362
|
+
attribute :workspace_id
|
|
1363
|
+
attribute :campaigns, [AdCampaign]
|
|
1364
|
+
end
|
|
1365
|
+
|
|
1366
|
+
class BulkAdStatusResult < Model
|
|
1367
|
+
attribute :id
|
|
1368
|
+
attribute :level
|
|
1369
|
+
attribute :ok
|
|
1370
|
+
attribute :error
|
|
1371
|
+
end
|
|
1372
|
+
|
|
1373
|
+
class AdCreative < Model
|
|
1374
|
+
attribute :id
|
|
1375
|
+
attribute :name
|
|
1376
|
+
attribute :format
|
|
1377
|
+
attribute :status
|
|
1378
|
+
attribute :title
|
|
1379
|
+
attribute :body
|
|
1380
|
+
attribute :link
|
|
1381
|
+
attribute :thumbnail_url
|
|
1382
|
+
attribute :call_to_action
|
|
1383
|
+
attribute :url_tags
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
# ─── Product catalogs ──────────────────────────────────────────
|
|
1387
|
+
|
|
1388
|
+
# A product catalog on the connection's business portfolio, read live.
|
|
1389
|
+
class ProductCatalog < Model
|
|
1390
|
+
attribute :id
|
|
1391
|
+
attribute :name
|
|
1392
|
+
attribute :vertical
|
|
1393
|
+
attribute :product_count
|
|
1394
|
+
end
|
|
1395
|
+
|
|
1396
|
+
class ProductCatalogsResult < Model
|
|
1397
|
+
attribute :catalogs, [ProductCatalog]
|
|
1398
|
+
attribute :workspace_id
|
|
1399
|
+
end
|
|
1400
|
+
|
|
1401
|
+
# One product in a catalog. `price_minor` is minor units of `currency`.
|
|
1402
|
+
class CatalogProduct < Model
|
|
1403
|
+
attribute :id
|
|
1404
|
+
# Your own key for the product.
|
|
1405
|
+
attribute :retailer_id
|
|
1406
|
+
attribute :name
|
|
1407
|
+
attribute :description
|
|
1408
|
+
attribute :availability
|
|
1409
|
+
attribute :condition
|
|
1410
|
+
attribute :price_minor
|
|
1411
|
+
attribute :currency
|
|
1412
|
+
attribute :image_url
|
|
1413
|
+
attribute :url
|
|
1414
|
+
end
|
|
1415
|
+
|
|
1416
|
+
class CatalogProductsPage < Model
|
|
1417
|
+
attribute :products, [CatalogProduct]
|
|
1418
|
+
attribute :next_cursor
|
|
1419
|
+
end
|
|
1420
|
+
|
|
1421
|
+
class CatalogBatchResult < Model
|
|
1422
|
+
attribute :handles
|
|
1423
|
+
# Products sent in this batch.
|
|
1424
|
+
attribute :accepted
|
|
1425
|
+
end
|
|
1426
|
+
|
|
1427
|
+
# Keeps a catalog in step with a product file you host.
|
|
1428
|
+
class ProductFeed < Model
|
|
1429
|
+
attribute :id
|
|
1430
|
+
attribute :name
|
|
1431
|
+
attribute :url
|
|
1432
|
+
attribute :schedule
|
|
1433
|
+
attribute :created_at, :time
|
|
1434
|
+
end
|
|
1435
|
+
|
|
1436
|
+
class ProductFeedUpload < Model
|
|
1437
|
+
attribute :id
|
|
1438
|
+
attribute :started_at, :time
|
|
1439
|
+
attribute :ended_at, :time
|
|
1440
|
+
attribute :status
|
|
1441
|
+
attribute :error_count
|
|
1442
|
+
attribute :warning_count
|
|
1443
|
+
end
|
|
1444
|
+
|
|
1445
|
+
# The slice of a catalog one catalog ad runs from.
|
|
1446
|
+
class ProductSet < Model
|
|
1447
|
+
attribute :id
|
|
1448
|
+
attribute :name
|
|
1449
|
+
attribute :product_count
|
|
1450
|
+
# The network's own product-set filter.
|
|
1451
|
+
attribute :filter
|
|
1452
|
+
end
|
|
1453
|
+
|
|
1454
|
+
# ─── Reach and frequency ───────────────────────────────────────
|
|
1455
|
+
|
|
1456
|
+
# A priced flight. Nothing is bought until it is reserved.
|
|
1457
|
+
class ReachFrequencyPrediction < Model
|
|
1458
|
+
attribute :id
|
|
1459
|
+
attribute :name
|
|
1460
|
+
attribute :status
|
|
1461
|
+
attribute :reach
|
|
1462
|
+
attribute :impressions
|
|
1463
|
+
attribute :frequency_cap
|
|
1464
|
+
# Account currency, minor units.
|
|
1465
|
+
attribute :budget_minor
|
|
1466
|
+
attribute :start_at, :time
|
|
1467
|
+
attribute :end_at, :time
|
|
1468
|
+
# True once the prediction holds inventory.
|
|
1469
|
+
attribute :reserved
|
|
1470
|
+
end
|
|
1471
|
+
|
|
1472
|
+
class ReachFrequencyResult < Model
|
|
1473
|
+
attribute :predictions, [ReachFrequencyPrediction]
|
|
1474
|
+
attribute :workspace_id
|
|
1475
|
+
end
|
|
1476
|
+
|
|
1477
|
+
# ─── Ad Library ────────────────────────────────────────────────
|
|
1478
|
+
|
|
1479
|
+
# One public archive entry. Read live on every search and stored nowhere.
|
|
1480
|
+
class AdLibraryEntry < Model
|
|
1481
|
+
attribute :id
|
|
1482
|
+
attribute :page_id
|
|
1483
|
+
attribute :page_name
|
|
1484
|
+
attribute :bodies
|
|
1485
|
+
attribute :titles
|
|
1486
|
+
attribute :link_urls
|
|
1487
|
+
attribute :snapshot_url
|
|
1488
|
+
attribute :publisher_platforms
|
|
1489
|
+
attribute :started_at, :time
|
|
1490
|
+
attribute :ended_at, :time
|
|
1491
|
+
# Only on the archive's disclosure entries.
|
|
1492
|
+
attribute :currency
|
|
1493
|
+
attribute :spend_lower
|
|
1494
|
+
attribute :spend_upper
|
|
1495
|
+
attribute :impressions_lower
|
|
1496
|
+
attribute :impressions_upper
|
|
1497
|
+
end
|
|
1498
|
+
|
|
1499
|
+
class AdLibraryPage < Model
|
|
1500
|
+
attribute :entries, [AdLibraryEntry]
|
|
1501
|
+
attribute :next_cursor
|
|
1502
|
+
end
|
|
1503
|
+
|
|
1504
|
+
# ─── Partnership ads ───────────────────────────────────────────
|
|
1505
|
+
|
|
1506
|
+
# A creator who allowlisted this advertiser for partnership ads.
|
|
1507
|
+
class PartnershipCreator < Model
|
|
1508
|
+
attribute :id
|
|
1509
|
+
attribute :username
|
|
1510
|
+
attribute :name
|
|
1511
|
+
attribute :status
|
|
1512
|
+
attribute :permissions
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
# ─── Ad account settings ───────────────────────────────────────
|
|
1516
|
+
|
|
1517
|
+
class AdActivity < Model
|
|
1518
|
+
attribute :id
|
|
1519
|
+
attribute :event_type
|
|
1520
|
+
attribute :actor_name
|
|
1521
|
+
attribute :object_name
|
|
1522
|
+
attribute :object_type
|
|
1523
|
+
attribute :extra_data
|
|
1524
|
+
attribute :created_at, :time
|
|
1525
|
+
end
|
|
1526
|
+
|
|
1527
|
+
class AdActivityResult < Model
|
|
1528
|
+
attribute :activity, [AdActivity]
|
|
1529
|
+
attribute :workspace_id
|
|
1530
|
+
end
|
|
1531
|
+
|
|
1532
|
+
# Groups campaigns, ad sets and ads for reporting.
|
|
1533
|
+
class AdLabel < Model
|
|
1534
|
+
attribute :id
|
|
1535
|
+
attribute :name
|
|
1536
|
+
attribute :created_at, :time
|
|
1537
|
+
end
|
|
1538
|
+
|
|
1539
|
+
# An A/B study splitting traffic across its cells.
|
|
1540
|
+
class AdStudy < Model
|
|
1541
|
+
attribute :id
|
|
1542
|
+
attribute :name
|
|
1543
|
+
attribute :description
|
|
1544
|
+
attribute :type
|
|
1545
|
+
attribute :status
|
|
1546
|
+
attribute :start_at, :time
|
|
1547
|
+
attribute :end_at, :time
|
|
1548
|
+
end
|
|
1549
|
+
|
|
1550
|
+
# How many iOS 14 campaigns an ad account may run at once, per app.
|
|
1551
|
+
class IosCampaignLimits < Model
|
|
1552
|
+
attribute :limit
|
|
1553
|
+
attribute :used
|
|
1554
|
+
attribute :app_id
|
|
1555
|
+
end
|
|
1556
|
+
|
|
1557
|
+
# A window the network should expect heavier spend over.
|
|
1558
|
+
class HighDemandPeriod < Model
|
|
1559
|
+
attribute :id
|
|
1560
|
+
attribute :start_at, :time
|
|
1561
|
+
attribute :end_at, :time
|
|
1562
|
+
attribute :budget_value
|
|
1563
|
+
attribute :budget_value_type
|
|
1564
|
+
end
|
|
1565
|
+
|
|
1566
|
+
# Weights conversions so some audiences count for more than others.
|
|
1567
|
+
class ValueRuleSet < Model
|
|
1568
|
+
attribute :id
|
|
1569
|
+
attribute :name
|
|
1570
|
+
attribute :status
|
|
1571
|
+
attribute :rules
|
|
1572
|
+
end
|
|
1573
|
+
|
|
1574
|
+
class ReachEstimate < Model
|
|
1575
|
+
attribute :lower
|
|
1576
|
+
attribute :upper
|
|
1577
|
+
attribute :ready
|
|
1578
|
+
end
|
|
1579
|
+
|
|
1580
|
+
# What the auction costs, in minor units of the ad account currency.
|
|
1581
|
+
class BidPricing < Model
|
|
1582
|
+
attribute :currency
|
|
1583
|
+
attribute :suggested_bid_minor
|
|
1584
|
+
attribute :min_bid_minor
|
|
1585
|
+
attribute :max_bid_minor
|
|
1586
|
+
attribute :daily_budget_floor_minor
|
|
1587
|
+
end
|
|
1588
|
+
|
|
1589
|
+
# What an audience would deliver at a budget, over the network's own window.
|
|
1590
|
+
class SupplyForecast < Model
|
|
1591
|
+
attribute :currency
|
|
1592
|
+
attribute :impressions
|
|
1593
|
+
attribute :clicks
|
|
1594
|
+
attribute :spend_minor
|
|
1595
|
+
attribute :window_days
|
|
1596
|
+
attribute :ready
|
|
1597
|
+
end
|
|
1598
|
+
|
|
1599
|
+
# How the network attributes a sale or a sign-up back to an ad set.
|
|
1600
|
+
class ConversionRule < Model
|
|
1601
|
+
attribute :id
|
|
1602
|
+
attribute :name
|
|
1603
|
+
attribute :type
|
|
1604
|
+
attribute :attribution
|
|
1605
|
+
attribute :post_click_window_days
|
|
1606
|
+
attribute :view_through_window_days
|
|
1607
|
+
attribute :value_minor
|
|
1608
|
+
attribute :currency
|
|
1609
|
+
attribute :enabled
|
|
1610
|
+
attribute :created_at
|
|
1611
|
+
attribute :campaign_ids
|
|
1612
|
+
end
|
|
1613
|
+
|
|
1614
|
+
class ConversionMetrics < Model
|
|
1615
|
+
attribute :conversions
|
|
1616
|
+
attribute :post_click_conversions
|
|
1617
|
+
attribute :view_through_conversions
|
|
1618
|
+
attribute :value_minor
|
|
1619
|
+
attribute :cost_per_conversion_minor
|
|
1620
|
+
end
|
|
1621
|
+
|
|
1622
|
+
# `spend_minor` is in the ad account currency, minor units; `ctr` is a percentage.
|
|
1623
|
+
class InsightsMetrics < Model
|
|
1624
|
+
attribute :impressions
|
|
1625
|
+
attribute :reach
|
|
1626
|
+
attribute :clicks
|
|
1627
|
+
attribute :spend_minor
|
|
1628
|
+
attribute :ctr
|
|
1629
|
+
attribute :leads
|
|
1630
|
+
end
|
|
1631
|
+
|
|
1632
|
+
class InsightsBreakdownRow < Model
|
|
1633
|
+
attribute :key
|
|
1634
|
+
attribute :metrics, InsightsMetrics
|
|
1635
|
+
end
|
|
1636
|
+
|
|
1637
|
+
class InsightsTimelineRow < Model
|
|
1638
|
+
attribute :date
|
|
1639
|
+
attribute :metrics, InsightsMetrics
|
|
1640
|
+
end
|
|
1641
|
+
|
|
1642
|
+
class AdInsightsReport < Model
|
|
1643
|
+
attribute :currency
|
|
1644
|
+
attribute :since
|
|
1645
|
+
attribute :until
|
|
1646
|
+
attribute :breakdown_by
|
|
1647
|
+
attribute :totals, InsightsMetrics
|
|
1648
|
+
attribute :breakdown, [InsightsBreakdownRow]
|
|
1649
|
+
attribute :timeline, [InsightsTimelineRow]
|
|
1650
|
+
|
|
1651
|
+
# The Meta id the report covers; `object_id` is taken by Ruby itself.
|
|
1652
|
+
def meta_object_id
|
|
1653
|
+
self['objectId']
|
|
1654
|
+
end
|
|
1655
|
+
end
|
|
1656
|
+
|
|
1657
|
+
class LeadFormDetail < Model
|
|
1658
|
+
attribute :id
|
|
1659
|
+
attribute :name
|
|
1660
|
+
attribute :status
|
|
1661
|
+
attribute :leads_count
|
|
1662
|
+
attribute :created_at, :time
|
|
1663
|
+
attribute :questions
|
|
1664
|
+
attribute :page_id
|
|
1665
|
+
attribute :privacy_policy_url
|
|
1666
|
+
attribute :locale
|
|
1667
|
+
end
|
|
1668
|
+
|
|
1669
|
+
# A lead stored from a subscribed Page.
|
|
1670
|
+
class FeedLead < Model
|
|
1671
|
+
attribute :id
|
|
1672
|
+
attribute :lead_id
|
|
1673
|
+
attribute :connection_id
|
|
1674
|
+
attribute :page_id
|
|
1675
|
+
attribute :form_id
|
|
1676
|
+
attribute :ad_id
|
|
1677
|
+
attribute :ad_name
|
|
1678
|
+
attribute :campaign_name
|
|
1679
|
+
attribute :platform
|
|
1680
|
+
attribute :is_organic
|
|
1681
|
+
attribute :fields
|
|
1682
|
+
attribute :submitted_at, :time
|
|
1683
|
+
attribute :workspace_id
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
# One page of the leads feed; pass `next_cursor` back as `cursor:` for the next.
|
|
1687
|
+
class LeadsFeedPage < Model
|
|
1688
|
+
attribute :leads, [FeedLead]
|
|
1689
|
+
attribute :next_cursor
|
|
1690
|
+
end
|
|
1691
|
+
|
|
1692
|
+
# Who did something: `user`, `api_key`, `agent` or `system`.
|
|
1693
|
+
class ActivityActor < Model
|
|
1694
|
+
attribute :type
|
|
1695
|
+
attribute :name
|
|
1696
|
+
end
|
|
1697
|
+
|
|
1698
|
+
# One thing that happened in a workspace. A `security` kind is an audit row.
|
|
1699
|
+
class ActivityEvent < Model
|
|
1700
|
+
attribute :id
|
|
1701
|
+
attribute :workspace_id
|
|
1702
|
+
attribute :kind
|
|
1703
|
+
attribute :ref_type
|
|
1704
|
+
attribute :ref_id
|
|
1705
|
+
attribute :summary
|
|
1706
|
+
attribute :actor, ActivityActor
|
|
1707
|
+
attribute :time, :time
|
|
1708
|
+
end
|
|
1709
|
+
|
|
1710
|
+
# One page of activity; pass `next_cursor` back as `cursor:` for the next.
|
|
1711
|
+
class ActivityPage < Model
|
|
1712
|
+
attribute :events, [ActivityEvent]
|
|
1713
|
+
attribute :next_cursor
|
|
1714
|
+
end
|
|
1715
|
+
|
|
1716
|
+
class LeadPage < Model
|
|
1717
|
+
attribute :connection_id
|
|
1718
|
+
attribute :page_id
|
|
1719
|
+
attribute :page_name
|
|
1720
|
+
attribute :created_at, :time
|
|
1721
|
+
attribute :workspace_id
|
|
1722
|
+
end
|
|
1723
|
+
# ─── Contacts ────────────────────────────────────────────────────
|
|
1724
|
+
|
|
1725
|
+
# One handle on one network. The handle is lower-cased with no leading @.
|
|
1726
|
+
class ContactChannel < Model
|
|
1727
|
+
attribute :platform
|
|
1728
|
+
attribute :handle
|
|
1729
|
+
# The platform's own id for this person, when the network gave us one.
|
|
1730
|
+
attribute :external_id
|
|
1731
|
+
end
|
|
1732
|
+
|
|
1733
|
+
class ContactLabel < Model
|
|
1734
|
+
attribute :id
|
|
1735
|
+
attribute :name
|
|
1736
|
+
attribute :color
|
|
1737
|
+
end
|
|
1738
|
+
|
|
1739
|
+
# One person, however many handles they write from.
|
|
1740
|
+
class Contact < Model
|
|
1741
|
+
attribute :id
|
|
1742
|
+
attribute :display_name
|
|
1743
|
+
attribute :channels, [ContactChannel]
|
|
1744
|
+
# inbox, radar or import — what first created the row.
|
|
1745
|
+
attribute :source
|
|
1746
|
+
attribute :note
|
|
1747
|
+
attribute :first_seen_at, :time
|
|
1748
|
+
attribute :last_seen_at, :time
|
|
1749
|
+
# Custom field values, keyed by field key.
|
|
1750
|
+
attribute :fields, :hash
|
|
1751
|
+
attribute :labels, [ContactLabel]
|
|
1752
|
+
# Only on a listing that spans workspaces.
|
|
1753
|
+
attribute :workspace_id
|
|
1754
|
+
end
|
|
1755
|
+
|
|
1756
|
+
# One thread a contact appears in.
|
|
1757
|
+
class ContactConversation < Model
|
|
1758
|
+
# How the inbox groups it: DM thread id, else root post id, else handle.
|
|
1759
|
+
attribute :key
|
|
1760
|
+
attribute :account_id
|
|
1761
|
+
attribute :account_username
|
|
1762
|
+
attribute :platform
|
|
1763
|
+
attribute :messages
|
|
1764
|
+
attribute :received
|
|
1765
|
+
attribute :sent
|
|
1766
|
+
attribute :last_message_at, :time
|
|
1767
|
+
attribute :last_item_id
|
|
1768
|
+
end
|
|
1769
|
+
|
|
1770
|
+
class ContactImportSkip < Model
|
|
1771
|
+
attribute :row
|
|
1772
|
+
attribute :reason
|
|
1773
|
+
end
|
|
1774
|
+
|
|
1775
|
+
# What a CSV import did.
|
|
1776
|
+
class ContactImportResult < Model
|
|
1777
|
+
attribute :created
|
|
1778
|
+
# Rows that folded into a contact already on file.
|
|
1779
|
+
attribute :merged
|
|
1780
|
+
attribute :skipped, [ContactImportSkip]
|
|
1781
|
+
# Columns that named neither a reserved field nor a custom field.
|
|
1782
|
+
attribute :unknown_columns
|
|
1783
|
+
end
|
|
1784
|
+
|
|
1785
|
+
# A column the workspace invented to keep about its contacts.
|
|
1786
|
+
class ContactField < Model
|
|
1787
|
+
attribute :id
|
|
1788
|
+
# Lower-case key, also the CSV column header. Fixed once created.
|
|
1789
|
+
attribute :key
|
|
1790
|
+
attribute :name
|
|
1791
|
+
# text, number, date, select or boolean.
|
|
1792
|
+
attribute :type
|
|
1793
|
+
# Allowed values when the type is select.
|
|
1794
|
+
attribute :options
|
|
1795
|
+
attribute :position
|
|
1796
|
+
end
|
|
1797
|
+
|
|
1798
|
+
class ConversationAnalyticsRow < Model
|
|
1799
|
+
attribute :key
|
|
1800
|
+
attribute :account_id
|
|
1801
|
+
attribute :platform
|
|
1802
|
+
attribute :received
|
|
1803
|
+
attribute :sent
|
|
1804
|
+
attribute :answered
|
|
1805
|
+
attribute :open
|
|
1806
|
+
# Median minutes to the first reply in this thread.
|
|
1807
|
+
attribute :median_response_minutes
|
|
1808
|
+
attribute :first_message_at, :time
|
|
1809
|
+
attribute :last_message_at, :time
|
|
1810
|
+
end
|
|
1811
|
+
|
|
1812
|
+
# Inbox analytics broken out per thread.
|
|
1813
|
+
class ConversationAnalytics < Model
|
|
1814
|
+
attribute :conversations, [ConversationAnalyticsRow]
|
|
1815
|
+
attribute :total
|
|
1816
|
+
attribute :page
|
|
1817
|
+
attribute :per_page
|
|
1818
|
+
end
|
|
1819
|
+
|
|
1820
|
+
# The pagination block a contacts listing returns.
|
|
1821
|
+
class ContactPageMeta < Model
|
|
1822
|
+
attribute :page
|
|
1823
|
+
attribute :per_page
|
|
1824
|
+
attribute :total
|
|
1825
|
+
end
|
|
1826
|
+
|
|
1827
|
+
# ─── Broadcasts and sequences ────────────────────────────────────
|
|
1828
|
+
|
|
1829
|
+
# What became of a broadcast's recipients, by status.
|
|
1830
|
+
class BroadcastCounts < Model
|
|
1831
|
+
attribute :total
|
|
1832
|
+
attribute :sent
|
|
1833
|
+
# Usually the messaging window doing its job.
|
|
1834
|
+
attribute :skipped
|
|
1835
|
+
attribute :failed
|
|
1836
|
+
attribute :pending
|
|
1837
|
+
end
|
|
1838
|
+
|
|
1839
|
+
# One message, sent into conversations the workspace already has.
|
|
1840
|
+
class Broadcast < Model
|
|
1841
|
+
attribute :id
|
|
1842
|
+
# Internal only; never sent to anyone.
|
|
1843
|
+
attribute :name
|
|
1844
|
+
attribute :text
|
|
1845
|
+
attribute :account_id
|
|
1846
|
+
attribute :audience, :hash
|
|
1847
|
+
# draft, scheduled, sending, sent or cancelled.
|
|
1848
|
+
attribute :status
|
|
1849
|
+
attribute :scheduled_at, :time
|
|
1850
|
+
attribute :sent_at, :time
|
|
1851
|
+
attribute :created_at, :time
|
|
1852
|
+
attribute :counts, BroadcastCounts
|
|
1853
|
+
# Only on a listing that spans workspaces.
|
|
1854
|
+
attribute :workspace_id
|
|
1855
|
+
end
|
|
1856
|
+
|
|
1857
|
+
# One contact on one broadcast, and what became of their message.
|
|
1858
|
+
class BroadcastRecipient < Model
|
|
1859
|
+
attribute :contact_id
|
|
1860
|
+
attribute :display_name
|
|
1861
|
+
# pending, sent, skipped or failed.
|
|
1862
|
+
attribute :status
|
|
1863
|
+
# Why nothing was sent: window_closed, no_conversation or
|
|
1864
|
+
# unsupported_platform. window_closed means the network's messaging
|
|
1865
|
+
# window had shut, so nothing was attempted.
|
|
1866
|
+
attribute :skip_reason
|
|
1867
|
+
attribute :sent_at, :time
|
|
1868
|
+
attribute :error
|
|
1869
|
+
end
|
|
1870
|
+
|
|
1871
|
+
# One message and how long after the previous step it goes out.
|
|
1872
|
+
class SequenceStep < Model
|
|
1873
|
+
attribute :delay_hours
|
|
1874
|
+
attribute :text
|
|
1875
|
+
attribute :media_id
|
|
1876
|
+
end
|
|
1877
|
+
|
|
1878
|
+
# Where a sequence's enrollments stand, by status.
|
|
1879
|
+
class SequenceEnrollmentCounts < Model
|
|
1880
|
+
attribute :total
|
|
1881
|
+
attribute :active
|
|
1882
|
+
attribute :completed
|
|
1883
|
+
attribute :stopped
|
|
1884
|
+
attribute :failed
|
|
1885
|
+
end
|
|
1886
|
+
|
|
1887
|
+
# A series of messages, each a delay after the one before.
|
|
1888
|
+
class Sequence < Model
|
|
1889
|
+
attribute :id
|
|
1890
|
+
attribute :name
|
|
1891
|
+
attribute :account_id
|
|
1892
|
+
attribute :steps, [SequenceStep]
|
|
1893
|
+
# active or paused. A paused sequence fires nothing.
|
|
1894
|
+
attribute :status
|
|
1895
|
+
attribute :created_at, :time
|
|
1896
|
+
attribute :enrollments, SequenceEnrollmentCounts
|
|
1897
|
+
# Only on a listing that spans workspaces.
|
|
1898
|
+
attribute :workspace_id
|
|
1899
|
+
end
|
|
1900
|
+
|
|
1901
|
+
# One contact walking one sequence.
|
|
1902
|
+
class Enrollment < Model
|
|
1903
|
+
attribute :id
|
|
1904
|
+
attribute :contact_id
|
|
1905
|
+
attribute :display_name
|
|
1906
|
+
# Steps already sent, so also the index of the next one.
|
|
1907
|
+
attribute :step
|
|
1908
|
+
attribute :next_at, :time
|
|
1909
|
+
# active, completed, stopped or failed.
|
|
1910
|
+
attribute :status
|
|
1911
|
+
attribute :last_sent_at, :time
|
|
1912
|
+
# On a skipped step, the reason it was skipped.
|
|
1913
|
+
attribute :error
|
|
1914
|
+
end
|
|
1915
|
+
|
|
1916
|
+
# ─── Google Ads ───────────────────────────────────────────────────
|
|
1917
|
+
|
|
1918
|
+
# A keyword on an ad group. `id` is `<customer_id>~keyword~<ad_group_id>~<criterion_id>`.
|
|
1919
|
+
class GoogleKeyword < Model
|
|
1920
|
+
attribute :id
|
|
1921
|
+
attribute :ad_group_id
|
|
1922
|
+
attribute :text
|
|
1923
|
+
attribute :match_type
|
|
1924
|
+
attribute :status
|
|
1925
|
+
# Account currency, minor units.
|
|
1926
|
+
attribute :cpc_bid_minor
|
|
1927
|
+
attribute :negative
|
|
1928
|
+
end
|
|
1929
|
+
|
|
1930
|
+
class GoogleKeywordIdea < Model
|
|
1931
|
+
attribute :text
|
|
1932
|
+
attribute :avg_monthly_searches
|
|
1933
|
+
attribute :competition
|
|
1934
|
+
attribute :low_top_of_page_bid_minor
|
|
1935
|
+
attribute :high_top_of_page_bid_minor
|
|
1936
|
+
end
|
|
1937
|
+
|
|
1938
|
+
class GoogleSearchTerm < Model
|
|
1939
|
+
attribute :term
|
|
1940
|
+
attribute :ad_group_id
|
|
1941
|
+
attribute :status
|
|
1942
|
+
attribute :metrics
|
|
1943
|
+
end
|
|
1944
|
+
|
|
1945
|
+
class GoogleBidStrategy < Model
|
|
1946
|
+
attribute :id
|
|
1947
|
+
attribute :name
|
|
1948
|
+
attribute :type
|
|
1949
|
+
attribute :status
|
|
1950
|
+
attribute :campaign_count
|
|
1951
|
+
end
|
|
1952
|
+
|
|
1953
|
+
class GoogleAdScheduleSlot < Model
|
|
1954
|
+
attribute :id
|
|
1955
|
+
attribute :day_of_week
|
|
1956
|
+
attribute :start_hour
|
|
1957
|
+
attribute :end_hour
|
|
1958
|
+
attribute :bid_modifier
|
|
1959
|
+
end
|
|
1960
|
+
|
|
1961
|
+
# A negative keyword list.
|
|
1962
|
+
class GoogleSharedSet < Model
|
|
1963
|
+
attribute :id
|
|
1964
|
+
attribute :name
|
|
1965
|
+
attribute :type
|
|
1966
|
+
attribute :member_count
|
|
1967
|
+
end
|
|
1968
|
+
|
|
1969
|
+
# A sitelink, callout or structured snippet.
|
|
1970
|
+
class GoogleAsset < Model
|
|
1971
|
+
attribute :id
|
|
1972
|
+
attribute :name
|
|
1973
|
+
attribute :type
|
|
1974
|
+
attribute :text
|
|
1975
|
+
attribute :final_url
|
|
1976
|
+
end
|
|
1977
|
+
|
|
1978
|
+
# Where an asset is attached; an asset with no links serves nowhere.
|
|
1979
|
+
class GoogleAssetLink < Model
|
|
1980
|
+
attribute :id
|
|
1981
|
+
attribute :asset_id
|
|
1982
|
+
attribute :level
|
|
1983
|
+
attribute :owner_id
|
|
1984
|
+
attribute :field_type
|
|
1985
|
+
attribute :status
|
|
1986
|
+
end
|
|
1987
|
+
|
|
1988
|
+
# A Performance Max asset group.
|
|
1989
|
+
class GoogleAssetGroup < Model
|
|
1990
|
+
attribute :id
|
|
1991
|
+
attribute :campaign_id
|
|
1992
|
+
attribute :name
|
|
1993
|
+
attribute :status
|
|
1994
|
+
attribute :final_urls
|
|
1995
|
+
end
|
|
1996
|
+
|
|
1997
|
+
# A lead from Local Services Ads, read live and never stored.
|
|
1998
|
+
class GoogleLocalServicesLead < Model
|
|
1999
|
+
attribute :id
|
|
2000
|
+
attribute :category
|
|
2001
|
+
attribute :service
|
|
2002
|
+
attribute :contact_name
|
|
2003
|
+
attribute :phone
|
|
2004
|
+
attribute :email
|
|
2005
|
+
attribute :status
|
|
2006
|
+
attribute :type
|
|
2007
|
+
attribute :created_at
|
|
2008
|
+
end
|
|
2009
|
+
|
|
2010
|
+
class GoogleConversionAction < Model
|
|
2011
|
+
attribute :id
|
|
2012
|
+
attribute :name
|
|
2013
|
+
attribute :category
|
|
2014
|
+
attribute :status
|
|
2015
|
+
attribute :type
|
|
2016
|
+
attribute :counting_type
|
|
2017
|
+
attribute :value_minor
|
|
2018
|
+
end
|
|
2019
|
+
|
|
2020
|
+
# What Google projects applying a recommendation would change.
|
|
2021
|
+
class GoogleRecommendationImpact < Model
|
|
2022
|
+
attribute :base_clicks
|
|
2023
|
+
attribute :potential_clicks
|
|
2024
|
+
attribute :base_cost_minor
|
|
2025
|
+
attribute :potential_cost_minor
|
|
2026
|
+
attribute :base_conversions
|
|
2027
|
+
attribute :potential_conversions
|
|
2028
|
+
end
|
|
2029
|
+
|
|
2030
|
+
# One of Google's own recommendations. The id is the Google resource name
|
|
2031
|
+
# rather than the `~` form other objects use, because a recommendation is not
|
|
2032
|
+
# an object you address again: it is what apply and dismiss take.
|
|
2033
|
+
class GoogleRecommendation < Model
|
|
2034
|
+
attribute :id
|
|
2035
|
+
attribute :type
|
|
2036
|
+
attribute :campaign_id
|
|
2037
|
+
attribute :ad_group_id
|
|
2038
|
+
attribute :dismissed
|
|
2039
|
+
attribute :impact, GoogleRecommendationImpact
|
|
2040
|
+
end
|
|
2041
|
+
|
|
2042
|
+
class GoogleOptimizationScoreCampaign < Model
|
|
2043
|
+
attribute :id
|
|
2044
|
+
attribute :name
|
|
2045
|
+
attribute :score
|
|
2046
|
+
end
|
|
2047
|
+
|
|
2048
|
+
# Google's estimate of how well the account is set up, from 0 to 1.
|
|
2049
|
+
class GoogleOptimizationScore < Model
|
|
2050
|
+
attribute :score
|
|
2051
|
+
attribute :weight
|
|
2052
|
+
attribute :campaigns, [GoogleOptimizationScoreCampaign]
|
|
2053
|
+
end
|
|
2054
|
+
|
|
2055
|
+
# ─── Blog ─────────────────────────────────────────────────────────
|
|
2056
|
+
|
|
2057
|
+
# The last keyword research run.
|
|
2058
|
+
class BlogPlanRun < Model
|
|
2059
|
+
# queued, running, done or failed.
|
|
2060
|
+
attribute :status
|
|
2061
|
+
attribute :error
|
|
2062
|
+
# New keywords the run found.
|
|
2063
|
+
attribute :added
|
|
2064
|
+
attribute :finished_at, :time
|
|
2065
|
+
end
|
|
2066
|
+
|
|
2067
|
+
# Where articles publish, what the blog is for and how often it is planned.
|
|
2068
|
+
# `website_secret` is never on this model; it is shown once, on the update
|
|
2069
|
+
# that first sets `website_url`, or on a rotation.
|
|
2070
|
+
class BlogSettings < Model
|
|
2071
|
+
attribute :site_url
|
|
2072
|
+
attribute :topic
|
|
2073
|
+
attribute :audience
|
|
2074
|
+
# traffic, leads, sales, signups or authority.
|
|
2075
|
+
attribute :goal
|
|
2076
|
+
attribute :focus_topics
|
|
2077
|
+
attribute :avoid_topics
|
|
2078
|
+
attribute :language
|
|
2079
|
+
attribute :location_code
|
|
2080
|
+
# Articles planned per week; 0 turns planning off.
|
|
2081
|
+
attribute :cadence_per_week
|
|
2082
|
+
# Days before its planned date that a picked keyword starts being written.
|
|
2083
|
+
attribute :review_hold_days
|
|
2084
|
+
# draft, standard or best.
|
|
2085
|
+
attribute :image_tier
|
|
2086
|
+
attribute :in_body_images
|
|
2087
|
+
attribute :min_words
|
|
2088
|
+
attribute :max_words
|
|
2089
|
+
attribute :brand_voice_id
|
|
2090
|
+
# product_blog, account or website.
|
|
2091
|
+
attribute :target_kind
|
|
2092
|
+
attribute :target_account_id
|
|
2093
|
+
attribute :target_platform
|
|
2094
|
+
attribute :website_url
|
|
2095
|
+
attribute :has_website_secret
|
|
2096
|
+
# Nil before the first run.
|
|
2097
|
+
attribute :plan_run, BlogPlanRun
|
|
2098
|
+
attribute :keyword_data_available
|
|
2099
|
+
attribute :updated_at, :time
|
|
2100
|
+
end
|
|
2101
|
+
|
|
2102
|
+
# What a settings update answers: the settings, plus the website secret on
|
|
2103
|
+
# the one update that first set `website_url`.
|
|
2104
|
+
class BlogSettingsUpdate < Model
|
|
2105
|
+
attribute :settings, BlogSettings
|
|
2106
|
+
attribute :website_secret
|
|
2107
|
+
end
|
|
2108
|
+
|
|
2109
|
+
# The outcome of a test delivery to `website_url`.
|
|
2110
|
+
class BlogWebsiteTest < Model
|
|
2111
|
+
# What the website answered.
|
|
2112
|
+
attribute :http_status
|
|
2113
|
+
end
|
|
2114
|
+
|
|
2115
|
+
class BlogKeyword < Model
|
|
2116
|
+
attribute :id
|
|
2117
|
+
attribute :keyword
|
|
2118
|
+
attribute :search_volume
|
|
2119
|
+
# 0 to 100.
|
|
2120
|
+
attribute :difficulty
|
|
2121
|
+
attribute :cpc
|
|
2122
|
+
attribute :intent
|
|
2123
|
+
# provider, user or agent.
|
|
2124
|
+
attribute :source
|
|
2125
|
+
# suggested, planned, written or dismissed.
|
|
2126
|
+
attribute :status
|
|
2127
|
+
# A date, YYYY-MM-DD.
|
|
2128
|
+
attribute :planned_for
|
|
2129
|
+
# Why the keyword serves the blog goal.
|
|
2130
|
+
attribute :fit_reason
|
|
2131
|
+
attribute :created_at, :time
|
|
2132
|
+
end
|
|
2133
|
+
|
|
2134
|
+
class BlogArticleImage < Model
|
|
2135
|
+
attribute :media_id
|
|
2136
|
+
attribute :url
|
|
2137
|
+
attribute :alt
|
|
2138
|
+
# Index of the outline heading the image sits under; absent on the featured image.
|
|
2139
|
+
attribute :position
|
|
2140
|
+
end
|
|
2141
|
+
|
|
2142
|
+
# One article as a listing shows it, without the body.
|
|
2143
|
+
class BlogArticle < Model
|
|
2144
|
+
attribute :id
|
|
2145
|
+
attribute :title
|
|
2146
|
+
attribute :slug
|
|
2147
|
+
attribute :keyword
|
|
2148
|
+
attribute :excerpt
|
|
2149
|
+
attribute :meta_title
|
|
2150
|
+
attribute :meta_description
|
|
2151
|
+
attribute :featured_image, BlogArticleImage
|
|
2152
|
+
attribute :tags
|
|
2153
|
+
attribute :word_count
|
|
2154
|
+
# queued, writing, draft, in_review, scheduled, publishing, published, failed or rejected.
|
|
2155
|
+
attribute :status
|
|
2156
|
+
# plan, user or agent.
|
|
2157
|
+
attribute :origin
|
|
2158
|
+
attribute :review_until, :time
|
|
2159
|
+
attribute :publish_at, :time
|
|
2160
|
+
attribute :published_at, :time
|
|
2161
|
+
attribute :published_url
|
|
2162
|
+
attribute :error
|
|
2163
|
+
attribute :created_at, :time
|
|
2164
|
+
attribute :updated_at, :time
|
|
2165
|
+
end
|
|
2166
|
+
|
|
2167
|
+
# An article with its body, outline and images.
|
|
2168
|
+
class BlogArticleFull < BlogArticle
|
|
2169
|
+
attribute :instructions
|
|
2170
|
+
attribute :outline
|
|
2171
|
+
# The research the writer worked from.
|
|
2172
|
+
attribute :brief, :hash
|
|
2173
|
+
attribute :body_markdown
|
|
2174
|
+
attribute :body_html
|
|
2175
|
+
attribute :images, [BlogArticleImage]
|
|
2176
|
+
end
|
|
2177
|
+
|
|
2178
|
+
# The `data` of an `article.published` webhook. Image URLs stay fetchable
|
|
2179
|
+
# for six hours; a receiver stores its own copy.
|
|
2180
|
+
class BlogArticlePublished < Model
|
|
2181
|
+
attribute :id
|
|
2182
|
+
attribute :title
|
|
2183
|
+
attribute :slug
|
|
2184
|
+
attribute :excerpt
|
|
2185
|
+
attribute :meta_title
|
|
2186
|
+
attribute :meta_description
|
|
2187
|
+
attribute :body_markdown
|
|
2188
|
+
attribute :body_html
|
|
2189
|
+
attribute :featured_image, BlogArticleImage
|
|
2190
|
+
attribute :images, [BlogArticleImage]
|
|
2191
|
+
attribute :tags
|
|
2192
|
+
attribute :keyword
|
|
2193
|
+
attribute :word_count
|
|
2194
|
+
attribute :published_at, :time
|
|
2195
|
+
attribute :published_url
|
|
2196
|
+
end
|
|
2197
|
+
|
|
2198
|
+
# The envelope every FoPost webhook delivers, after its signature checked out.
|
|
2199
|
+
class WebhookEvent < Model
|
|
2200
|
+
attribute :event
|
|
2201
|
+
attribute :data, :hash
|
|
2202
|
+
attribute :timestamp, :time
|
|
2203
|
+
|
|
2204
|
+
# The typed payload of an `article.published` (or `article.test`) delivery.
|
|
2205
|
+
def article
|
|
2206
|
+
BlogArticlePublished.new(data)
|
|
2207
|
+
end
|
|
2208
|
+
end
|
|
2209
|
+
|
|
2210
|
+
# ─── WhatsApp Business ─────────────────────────────────────────
|
|
2211
|
+
#
|
|
2212
|
+
# The platform owns these resources, so nothing here is a cached copy: a
|
|
2213
|
+
# template's status is whatever the platform assigned it.
|
|
2214
|
+
|
|
2215
|
+
# A message template on a WhatsApp Business Account.
|
|
2216
|
+
class WhatsappTemplate < Model
|
|
2217
|
+
attribute :id
|
|
2218
|
+
attribute :name
|
|
2219
|
+
attribute :language
|
|
2220
|
+
attribute :category
|
|
2221
|
+
# The review status the platform assigned: APPROVED, PENDING, REJECTED, …
|
|
2222
|
+
attribute :status
|
|
2223
|
+
attribute :rejected_reason
|
|
2224
|
+
attribute :components
|
|
2225
|
+
attribute :quality_score
|
|
2226
|
+
end
|
|
2227
|
+
|
|
2228
|
+
# The business profile on a WhatsApp number, plus its quality and limit tier.
|
|
2229
|
+
class WhatsappProfile < Model
|
|
2230
|
+
attribute :about
|
|
2231
|
+
attribute :address
|
|
2232
|
+
attribute :description
|
|
2233
|
+
attribute :email
|
|
2234
|
+
attribute :vertical
|
|
2235
|
+
attribute :websites
|
|
2236
|
+
attribute :profile_picture_url
|
|
2237
|
+
attribute :display_name
|
|
2238
|
+
# The platform's review state for the display name.
|
|
2239
|
+
attribute :display_name_status
|
|
2240
|
+
attribute :username
|
|
2241
|
+
attribute :quality_rating
|
|
2242
|
+
attribute :messaging_limit_tier
|
|
2243
|
+
end
|
|
2244
|
+
|
|
2245
|
+
# A group on a WhatsApp number. Participation is invite-only.
|
|
2246
|
+
class WhatsappGroup < Model
|
|
2247
|
+
attribute :id
|
|
2248
|
+
attribute :subject
|
|
2249
|
+
attribute :description
|
|
2250
|
+
attribute :participant_count
|
|
2251
|
+
attribute :invite_link
|
|
2252
|
+
attribute :created_at, :time
|
|
2253
|
+
end
|
|
2254
|
+
|
|
2255
|
+
# What the platform took and what it refused.
|
|
2256
|
+
class WhatsappBlockResult < Model
|
|
2257
|
+
attribute :blocked
|
|
2258
|
+
attribute :unblocked
|
|
2259
|
+
attribute :failed
|
|
2260
|
+
end
|
|
2261
|
+
|
|
2262
|
+
# Whether the cart and catalog show on the number, and which catalog is linked.
|
|
2263
|
+
class WhatsappCommerceSettings < Model
|
|
2264
|
+
attribute :cart_enabled
|
|
2265
|
+
attribute :catalog_visible
|
|
2266
|
+
attribute :catalog_id
|
|
2267
|
+
end
|
|
2268
|
+
|
|
2269
|
+
# An in-chat form. The platform validates it and owns its status.
|
|
2270
|
+
class WhatsappFlow < Model
|
|
2271
|
+
attribute :id
|
|
2272
|
+
attribute :name
|
|
2273
|
+
attribute :status
|
|
2274
|
+
attribute :categories
|
|
2275
|
+
attribute :validation_errors
|
|
2276
|
+
attribute :endpoint_uri
|
|
2277
|
+
attribute :json_version
|
|
2278
|
+
attribute :preview_url
|
|
2279
|
+
attribute :preview_expires_at, :time
|
|
2280
|
+
end
|
|
2281
|
+
|
|
2282
|
+
# The platform answers a flow upload with its validation errors, not a refusal.
|
|
2283
|
+
class WhatsappFlowJsonResult < Model
|
|
2284
|
+
attribute :success
|
|
2285
|
+
attribute :validation_errors
|
|
2286
|
+
end
|
|
2287
|
+
|
|
2288
|
+
# What one person submitted through a flow.
|
|
2289
|
+
class WhatsappFlowResponse < Model
|
|
2290
|
+
attribute :message_id
|
|
2291
|
+
attribute :wa_id
|
|
2292
|
+
attribute :flow_token
|
|
2293
|
+
attribute :answers
|
|
2294
|
+
attribute :responded_at, :time
|
|
2295
|
+
end
|
|
2296
|
+
|
|
2297
|
+
# Whether a key is registered. The key itself never comes back.
|
|
2298
|
+
class WhatsappEncryptionKeyStatus < Model
|
|
2299
|
+
attribute :has_key
|
|
2300
|
+
attribute :signature_status
|
|
2301
|
+
end
|
|
2302
|
+
|
|
2303
|
+
# A sandbox invitation. The tester's number is never stored in full.
|
|
2304
|
+
class WhatsappSandboxSession < Model
|
|
2305
|
+
attribute :id
|
|
2306
|
+
attribute :status
|
|
2307
|
+
attribute :phone_number_last4
|
|
2308
|
+
attribute :invited_at, :time
|
|
2309
|
+
attribute :activated_at, :time
|
|
2310
|
+
attribute :expires_at, :time
|
|
2311
|
+
end
|
|
485
2312
|
end
|