zelf-sdk 1.3.3 → 1.4.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/lib/zelf/models.rb +769 -0
- data/lib/zelf/resources/advanced_ai_analysis.rb +117 -0
- data/lib/zelf/resources/creator_vetting.rb +11 -13
- data/lib/zelf/version.rb +1 -1
- data/lib/zelf/webhooks.rb +3 -1
- data/lib/zelf.rb +4 -2
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13a7b277cfa9bd372edd4368827cc6ca506e6603ae6aa42414eed352a1c6cfb5
|
|
4
|
+
data.tar.gz: 63bddf5b19014ffe02a5c88b685f610a6102a40207920f20a09cea4f019db62c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e90caf2e9dae89dce9641ede27b5c492499669435621df72f9c5aa4dbdef398cb2cb470bbfe07f043a0ffc3d66965298bad1b73bf2bf4bb0504972127e3b978a
|
|
7
|
+
data.tar.gz: aef0623ef983d33faf60efd936c5a0ab35b1618e5302e83354b1924818e095c9d8bad63745b29314635865319d843dcfd0676dfd3ded0493dfb9a3ff802dfa09
|
data/lib/zelf/models.rb
CHANGED
|
@@ -90,8 +90,47 @@ module Zelf
|
|
|
90
90
|
"DISCLOSURE",
|
|
91
91
|
].freeze
|
|
92
92
|
|
|
93
|
+
class AdvancedAiAnalysis < Zelf::Model; end
|
|
94
|
+
class AdvancedAiAnalysisCreateRequest < Zelf::Model; end
|
|
95
|
+
class AdvancedAiAnalysisReport < Zelf::Model; end
|
|
96
|
+
class AdvancedAiAnalysisResult < Zelf::Model; end
|
|
97
|
+
class AdvancedAiAnalysisRun < Zelf::Model; end
|
|
98
|
+
class AdvancedAudienceVoice < Zelf::Model; end
|
|
99
|
+
class AdvancedContentForm < Zelf::Model; end
|
|
100
|
+
class AdvancedCoverage < Zelf::Model; end
|
|
101
|
+
class AdvancedCreatorIntel < Zelf::Model; end
|
|
102
|
+
class AdvancedCreatorIntelMeta < Zelf::Model; end
|
|
103
|
+
class AdvancedCreatorIntelTotals < Zelf::Model; end
|
|
104
|
+
class AdvancedCreatorProfile < Zelf::Model; end
|
|
105
|
+
class AdvancedLanguage < Zelf::Model; end
|
|
106
|
+
class AdvancedLoveDislike < Zelf::Model; end
|
|
107
|
+
class AdvancedLoveDislikeBucket < Zelf::Model; end
|
|
108
|
+
class AdvancedNarrative < Zelf::Model; end
|
|
109
|
+
class AdvancedPerception < Zelf::Model; end
|
|
110
|
+
class AdvancedPerceptionAxis < Zelf::Model; end
|
|
111
|
+
class AdvancedPerceptionBucket < Zelf::Model; end
|
|
112
|
+
class AdvancedPerceptionSide < Zelf::Model; end
|
|
113
|
+
class AdvancedPersona < Zelf::Model; end
|
|
114
|
+
class AdvancedPersonaRepresentative < Zelf::Model; end
|
|
115
|
+
class AdvancedPersonas < Zelf::Model; end
|
|
116
|
+
class AdvancedPostureMapEntry < Zelf::Model; end
|
|
117
|
+
class AdvancedSentimentByTheme < Zelf::Model; end
|
|
118
|
+
class AdvancedSignals < Zelf::Model; end
|
|
119
|
+
class AdvancedSpeakerDemographics < Zelf::Model; end
|
|
120
|
+
class AdvancedSummary < Zelf::Model; end
|
|
121
|
+
class AdvancedThemeCount < Zelf::Model; end
|
|
122
|
+
class AdvancedThemeDivergence < Zelf::Model; end
|
|
123
|
+
class AdvancedTimelinePoint < Zelf::Model; end
|
|
124
|
+
class AdvancedTopComment < Zelf::Model; end
|
|
125
|
+
class AdvancedTopCreator < Zelf::Model; end
|
|
126
|
+
class AdvancedVoiceBrand < Zelf::Model; end
|
|
127
|
+
class AdvancedVoiceSentiment < Zelf::Model; end
|
|
128
|
+
class AdvancedVoiceTheme < Zelf::Model; end
|
|
129
|
+
class AdvancedVoiceTimeline < Zelf::Model; end
|
|
130
|
+
class AdvancedVoiceTotals < Zelf::Model; end
|
|
93
131
|
class AiAnalysis < Zelf::Model; end
|
|
94
132
|
class AiAnalysisCreateRequest < Zelf::Model; end
|
|
133
|
+
class AiAnalysisReport < Zelf::Model; end
|
|
95
134
|
class AiAnalysisResult < Zelf::Model; end
|
|
96
135
|
class AiAnalysisRun < Zelf::Model; end
|
|
97
136
|
class AnalyticsBrand < Zelf::Model; end
|
|
@@ -123,6 +162,7 @@ module Zelf
|
|
|
123
162
|
class CreatorSync < Zelf::Model; end
|
|
124
163
|
class CreatorSyncCreateRequest < Zelf::Model; end
|
|
125
164
|
class CreatorVetting < Zelf::Model; end
|
|
165
|
+
class CreatorVettingReport < Zelf::Model; end
|
|
126
166
|
class CreatorVettingRequest < Zelf::Model; end
|
|
127
167
|
class CreatorVettingResult < Zelf::Model; end
|
|
128
168
|
class CreatorVettingRun < Zelf::Model; end
|
|
@@ -143,6 +183,7 @@ module Zelf
|
|
|
143
183
|
class FollowerAccount < Zelf::Model; end
|
|
144
184
|
class FollowerPeriod < Zelf::Model; end
|
|
145
185
|
class FollowerTimeseries < Zelf::Model; end
|
|
186
|
+
class LabelCount < Zelf::Model; end
|
|
146
187
|
class PatchedBrandUpdateRequest < Zelf::Model; end
|
|
147
188
|
class PatchedWebhookSubscriptionUpdateRequest < Zelf::Model; end
|
|
148
189
|
class ResultFile < Zelf::Model; end
|
|
@@ -152,6 +193,10 @@ module Zelf
|
|
|
152
193
|
class UsageHistory < Zelf::Model; end
|
|
153
194
|
class UsageScope < Zelf::Model; end
|
|
154
195
|
class UsageWindow < Zelf::Model; end
|
|
196
|
+
class VettingDisclosure < Zelf::Model; end
|
|
197
|
+
class VettingSummary < Zelf::Model; end
|
|
198
|
+
class VettingTopThemes < Zelf::Model; end
|
|
199
|
+
class VettingViolation < Zelf::Model; end
|
|
155
200
|
class WebhookAvailableEvent < Zelf::Model; end
|
|
156
201
|
class WebhookData < Zelf::Model; end
|
|
157
202
|
class WebhookDeleteAcknowledgement < Zelf::Model; end
|
|
@@ -165,6 +210,638 @@ module Zelf
|
|
|
165
210
|
class WebhookSubscriptionCreateRequest < Zelf::Model; end
|
|
166
211
|
class WebhookSubscriptionCreated < Zelf::Model; end
|
|
167
212
|
|
|
213
|
+
# Response body for the advanced AI analysis root.
|
|
214
|
+
class AdvancedAiAnalysis
|
|
215
|
+
# ID of the analysis
|
|
216
|
+
field :id, "id"
|
|
217
|
+
# Always ADVANCED_AI_ANALYSIS here
|
|
218
|
+
field :analysis_type, "analysis_type"
|
|
219
|
+
# The analysis label
|
|
220
|
+
field :name, "name"
|
|
221
|
+
# The subject the analysis focuses on
|
|
222
|
+
field :topic, "topic"
|
|
223
|
+
# When the analysis was created (UTC, ISO-8601)
|
|
224
|
+
field :created_at, "created_at", cast: :time
|
|
225
|
+
# When the analysis was last modified (UTC, ISO-8601)
|
|
226
|
+
field :modified_at, "modified_at", cast: :time
|
|
227
|
+
# The runs that make up this analysis, ordered newest first
|
|
228
|
+
field :analyses, "analyses", cast: [AdvancedAiAnalysisRun]
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Request body for ``POST /api/v1/advanced_ai_analysis/``.
|
|
232
|
+
class AdvancedAiAnalysisCreateRequest
|
|
233
|
+
# A label for this analysis
|
|
234
|
+
field :name, "name"
|
|
235
|
+
# The brand, product, person or event to analyze, as a short term
|
|
236
|
+
field :topic, "topic"
|
|
237
|
+
# Selects which content the analysis runs over
|
|
238
|
+
field :content_filters, "content_filters", cast: ContentFilterInputRequest
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# The JSON document behind an advanced AI analysis run's `result.download_url`. Counts
|
|
242
|
+
# are whole numbers, shares and rates are decimals from 0 to 1, money is in whole
|
|
243
|
+
# cents, and a value is `null` when there was not enough data to work it out. A
|
|
244
|
+
# section is absent when the run could not produce it, so read every one as optional,
|
|
245
|
+
# and ignore keys you do not recognise.
|
|
246
|
+
class AdvancedAiAnalysisReport
|
|
247
|
+
# Totals over the analyzed set, and how much of it was analyzed
|
|
248
|
+
field :summary, "summary", cast: AdvancedSummary
|
|
249
|
+
# Videos by sentiment: positive, neutral, negative, mixed
|
|
250
|
+
field :sentiment, "sentiment", cast: [LabelCount]
|
|
251
|
+
# Videos by what the creator does with the topic: promoting, cautioning, neutral,...
|
|
252
|
+
field :stance, "stance", cast: [LabelCount]
|
|
253
|
+
# Videos by theme
|
|
254
|
+
field :themes, "themes", cast: [AdvancedThemeCount]
|
|
255
|
+
# How sentiment splits inside each theme
|
|
256
|
+
field :sentiment_by_theme, "sentiment_by_theme", cast: [AdvancedSentimentByTheme]
|
|
257
|
+
# Posts, views and engagements month by month
|
|
258
|
+
field :timeline, "timeline", cast: [AdvancedTimelinePoint]
|
|
259
|
+
# Videos by language
|
|
260
|
+
field :languages, "languages", cast: [AdvancedLanguage]
|
|
261
|
+
# Videos by format, with per-format averages
|
|
262
|
+
field :content_forms, "content_forms", cast: [AdvancedContentForm]
|
|
263
|
+
# The creators who brought the most reach
|
|
264
|
+
field :top_creators, "top_creators", cast: [AdvancedTopCreator]
|
|
265
|
+
# Inferred traits of the people on screen
|
|
266
|
+
field :speaker_demographics, "speaker_demographics", cast: AdvancedSpeakerDemographics
|
|
267
|
+
# Product context: stack, rivals, pain points, buying stage
|
|
268
|
+
field :signals, "signals", cast: AdvancedSignals
|
|
269
|
+
# What the audience loves and dislikes, bucket by bucket
|
|
270
|
+
field :love_dislike, "love_dislike", cast: AdvancedLoveDislike
|
|
271
|
+
# Price and quality perception, from the audience and the creators
|
|
272
|
+
field :perception, "perception", cast: AdvancedPerception
|
|
273
|
+
# What the comments say
|
|
274
|
+
field :audience_voice, "audience_voice", cast: AdvancedAudienceVoice
|
|
275
|
+
# Audience archetypes
|
|
276
|
+
field :personas, "personas", cast: AdvancedPersonas
|
|
277
|
+
# Advocates, detractors, prospects and narratives
|
|
278
|
+
field :creator_intel, "creator_intel", cast: AdvancedCreatorIntel
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# A single advanced run with its downloadable ``result``.
|
|
282
|
+
class AdvancedAiAnalysisResult
|
|
283
|
+
# ID of the analysis run
|
|
284
|
+
field :id, "id"
|
|
285
|
+
# ID of the analysis this run belongs to
|
|
286
|
+
field :analysis_id, "analysis_id"
|
|
287
|
+
# Run status: one of IN_PROGRESS, COMPLETED, EMPTY_RESULT (finished with no...
|
|
288
|
+
field :status, "status"
|
|
289
|
+
# Signed, time-limited download of the run's analysis payload: download_url...
|
|
290
|
+
field :result, "result", cast: ResultFile
|
|
291
|
+
# Signed link to the run's interactive dashboard
|
|
292
|
+
field :dashboard_url, "dashboard_url"
|
|
293
|
+
# When the run was created (UTC, ISO-8601)
|
|
294
|
+
field :created_at, "created_at", cast: :time
|
|
295
|
+
# When the run was last modified (UTC, ISO-8601)
|
|
296
|
+
field :modified_at, "modified_at", cast: :time
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# A single advanced run, without its result payload. The run ``result`` is not
|
|
300
|
+
# included; retrieve it from `advanced_ai_analysis.results` once ``status`` is
|
|
301
|
+
# `COMPLETED`.
|
|
302
|
+
class AdvancedAiAnalysisRun
|
|
303
|
+
# ID of the analysis run
|
|
304
|
+
field :id, "id"
|
|
305
|
+
# Run status: one of IN_PROGRESS, COMPLETED, EMPTY_RESULT (finished with no...
|
|
306
|
+
field :status, "status"
|
|
307
|
+
# Signed link to the run's interactive dashboard, for showing a person the analysis
|
|
308
|
+
field :dashboard_url, "dashboard_url"
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# What the comments say, as a whole.
|
|
312
|
+
class AdvancedAudienceVoice
|
|
313
|
+
# False when no comments were available; the lists are then empty
|
|
314
|
+
field :has_comments, "has_comments"
|
|
315
|
+
# Totals over the comments read
|
|
316
|
+
field :totals, "totals", cast: AdvancedVoiceTotals
|
|
317
|
+
# Comments by sentiment
|
|
318
|
+
field :sentiment, "sentiment", cast: [AdvancedVoiceSentiment]
|
|
319
|
+
# Comments by what the commenter wants
|
|
320
|
+
field :intent, "intent", cast: [LabelCount]
|
|
321
|
+
# Comments by theme
|
|
322
|
+
field :themes, "themes", cast: [AdvancedVoiceTheme]
|
|
323
|
+
# Comments month by month
|
|
324
|
+
field :timeline, "timeline", cast: [AdvancedVoiceTimeline]
|
|
325
|
+
# The comments worth reading
|
|
326
|
+
field :top_comments, "top_comments", cast: [AdvancedTopComment]
|
|
327
|
+
# Themes where creators and their audience part ways
|
|
328
|
+
field :theme_divergence, "theme_divergence", cast: [AdvancedThemeDivergence]
|
|
329
|
+
# Brands the commenters bring up
|
|
330
|
+
field :brands, "brands", cast: [AdvancedVoiceBrand]
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# One video format and how it performs.
|
|
334
|
+
class AdvancedContentForm
|
|
335
|
+
# The format, for example short
|
|
336
|
+
field :form, "form"
|
|
337
|
+
# Videos in this format
|
|
338
|
+
field :count, "count"
|
|
339
|
+
# Mean views per video
|
|
340
|
+
field :avg_views, "avg_views"
|
|
341
|
+
# Mean engagements per video
|
|
342
|
+
field :avg_engagements, "avg_engagements"
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# How many of the analyzed videos carry each kind of analysis.
|
|
346
|
+
class AdvancedCoverage
|
|
347
|
+
# Videos in the analysis
|
|
348
|
+
field :total, "total"
|
|
349
|
+
# Videos that were analyzed at all
|
|
350
|
+
field :enriched, "enriched"
|
|
351
|
+
# Videos with a sentiment
|
|
352
|
+
field :has_sentiment, "has_sentiment"
|
|
353
|
+
# Videos with themes
|
|
354
|
+
field :has_themes, "has_themes"
|
|
355
|
+
# Videos classified into a love or dislike bucket
|
|
356
|
+
field :has_love_dislike, "has_love_dislike"
|
|
357
|
+
# Videos with inferred on-screen demographics
|
|
358
|
+
field :has_speaker_demographics, "has_speaker_demographics"
|
|
359
|
+
# Videos with product context signals
|
|
360
|
+
field :has_human_signals, "has_human_signals"
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# Creators sorted by posture, and the stories they carry.
|
|
364
|
+
class AdvancedCreatorIntel
|
|
365
|
+
# How the creators split across postures
|
|
366
|
+
field :totals, "totals", cast: AdvancedCreatorIntelTotals
|
|
367
|
+
# Creators who back the topic
|
|
368
|
+
field :advocates, "advocates", cast: [AdvancedCreatorProfile]
|
|
369
|
+
# Creators who criticise it
|
|
370
|
+
field :detractors, "detractors", cast: [AdvancedCreatorProfile]
|
|
371
|
+
# Creators worth approaching
|
|
372
|
+
field :prospects, "prospects", cast: [AdvancedCreatorProfile]
|
|
373
|
+
# Every creator plotted by reach against stance
|
|
374
|
+
field :posture_map, "posture_map", cast: [AdvancedPostureMapEntry]
|
|
375
|
+
# The stories moving through the conversation
|
|
376
|
+
field :narratives, "narratives", cast: [AdvancedNarrative]
|
|
377
|
+
# How and when this section was built
|
|
378
|
+
field :meta, "meta", cast: AdvancedCreatorIntelMeta
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
# How and when this section was built.
|
|
382
|
+
class AdvancedCreatorIntelMeta
|
|
383
|
+
# When the section was built (UTC, ISO-8601)
|
|
384
|
+
field :generated_at, "generated_at"
|
|
385
|
+
# The model that built it
|
|
386
|
+
field :model, "model"
|
|
387
|
+
# Creators analyzed
|
|
388
|
+
field :enriched_count, "enriched_count"
|
|
389
|
+
# True when the section predates the analysis' latest content
|
|
390
|
+
field :stale, "stale"
|
|
391
|
+
# The content snapshot it was built from
|
|
392
|
+
field :derived_from, "derived_from"
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# How the creators split across postures.
|
|
396
|
+
class AdvancedCreatorIntelTotals
|
|
397
|
+
# Creators in the analysis
|
|
398
|
+
field :creators, "creators"
|
|
399
|
+
# Creators who back the topic
|
|
400
|
+
field :advocates, "advocates"
|
|
401
|
+
# Creators who criticise it
|
|
402
|
+
field :detractors, "detractors"
|
|
403
|
+
# Creators worth approaching
|
|
404
|
+
field :prospects, "prospects"
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# A creator, scored on how they treat the topic.
|
|
408
|
+
class AdvancedCreatorProfile
|
|
409
|
+
# The creator's handle
|
|
410
|
+
field :handle, "handle"
|
|
411
|
+
# Videos they posted
|
|
412
|
+
field :posts, "posts"
|
|
413
|
+
# Views across those videos
|
|
414
|
+
field :views, "views"
|
|
415
|
+
# Engagements across them
|
|
416
|
+
field :engagements, "engagements"
|
|
417
|
+
# Earned media value, in cents
|
|
418
|
+
field :emv_cents, "emv_cents"
|
|
419
|
+
# Average sentiment of their videos, -1 to 1
|
|
420
|
+
field :avg_sentiment, "avg_sentiment"
|
|
421
|
+
# How many of their videos take each stance
|
|
422
|
+
field :stance_counts, "stance_counts"
|
|
423
|
+
# What they post about most
|
|
424
|
+
field :top_themes, "top_themes", cast: [AdvancedThemeCount]
|
|
425
|
+
# Share of their posts carrying no sponsorship marker, from 0 to 1
|
|
426
|
+
field :organic_share, "organic_share"
|
|
427
|
+
# Their earliest post, as YYYY-MM-DD
|
|
428
|
+
field :first_post, "first_post"
|
|
429
|
+
# Their latest post, as YYYY-MM-DD
|
|
430
|
+
field :last_post, "last_post"
|
|
431
|
+
# Where their views rank among this analysis' creators, 0 to 1
|
|
432
|
+
field :reach_percentile, "reach_percentile"
|
|
433
|
+
# Which way they lean, -1 critical to 1 promoting
|
|
434
|
+
field :stance_lean, "stance_lean"
|
|
435
|
+
# advocate, detractor, prospect or longtail
|
|
436
|
+
field :posture, "posture"
|
|
437
|
+
# How good a partner they would be, 0 to 100
|
|
438
|
+
field :partnership_fit, "partnership_fit"
|
|
439
|
+
# How much risk their criticism carries, 0 to 100
|
|
440
|
+
field :detractor_severity, "detractor_severity"
|
|
441
|
+
# How strongly commenters respond to them, 0 to 100
|
|
442
|
+
field :consumer_resonance, "consumer_resonance"
|
|
443
|
+
# Model summary of the creator
|
|
444
|
+
field :read, "read"
|
|
445
|
+
# The creator's declared platform profile
|
|
446
|
+
field :profile, "profile"
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# One language and its share of the set.
|
|
450
|
+
class AdvancedLanguage
|
|
451
|
+
# Language code, for example en
|
|
452
|
+
field :language, "language"
|
|
453
|
+
# Videos in this language
|
|
454
|
+
field :count, "count"
|
|
455
|
+
# Engagements on those videos
|
|
456
|
+
field :engagements, "engagements"
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# What the audience loves and dislikes about the topic.
|
|
460
|
+
class AdvancedLoveDislike
|
|
461
|
+
# Videos that fell into a love or dislike bucket
|
|
462
|
+
field :classified_count, "classified_count"
|
|
463
|
+
# Videos considered
|
|
464
|
+
field :total_count, "total_count"
|
|
465
|
+
# What people praise, strongest first
|
|
466
|
+
field :love, "love", cast: [AdvancedLoveDislikeBucket]
|
|
467
|
+
# What people criticise, strongest first
|
|
468
|
+
field :dislike, "dislike", cast: [AdvancedLoveDislikeBucket]
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# One thing people love or dislike, and what backs it.
|
|
472
|
+
class AdvancedLoveDislikeBucket
|
|
473
|
+
# Stable key for the bucket
|
|
474
|
+
field :slug, "slug"
|
|
475
|
+
# Display name for the bucket
|
|
476
|
+
field :label, "label"
|
|
477
|
+
# What the bucket covers
|
|
478
|
+
field :definition, "definition"
|
|
479
|
+
# Videos in the bucket
|
|
480
|
+
field :video_count, "video_count"
|
|
481
|
+
# Earned media value of those videos, in cents
|
|
482
|
+
field :emv_cents, "emv_cents"
|
|
483
|
+
# Views on those videos
|
|
484
|
+
field :total_views, "total_views"
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# A story moving through the conversation.
|
|
488
|
+
class AdvancedNarrative
|
|
489
|
+
# The theme the story is about
|
|
490
|
+
field :theme, "theme"
|
|
491
|
+
# Videos carrying it
|
|
492
|
+
field :total, "total"
|
|
493
|
+
# Share of those videos that are positive, 0 to 1
|
|
494
|
+
field :positive_share, "positive_share"
|
|
495
|
+
# Share of those videos that are negative, 0 to 1
|
|
496
|
+
field :negative_share, "negative_share"
|
|
497
|
+
# Whether the theme is gaining or losing share, -1 to 1
|
|
498
|
+
field :momentum, "momentum"
|
|
499
|
+
# rising or falling
|
|
500
|
+
field :direction, "direction"
|
|
501
|
+
# The creators posting most on the theme
|
|
502
|
+
field :carriers, "carriers"
|
|
503
|
+
# A suggested response
|
|
504
|
+
field :play, "play"
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
# Price and quality perception, measured from both sides.
|
|
508
|
+
class AdvancedPerception
|
|
509
|
+
# What commenters say
|
|
510
|
+
field :audience, "audience", cast: AdvancedPerceptionSide
|
|
511
|
+
# How the videos frame it
|
|
512
|
+
field :creator, "creator", cast: AdvancedPerceptionSide
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# One perception axis, price or quality, measured one way.
|
|
516
|
+
class AdvancedPerceptionAxis
|
|
517
|
+
# Share of analyzed items that express any view on this axis, from 0 to 1
|
|
518
|
+
field :share_indicating, "share_indicating"
|
|
519
|
+
# Items that express a view on this axis
|
|
520
|
+
field :classified_count, "classified_count"
|
|
521
|
+
# Items analyzed for this axis, those with no view included
|
|
522
|
+
field :enriched_count, "enriched_count"
|
|
523
|
+
# The bands on this axis, largest share first
|
|
524
|
+
field :buckets, "buckets", cast: [AdvancedPerceptionBucket]
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# One perception band and its share.
|
|
528
|
+
class AdvancedPerceptionBucket
|
|
529
|
+
# The band
|
|
530
|
+
field :key, "key"
|
|
531
|
+
# Display name for the band
|
|
532
|
+
field :label, "label"
|
|
533
|
+
# This band's share of the classified items, from 0 to 1
|
|
534
|
+
field :pct, "pct"
|
|
535
|
+
# Videos the band covers
|
|
536
|
+
field :video_count, "video_count"
|
|
537
|
+
# Earned media value of those videos, in cents
|
|
538
|
+
field :emv_cents, "emv_cents"
|
|
539
|
+
# Views on those videos
|
|
540
|
+
field :total_views, "total_views"
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
# Price and quality as seen from one side.
|
|
544
|
+
class AdvancedPerceptionSide
|
|
545
|
+
# How price is read
|
|
546
|
+
field :price, "price", cast: AdvancedPerceptionAxis
|
|
547
|
+
# How quality is read
|
|
548
|
+
field :quality, "quality", cast: AdvancedPerceptionAxis
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
# An audience archetype found across the analyzed videos.
|
|
552
|
+
class AdvancedPersona
|
|
553
|
+
# Stable key for the persona
|
|
554
|
+
field :id, "id"
|
|
555
|
+
# Short label for the persona
|
|
556
|
+
field :name, "name"
|
|
557
|
+
# One line describing them
|
|
558
|
+
field :tagline, "tagline"
|
|
559
|
+
# Who this person is
|
|
560
|
+
field :description, "description"
|
|
561
|
+
# Videos that match the archetype
|
|
562
|
+
field :member_count, "member_count"
|
|
563
|
+
# Average sentiment of those videos, -1 to 1
|
|
564
|
+
field :avg_sentiment, "avg_sentiment"
|
|
565
|
+
# Views across those videos
|
|
566
|
+
field :total_views, "total_views"
|
|
567
|
+
# How closely the best-matching video fits, from 0 to 1
|
|
568
|
+
field :top_similarity, "top_similarity"
|
|
569
|
+
# The videos that stand for the persona
|
|
570
|
+
field :representatives, "representatives", cast: [AdvancedPersonaRepresentative]
|
|
571
|
+
# A deeper profile of the persona
|
|
572
|
+
field :breakdown, "breakdown"
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
# A video that stands for a persona.
|
|
576
|
+
class AdvancedPersonaRepresentative
|
|
577
|
+
# The video's id
|
|
578
|
+
field :record_id, "record_id"
|
|
579
|
+
# The creator's handle
|
|
580
|
+
field :handle, "handle"
|
|
581
|
+
# The video's caption
|
|
582
|
+
field :caption, "caption"
|
|
583
|
+
# One line summarising the video
|
|
584
|
+
field :gist, "gist"
|
|
585
|
+
# Views on the video
|
|
586
|
+
field :views, "views"
|
|
587
|
+
# Likes on the video
|
|
588
|
+
field :likes, "likes"
|
|
589
|
+
# Engagements on the video
|
|
590
|
+
field :engagements, "engagements"
|
|
591
|
+
# Earned media value, in cents
|
|
592
|
+
field :emv_cents, "emv_cents"
|
|
593
|
+
# The video's sentiment band
|
|
594
|
+
field :sentiment, "sentiment"
|
|
595
|
+
# The video's sentiment, -1 to 1
|
|
596
|
+
field :sentiment_score, "sentiment_score"
|
|
597
|
+
# The creator's stance in the video
|
|
598
|
+
field :stance, "stance"
|
|
599
|
+
# Themes the video covers
|
|
600
|
+
field :themes, "themes"
|
|
601
|
+
# The video's language code
|
|
602
|
+
field :language, "language"
|
|
603
|
+
# The video's format
|
|
604
|
+
field :content_form, "content_form"
|
|
605
|
+
# How long the video runs, in seconds
|
|
606
|
+
field :duration_s, "duration_s"
|
|
607
|
+
# When it was posted (UTC, ISO-8601)
|
|
608
|
+
field :posted_at, "posted_at"
|
|
609
|
+
# Link to the video's thumbnail
|
|
610
|
+
field :thumbnail_url, "thumbnail_url"
|
|
611
|
+
# Link to the video
|
|
612
|
+
field :video_url, "video_url"
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
# The audience archetypes, and how they were derived.
|
|
616
|
+
class AdvancedPersonas
|
|
617
|
+
# derived when the archetypes came from this analysis' own vocabulary, fallback...
|
|
618
|
+
field :vocab_source, "vocab_source"
|
|
619
|
+
# The archetypes found
|
|
620
|
+
field :personas, "personas", cast: [AdvancedPersona]
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
# One creator plotted by reach against stance.
|
|
624
|
+
class AdvancedPostureMapEntry
|
|
625
|
+
# The creator's handle
|
|
626
|
+
field :handle, "handle"
|
|
627
|
+
# Where their views rank, 0 to 1
|
|
628
|
+
field :reach_percentile, "reach_percentile"
|
|
629
|
+
# Which way they lean, -1 to 1
|
|
630
|
+
field :stance_lean, "stance_lean"
|
|
631
|
+
# Videos they posted
|
|
632
|
+
field :posts, "posts"
|
|
633
|
+
# Their posture towards the topic
|
|
634
|
+
field :posture, "posture"
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
# How sentiment splits inside one theme.
|
|
638
|
+
class AdvancedSentimentByTheme
|
|
639
|
+
# The theme
|
|
640
|
+
field :theme, "theme"
|
|
641
|
+
# Positive videos on the theme
|
|
642
|
+
field :positive, "positive"
|
|
643
|
+
# Neutral videos on the theme
|
|
644
|
+
field :neutral, "neutral"
|
|
645
|
+
# Negative videos on the theme
|
|
646
|
+
field :negative, "negative"
|
|
647
|
+
# Mixed videos on the theme
|
|
648
|
+
field :mixed, "mixed"
|
|
649
|
+
# Videos on the theme
|
|
650
|
+
field :total, "total"
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
# Product context drawn from what people show and say.
|
|
654
|
+
class AdvancedSignals
|
|
655
|
+
# Products shown or used alongside the subject
|
|
656
|
+
field :stack, "stack", cast: [LabelCount]
|
|
657
|
+
# Rival products that appear
|
|
658
|
+
field :competitors, "competitors", cast: [LabelCount]
|
|
659
|
+
# Problems people keep raising
|
|
660
|
+
field :pain_points, "pain_points", cast: [LabelCount]
|
|
661
|
+
# Where the speaker is in their buying journey
|
|
662
|
+
field :journey_stage, "journey_stage", cast: [LabelCount]
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
# Inferred traits of the people on screen. These are model inferences, not verified
|
|
666
|
+
# facts. Use them for trends across the set, never as a statement about any one
|
|
667
|
+
# person.
|
|
668
|
+
class AdvancedSpeakerDemographics
|
|
669
|
+
# Videos by inferred gender
|
|
670
|
+
field :gender, "gender", cast: [LabelCount]
|
|
671
|
+
# Videos by inferred age band
|
|
672
|
+
field :age, "age", cast: [LabelCount]
|
|
673
|
+
# Videos by inferred ethnicity
|
|
674
|
+
field :ethnicity, "ethnicity", cast: [LabelCount]
|
|
675
|
+
# Videos by the setting they were filmed in
|
|
676
|
+
field :setting, "setting", cast: [LabelCount]
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# Totals over the whole analyzed set.
|
|
680
|
+
class AdvancedSummary
|
|
681
|
+
# Videos analyzed
|
|
682
|
+
field :videos, "videos"
|
|
683
|
+
# Distinct creators behind them
|
|
684
|
+
field :creators, "creators"
|
|
685
|
+
# Views summed over the set
|
|
686
|
+
field :total_views, "total_views"
|
|
687
|
+
# Likes summed over the set
|
|
688
|
+
field :total_likes, "total_likes"
|
|
689
|
+
# Comments summed over the set
|
|
690
|
+
field :total_comments, "total_comments"
|
|
691
|
+
# Shares summed over the set
|
|
692
|
+
field :total_shares, "total_shares"
|
|
693
|
+
# Likes, comments and shares summed over the set
|
|
694
|
+
field :total_engagements, "total_engagements"
|
|
695
|
+
# Average of each video's engagements divided by its views, from 0 to 1
|
|
696
|
+
field :mean_engagement_rate, "mean_engagement_rate"
|
|
697
|
+
# Earned media value in cents
|
|
698
|
+
field :total_emv_cents, "total_emv_cents"
|
|
699
|
+
# Date of the earliest video, as YYYY-MM-DD
|
|
700
|
+
field :first_post, "first_post"
|
|
701
|
+
# Date of the latest video, as YYYY-MM-DD
|
|
702
|
+
field :last_post, "last_post"
|
|
703
|
+
# How many videos carry each kind of analysis
|
|
704
|
+
field :coverage, "coverage", cast: AdvancedCoverage
|
|
705
|
+
end
|
|
706
|
+
|
|
707
|
+
# A theme and how many videos carry it.
|
|
708
|
+
class AdvancedThemeCount
|
|
709
|
+
# The theme, from this analysis' own set
|
|
710
|
+
field :theme, "theme"
|
|
711
|
+
# Videos carrying it
|
|
712
|
+
field :count, "count"
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
# A theme where creators and their audience disagree.
|
|
716
|
+
class AdvancedThemeDivergence
|
|
717
|
+
# The theme
|
|
718
|
+
field :theme, "theme"
|
|
719
|
+
# Videos on the theme
|
|
720
|
+
field :videos, "videos"
|
|
721
|
+
# Comments on the theme
|
|
722
|
+
field :comments, "comments"
|
|
723
|
+
# How the creators lean, -1 to 1
|
|
724
|
+
field :creator_score, "creator_score"
|
|
725
|
+
# How the audience leans, -1 to 1
|
|
726
|
+
field :audience_score, "audience_score"
|
|
727
|
+
# audience_score minus creator_score
|
|
728
|
+
field :gap, "gap"
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
# One month of posting activity.
|
|
732
|
+
class AdvancedTimelinePoint
|
|
733
|
+
# The month, as YYYY-MM
|
|
734
|
+
field :month, "month"
|
|
735
|
+
# Videos posted that month
|
|
736
|
+
field :posts, "posts"
|
|
737
|
+
# Views on those videos
|
|
738
|
+
field :views, "views"
|
|
739
|
+
# Engagements on those videos
|
|
740
|
+
field :engagements, "engagements"
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
# A comment worth reading, with the video it sits under.
|
|
744
|
+
class AdvancedTopComment
|
|
745
|
+
# The comment's id
|
|
746
|
+
field :comment_id, "comment_id"
|
|
747
|
+
# What the comment says
|
|
748
|
+
field :text, "text"
|
|
749
|
+
# Likes on the comment
|
|
750
|
+
field :likes, "likes"
|
|
751
|
+
# When it was posted (UTC, ISO-8601)
|
|
752
|
+
field :posted_at, "posted_at"
|
|
753
|
+
# Its sentiment band
|
|
754
|
+
field :sentiment, "sentiment"
|
|
755
|
+
# What the commenter is doing, for example question
|
|
756
|
+
field :intent, "intent"
|
|
757
|
+
# One line summarising the comment
|
|
758
|
+
field :gist, "gist"
|
|
759
|
+
# The video it sits under
|
|
760
|
+
field :video_record_id, "video_record_id"
|
|
761
|
+
# That video's creator handle
|
|
762
|
+
field :video_handle, "video_handle"
|
|
763
|
+
# That video's caption
|
|
764
|
+
field :video_caption, "video_caption"
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
# A creator ranked by the reach they brought.
|
|
768
|
+
class AdvancedTopCreator
|
|
769
|
+
# The creator's handle
|
|
770
|
+
field :handle, "handle"
|
|
771
|
+
# Videos they posted
|
|
772
|
+
field :posts, "posts"
|
|
773
|
+
# Views across those videos
|
|
774
|
+
field :views, "views"
|
|
775
|
+
# Engagements across them
|
|
776
|
+
field :engagements, "engagements"
|
|
777
|
+
# Earned media value in cents
|
|
778
|
+
field :emv_cents, "emv_cents"
|
|
779
|
+
end
|
|
780
|
+
|
|
781
|
+
# A brand the commenters bring up.
|
|
782
|
+
class AdvancedVoiceBrand
|
|
783
|
+
# The brand named
|
|
784
|
+
field :brand, "brand"
|
|
785
|
+
# Comments naming it
|
|
786
|
+
field :count, "count"
|
|
787
|
+
# Average sentiment of those comments, -1 to 1
|
|
788
|
+
field :avg_score, "avg_score"
|
|
789
|
+
# Likes on those comments
|
|
790
|
+
field :total_likes, "total_likes"
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
# Comments in one sentiment band.
|
|
794
|
+
class AdvancedVoiceSentiment
|
|
795
|
+
# The band: positive, neutral, negative or mixed
|
|
796
|
+
field :label, "label"
|
|
797
|
+
# Comments in the band
|
|
798
|
+
field :count, "count"
|
|
799
|
+
# Likes on those comments
|
|
800
|
+
field :likes, "likes"
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
# How the comments on one theme break down.
|
|
804
|
+
class AdvancedVoiceTheme
|
|
805
|
+
# The theme
|
|
806
|
+
field :theme, "theme"
|
|
807
|
+
# Comments on the theme
|
|
808
|
+
field :count, "count"
|
|
809
|
+
# Positive comments on it
|
|
810
|
+
field :positive, "positive"
|
|
811
|
+
# Negative comments on it
|
|
812
|
+
field :negative, "negative"
|
|
813
|
+
# Like-weighted sentiment on the theme, -1 to 1
|
|
814
|
+
field :like_weighted_score, "like_weighted_score"
|
|
815
|
+
end
|
|
816
|
+
|
|
817
|
+
# One month of comment activity.
|
|
818
|
+
class AdvancedVoiceTimeline
|
|
819
|
+
# The month, as YYYY-MM
|
|
820
|
+
field :month, "month"
|
|
821
|
+
# Comments that month
|
|
822
|
+
field :count, "count"
|
|
823
|
+
# Positive comments minus negative comments
|
|
824
|
+
field :net_sentiment, "net_sentiment"
|
|
825
|
+
# Like-weighted sentiment that month, -1 to 1
|
|
826
|
+
field :like_weighted_score, "like_weighted_score"
|
|
827
|
+
end
|
|
828
|
+
|
|
829
|
+
# Totals over the comments that were read.
|
|
830
|
+
class AdvancedVoiceTotals
|
|
831
|
+
# Videos considered
|
|
832
|
+
field :videos, "videos"
|
|
833
|
+
# Comments read
|
|
834
|
+
field :comments, "comments"
|
|
835
|
+
# Comments that were analyzed
|
|
836
|
+
field :enriched, "enriched"
|
|
837
|
+
# Likes on those comments
|
|
838
|
+
field :total_likes, "total_likes"
|
|
839
|
+
# Videos that had at least one comment
|
|
840
|
+
field :videos_with_comments, "videos_with_comments"
|
|
841
|
+
# Average comment sentiment weighted towards comments with more likes, from -1 to 1
|
|
842
|
+
field :like_weighted_sentiment, "like_weighted_sentiment"
|
|
843
|
+
end
|
|
844
|
+
|
|
168
845
|
# Response body for the AI analysis root.
|
|
169
846
|
class AiAnalysis
|
|
170
847
|
# ID of the analysis
|
|
@@ -195,6 +872,18 @@ module Zelf
|
|
|
195
872
|
field :content_filters, "content_filters", cast: ContentFilterInputRequest
|
|
196
873
|
end
|
|
197
874
|
|
|
875
|
+
# The JSON document behind an AI analysis run's `result.download_url`. Every section
|
|
876
|
+
# under `general_insights` is optional: a section the run could not produce is left
|
|
877
|
+
# out rather than returned empty. Which sections appear depends on the run's scope,
|
|
878
|
+
# `CONTENT` or `COMMENT`. New sections and fields can be added at any time, so ignore
|
|
879
|
+
# keys you do not recognise.
|
|
880
|
+
class AiAnalysisReport
|
|
881
|
+
# The topic the analysis ran on, as it was submitted
|
|
882
|
+
field :brand_name, "brand_name"
|
|
883
|
+
# The sections the run produced
|
|
884
|
+
field :general_insights, "general_insights"
|
|
885
|
+
end
|
|
886
|
+
|
|
198
887
|
# A single analysis run with its downloadable ``result``.
|
|
199
888
|
class AiAnalysisResult
|
|
200
889
|
# ID of the analysis run
|
|
@@ -777,6 +1466,22 @@ module Zelf
|
|
|
777
1466
|
field :content_scope, "content_scope"
|
|
778
1467
|
end
|
|
779
1468
|
|
|
1469
|
+
# The JSON document behind a creator vetting run's `result.download_url`.
|
|
1470
|
+
# `disclosures` is present only when the run asked for the `DISCLOSURE` safety check.
|
|
1471
|
+
# New fields can be added at any time, so ignore keys you do not recognise.
|
|
1472
|
+
class CreatorVettingReport
|
|
1473
|
+
# Two or three sentences describing the creator
|
|
1474
|
+
field :profile_summary, "profile_summary"
|
|
1475
|
+
# The creator's recurring subjects
|
|
1476
|
+
field :top_themes, "top_themes", cast: VettingTopThemes
|
|
1477
|
+
# How much of the catalogue raised a flag
|
|
1478
|
+
field :violation_summary, "violation_summary", cast: VettingSummary
|
|
1479
|
+
# Every flag raised, one row per criterion per content item
|
|
1480
|
+
field :violations, "violations", cast: [VettingViolation]
|
|
1481
|
+
# Paid-partnership signals, one row per signal
|
|
1482
|
+
field :disclosures, "disclosures", cast: [VettingDisclosure]
|
|
1483
|
+
end
|
|
1484
|
+
|
|
780
1485
|
# Request body for ``POST /api/v1/creator/vetting/``.
|
|
781
1486
|
class CreatorVettingRequest
|
|
782
1487
|
# When true, re-indexes the creator even if they already exist in our database
|
|
@@ -994,6 +1699,14 @@ module Zelf
|
|
|
994
1699
|
field :periods, "periods", cast: [FollowerPeriod]
|
|
995
1700
|
end
|
|
996
1701
|
|
|
1702
|
+
# A label and how many videos carry it.
|
|
1703
|
+
class LabelCount
|
|
1704
|
+
# The label
|
|
1705
|
+
field :label, "label"
|
|
1706
|
+
# Videos carrying it
|
|
1707
|
+
field :count, "count"
|
|
1708
|
+
end
|
|
1709
|
+
|
|
997
1710
|
# Partial update for a brand's monitoring keywords. Every field is optional, and only
|
|
998
1711
|
# the supplied fields are changed, but at least one field is required.
|
|
999
1712
|
class PatchedBrandUpdateRequest
|
|
@@ -1117,6 +1830,62 @@ module Zelf
|
|
|
1117
1830
|
field :reset_in, "reset_in"
|
|
1118
1831
|
end
|
|
1119
1832
|
|
|
1833
|
+
# A paid-partnership signal found in one piece of content.
|
|
1834
|
+
class VettingDisclosure
|
|
1835
|
+
# The content the signal is in
|
|
1836
|
+
field :content_id, "content_id"
|
|
1837
|
+
# Link to that content, blank when unknown
|
|
1838
|
+
field :content_url, "content_url"
|
|
1839
|
+
# Where it was found: frame, title, caption or audio
|
|
1840
|
+
field :source, "source"
|
|
1841
|
+
# What kind of signal it is, for example sponsorship
|
|
1842
|
+
field :kind, "kind"
|
|
1843
|
+
# The disclosure wording itself
|
|
1844
|
+
field :text, "text"
|
|
1845
|
+
# Seconds into the video, or null when it is not timed
|
|
1846
|
+
field :time_seconds, "time_seconds"
|
|
1847
|
+
end
|
|
1848
|
+
|
|
1849
|
+
# How much of the creator's catalogue raised a flag.
|
|
1850
|
+
class VettingSummary
|
|
1851
|
+
# Flags raised across every criterion
|
|
1852
|
+
field :total_violations, "total_violations"
|
|
1853
|
+
# Distinct content items carrying at least one flag
|
|
1854
|
+
field :affected_contents, "affected_contents"
|
|
1855
|
+
end
|
|
1856
|
+
|
|
1857
|
+
# The creator's recurring subjects, with what each is based on.
|
|
1858
|
+
class VettingTopThemes
|
|
1859
|
+
# The themes, strongest first
|
|
1860
|
+
field :top_themes, "top_themes"
|
|
1861
|
+
# top_themes: one grounded entry per theme
|
|
1862
|
+
field :grounding, "grounding"
|
|
1863
|
+
end
|
|
1864
|
+
|
|
1865
|
+
# One criterion raised against one piece of the creator's content.
|
|
1866
|
+
class VettingViolation
|
|
1867
|
+
# Stable id for this flag, as {content_id}_{type}
|
|
1868
|
+
field :violation_id, "violation_id"
|
|
1869
|
+
# The criterion
|
|
1870
|
+
field :type, "type"
|
|
1871
|
+
# The criterion's display name
|
|
1872
|
+
field :value, "value"
|
|
1873
|
+
# What the criterion covers
|
|
1874
|
+
field :description, "description"
|
|
1875
|
+
# Why this content was judged to breach the criterion
|
|
1876
|
+
field :reason, "reason"
|
|
1877
|
+
# The passage the judgement rests on, verbatim
|
|
1878
|
+
field :evidence_quote, "evidence_quote"
|
|
1879
|
+
# Where the quote came from: title, ai_summary, transcription, text_overlay,...
|
|
1880
|
+
field :evidence_field, "evidence_field"
|
|
1881
|
+
# The content the flag is against
|
|
1882
|
+
field :content_id, "content_id"
|
|
1883
|
+
# Always yes
|
|
1884
|
+
field :violation, "violation"
|
|
1885
|
+
# How serious the flag is: high, medium, low or N/A
|
|
1886
|
+
field :severity, "severity"
|
|
1887
|
+
end
|
|
1888
|
+
|
|
1120
1889
|
# An event type a subscription may ask for.
|
|
1121
1890
|
class WebhookAvailableEvent
|
|
1122
1891
|
# Event type identifier, e.g
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Generated by codegen. Do not edit by hand.
|
|
2
|
+
module Zelf
|
|
3
|
+
module Resources
|
|
4
|
+
# The advanced_ai_analysis endpoints.
|
|
5
|
+
class AdvancedAiAnalysis
|
|
6
|
+
def initialize(transport)
|
|
7
|
+
@transport = transport
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Get Advanced AI Analysis Content Statistics. Returns aggregate totals (post count,
|
|
11
|
+
# views, engagement, earned media value, and unique creators) over the content an
|
|
12
|
+
# advanced AI analysis ran over. Requires `analysis_id` (an analysis `id` from
|
|
13
|
+
# `advanced_ai_analysis.list`) and returns the same totals shape as
|
|
14
|
+
# `content.statistics`.
|
|
15
|
+
#
|
|
16
|
+
# Calls GET /api/v1/advanced_ai_analysis/contents/statistics/ (advanced_ai_analysis.content_statistics).
|
|
17
|
+
def content_statistics(analysis_id:)
|
|
18
|
+
query = {
|
|
19
|
+
"analysis_id" => analysis_id,
|
|
20
|
+
}.reject { |_, value| value.nil? }
|
|
21
|
+
envelope = @transport.request(:get, "/api/v1/advanced_ai_analysis/contents/statistics/", query: query)
|
|
22
|
+
Zelf.one(envelope, Models::ContentStatistics, "ContentStatistics")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# List Advanced AI Analysis Content. Returns the content an advanced AI analysis ran
|
|
26
|
+
# over, in the standard content shape. Use it to inspect the exact posts included in
|
|
27
|
+
# an analysis. Requires `analysis_id` (an analysis `id` from
|
|
28
|
+
# `advanced_ai_analysis.list`). Brand-scoped fields (`is_owned`, `is_tagged`,
|
|
29
|
+
# `net_promoter_score`, ...) are `null` in this response.
|
|
30
|
+
#
|
|
31
|
+
# Calls GET /api/v1/advanced_ai_analysis/contents/ (advanced_ai_analysis.contents).
|
|
32
|
+
def contents(analysis_id:, page: nil, page_size: nil)
|
|
33
|
+
query = {
|
|
34
|
+
"analysis_id" => analysis_id,
|
|
35
|
+
"page" => page,
|
|
36
|
+
"page_size" => page_size,
|
|
37
|
+
}.reject { |_, value| value.nil? }
|
|
38
|
+
envelope = @transport.request(:get, "/api/v1/advanced_ai_analysis/contents/", query: query)
|
|
39
|
+
path = @transport.resolve_path("/api/v1/advanced_ai_analysis/contents/".dup, {})
|
|
40
|
+
Zelf::Page.new(envelope, Models::Content, @transport, path, query)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Create Advanced AI Analysis. Starts an advanced AI analysis over the content matched
|
|
44
|
+
# by `content_filters` for a given `topic`. The advanced engine goes further than
|
|
45
|
+
# `ai_analysis.create`: alongside sentiment and themes it reports creator stance,
|
|
46
|
+
# price and quality perception from both the audience and the creators, audience voice
|
|
47
|
+
# from the comments, speaker demographics, audience personas and creator intel. Runs
|
|
48
|
+
# complete asynchronously; this method returns immediately with the created analysis
|
|
49
|
+
# and its initial run. The analysis runs over the highest-ranked matching content by
|
|
50
|
+
# `content_filters.order_by`, up to 500 posts or the limit configured for your
|
|
51
|
+
# workspace. When `order_by` is omitted, content is ranked by
|
|
52
|
+
# `earned_media_value_cents` descending. The created analysis is returned as the
|
|
53
|
+
# single item in `results`. Take its `id` and poll `advanced_ai_analysis.list` until
|
|
54
|
+
# the run reports `COMPLETED`. An advanced analysis can take several hours, so prefer
|
|
55
|
+
# the `advanced_ai_analysis.completed` webhook over frequent polling, which can
|
|
56
|
+
# trigger `RATE_LIMIT_EXCEEDED`. Once complete, retrieve the payload from
|
|
57
|
+
# `advanced_ai_analysis.results`, passing `analysis_id=<id>`.
|
|
58
|
+
#
|
|
59
|
+
# Calls POST /api/v1/advanced_ai_analysis/ (advanced_ai_analysis.create).
|
|
60
|
+
def create(name:, topic:, content_filters:)
|
|
61
|
+
body = {
|
|
62
|
+
"name" => name,
|
|
63
|
+
"topic" => topic,
|
|
64
|
+
"content_filters" => content_filters,
|
|
65
|
+
}.reject { |_, value| value.nil? }
|
|
66
|
+
envelope = @transport.request(:post, "/api/v1/advanced_ai_analysis/", body: body)
|
|
67
|
+
Zelf.one(envelope, Models::AdvancedAiAnalysis, "AdvancedAiAnalysis")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# List Advanced AI Analyses. Returns the advanced AI analyses that have been created,
|
|
71
|
+
# ordered newest first, each with its runs and their current `status`. It lists the
|
|
72
|
+
# analyses available and tracks run progress without retrieving the full result
|
|
73
|
+
# payload. An analysis `id` maps to `analysis_id` on `advanced_ai_analysis.results`
|
|
74
|
+
# and `advanced_ai_analysis.contents`, and each run's `id` maps to `id` on
|
|
75
|
+
# `advanced_ai_analysis.results`. The run `result` download is not included in this
|
|
76
|
+
# response; retrieve it from `advanced_ai_analysis.results` once a run reports
|
|
77
|
+
# `COMPLETED` (statuses: `IN_PROGRESS`, `COMPLETED`, `EMPTY_RESULT`, `FAILED`). Supply
|
|
78
|
+
# `id` to return a single analysis. Ordinary analyses are listed by `ai_analysis.list`
|
|
79
|
+
# instead; the two sets never overlap.
|
|
80
|
+
#
|
|
81
|
+
# Calls GET /api/v1/advanced_ai_analysis/ (advanced_ai_analysis.list).
|
|
82
|
+
def list(id: nil, page: nil, page_size: nil)
|
|
83
|
+
query = {
|
|
84
|
+
"id" => id,
|
|
85
|
+
"page" => page,
|
|
86
|
+
"page_size" => page_size,
|
|
87
|
+
}.reject { |_, value| value.nil? }
|
|
88
|
+
envelope = @transport.request(:get, "/api/v1/advanced_ai_analysis/", query: query)
|
|
89
|
+
path = @transport.resolve_path("/api/v1/advanced_ai_analysis/".dup, {})
|
|
90
|
+
Zelf::Page.new(envelope, Models::AdvancedAiAnalysis, @transport, path, query)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Get Advanced AI Analysis Results. Returns each run's `result`, a signed, time-
|
|
94
|
+
# limited download of the analysis payload, and `dashboard_url`, a link to the same
|
|
95
|
+
# analysis as an interactive dashboard. Call this method after a run reaches
|
|
96
|
+
# `COMPLETED`; for earlier statuses the row is returned with a `null` `result`. The
|
|
97
|
+
# downloaded document follows the `AdvancedAiAnalysisReport` schema. Supply
|
|
98
|
+
# `analysis_id` (the analysis `id` from `advanced_ai_analysis.list`) to return every
|
|
99
|
+
# run of that analysis, or `id` (a single run's `id`) to return one run. Exactly one
|
|
100
|
+
# is required. A malformed id returns `INVALID_ID`; omitting both returns
|
|
101
|
+
# `VALIDATION_ERROR`.
|
|
102
|
+
#
|
|
103
|
+
# Calls GET /api/v1/advanced_ai_analysis/results/ (advanced_ai_analysis.results).
|
|
104
|
+
def results(analysis_id: nil, id: nil, page: nil, page_size: nil)
|
|
105
|
+
query = {
|
|
106
|
+
"analysis_id" => analysis_id,
|
|
107
|
+
"id" => id,
|
|
108
|
+
"page" => page,
|
|
109
|
+
"page_size" => page_size,
|
|
110
|
+
}.reject { |_, value| value.nil? }
|
|
111
|
+
envelope = @transport.request(:get, "/api/v1/advanced_ai_analysis/results/", query: query)
|
|
112
|
+
path = @transport.resolve_path("/api/v1/advanced_ai_analysis/results/".dup, {})
|
|
113
|
+
Zelf::Page.new(envelope, Models::AdvancedAiAnalysisResult, @transport, path, query)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -93,19 +93,17 @@ module Zelf
|
|
|
93
93
|
# return every run of that vetting, or `id` (a single run's `id`) to return one run.
|
|
94
94
|
# One of the two is required. A malformed identifier returns `INVALID_ID`; omitting
|
|
95
95
|
# both returns `VALIDATION_ERROR`. **Disclosures.*; When the vetting requested
|
|
96
|
-
# `DISCLOSURE`, the payload's `
|
|
97
|
-
#
|
|
98
|
-
#
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# `
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
# videos
|
|
105
|
-
#
|
|
106
|
-
#
|
|
107
|
-
# video has no disclosure. Detection reports what was stated; it does not assess legal
|
|
108
|
-
# compliance.
|
|
96
|
+
# `DISCLOSURE`, the payload's `disclosures` holds one entry per signal found: its
|
|
97
|
+
# `content_id` and `content_url`, the `source` it was found in (`frame` for on-screen
|
|
98
|
+
# text, `audio` for the speech transcription, `title` or `caption`), a `kind`
|
|
99
|
+
# (`sponsorship`, `affiliate`, `gifted` or `relationship` for a commercial
|
|
100
|
+
# relationship; `terms` or `risk` for offer conditions and warnings), the quoted
|
|
101
|
+
# `text` and, where known, `time_seconds`. A video with no signal is simply absent.
|
|
102
|
+
# Disclosures are not counted as violations. Limits: only videos up to 10 minutes are
|
|
103
|
+
# checked; on-screen text is read from sampled frames, so text shown only briefly can
|
|
104
|
+
# be missed; videos Zelf analyzed before the request are not re-analyzed for
|
|
105
|
+
# disclosures. An empty `evidence` list does not confirm that a video has no
|
|
106
|
+
# disclosure. Detection reports what was stated; it does not assess legal compliance.
|
|
109
107
|
#
|
|
110
108
|
# Calls GET /api/v1/creator/vetting/results/ (creator_vetting.results).
|
|
111
109
|
def results(id: nil, page: nil, page_size: nil, vetting_id: nil)
|
data/lib/zelf/version.rb
CHANGED
data/lib/zelf/webhooks.rb
CHANGED
|
@@ -18,6 +18,8 @@ module Zelf
|
|
|
18
18
|
|
|
19
19
|
# Event types the API can deliver, one per `webhooks` declaration.
|
|
20
20
|
module EventType
|
|
21
|
+
# Fires once an advanced AI analysis run has finished and its results are stored
|
|
22
|
+
ADVANCED_AI_ANALYSIS_COMPLETED = "advanced_ai_analysis.completed".freeze
|
|
21
23
|
# Fires when an AI analysis run reaches a terminal state (COMPLETED or FAILED)
|
|
22
24
|
AI_ANALYSIS_COMPLETED = "ai_analysis.completed".freeze
|
|
23
25
|
# Scheduled snapshot of the content set that a subscription matches
|
|
@@ -27,7 +29,7 @@ module Zelf
|
|
|
27
29
|
# Fires when a creator vetting analysis run reaches a terminal state (COMPLETED or...
|
|
28
30
|
CREATOR_VETTING_COMPLETED = "creator_vetting.completed".freeze
|
|
29
31
|
|
|
30
|
-
ALL = [AI_ANALYSIS_COMPLETED, CONTENT_SNAPSHOT, CREATOR_SNAPSHOT, CREATOR_VETTING_COMPLETED].freeze
|
|
32
|
+
ALL = [ADVANCED_AI_ANALYSIS_COMPLETED, AI_ANALYSIS_COMPLETED, CONTENT_SNAPSHOT, CREATOR_SNAPSHOT, CREATOR_VETTING_COMPLETED].freeze
|
|
31
33
|
|
|
32
34
|
# Whether the API declares this event type.
|
|
33
35
|
def self.known?(value)
|
data/lib/zelf.rb
CHANGED
|
@@ -6,6 +6,7 @@ require_relative 'zelf/models'
|
|
|
6
6
|
require_relative 'zelf/transport'
|
|
7
7
|
require_relative 'zelf/page'
|
|
8
8
|
require_relative 'zelf/webhooks'
|
|
9
|
+
require_relative 'zelf/resources/advanced_ai_analysis'
|
|
9
10
|
require_relative 'zelf/resources/ai_analysis'
|
|
10
11
|
require_relative 'zelf/resources/analytics'
|
|
11
12
|
require_relative 'zelf/resources/brand_accounts'
|
|
@@ -21,7 +22,7 @@ require_relative 'zelf/resources/sub_brands'
|
|
|
21
22
|
require_relative 'zelf/resources/usage'
|
|
22
23
|
require_relative 'zelf/resources/webhooks'
|
|
23
24
|
|
|
24
|
-
# Ruby client for the Zelf APIs (spec version 1.
|
|
25
|
+
# Ruby client for the Zelf APIs (spec version 1.4.0).
|
|
25
26
|
module Zelf
|
|
26
27
|
# Client for the Zelf APIs.
|
|
27
28
|
#
|
|
@@ -29,13 +30,14 @@ module Zelf
|
|
|
29
30
|
# ZELF_API_KEY environment variable. It is sent as the x-api-key header
|
|
30
31
|
# and is kept out of inspect output.
|
|
31
32
|
class Client
|
|
32
|
-
attr_reader :ai_analysis, :analytics, :brand_accounts, :brands, :comments, :content, :creator_sync, :creator_vetting, :creators, :detection, :engage, :sub_brands, :usage, :webhooks
|
|
33
|
+
attr_reader :advanced_ai_analysis, :ai_analysis, :analytics, :brand_accounts, :brands, :comments, :content, :creator_sync, :creator_vetting, :creators, :detection, :engage, :sub_brands, :usage, :webhooks
|
|
33
34
|
|
|
34
35
|
def initialize(api_key: nil, base_url: nil, timeout: 60,
|
|
35
36
|
max_retries: 2, retry_writes: false, headers: {})
|
|
36
37
|
@transport = Transport.new(api_key: api_key, base_url: base_url, timeout: timeout,
|
|
37
38
|
max_retries: max_retries, retry_writes: retry_writes,
|
|
38
39
|
headers: headers)
|
|
40
|
+
@advanced_ai_analysis = Resources::AdvancedAiAnalysis.new(@transport)
|
|
39
41
|
@ai_analysis = Resources::AiAnalysis.new(@transport)
|
|
40
42
|
@analytics = Resources::Analytics.new(@transport)
|
|
41
43
|
@brand_accounts = Resources::BrandAccounts.new(@transport)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zelf-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Zelf
|
|
@@ -21,6 +21,7 @@ files:
|
|
|
21
21
|
- lib/zelf/model.rb
|
|
22
22
|
- lib/zelf/models.rb
|
|
23
23
|
- lib/zelf/page.rb
|
|
24
|
+
- lib/zelf/resources/advanced_ai_analysis.rb
|
|
24
25
|
- lib/zelf/resources/ai_analysis.rb
|
|
25
26
|
- lib/zelf/resources/analytics.rb
|
|
26
27
|
- lib/zelf/resources/brand_accounts.rb
|