☰
instagram-private-api 中 ReelsMediaFeedResponseTalliesItem 接口解析:Reels 投票与问答贴纸的计票项结构
2026/10/16 1:31:23 网站建设 项目流程
  • 后端

【免费下载链接】instagram-private-api

NodeJS Instagram private API SDK. Written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/in/instagram-private-api
点击查看免费下载

本文基于 instagram-private-api 仓库中 TypeDoc 自动生成的接口文档 ReelsMediaFeedResponseTalliesItem,围绕ReelsMediaFeedResponseTalliesItem这一响应模型展开:它是 Reels 媒体信息流(/api/v1/feed/reels_media/)中投票贴纸(poll)与问答贴纸(quiz)选项计票结果的最小数据单元。读完后你将掌握该接口三个字段(text、font_size、count)的语义与来源、它在响应树中的挂载位置(poll_sticker.tallies/quiz_sticker.tallies),以及如何通过ReelsMediaFeed发起请求拿到包含这些字段的数据,并与 SDK 写入侧的PollSticker、QuizSticker构建器对照理解同名字段的往返关系。

一、接口定义与三个字段

ReelsMediaFeedResponseTalliesItem定义在 src/responses/reels-media.feed.response.ts#L105-L109 中,是描述“某个互动选项当前计票情况”的 TypeScript 接口:

export interface ReelsMediaFeedResponseTalliesItem { text: string; // 选项文本,例如 "Yes" / "No",或 quiz 的备选项文案 font_size?: number; // 可选:贴纸内该选项文本的字体大小 count: number; // 当前该选项的投票/作答数量 }

对应文档页中的字段说明如下(与原文档一一对应):

字段类型必填源码位置说明
textstring是reels-media.feed.response.ts:106选项文本内容
font_sizenumber否(Optional)reels-media.feed.response.ts:107选项文本的字体大小,服务端不一定返回
countnumber是reels-media.feed.response.ts:108该选项的累计计数

该接口文件通过 src/responses/index.ts#L54 的export * from './reels-media.feed.response'统一导出,因此可以在项目任意处以ReelsMediaFeedResponseTalliesItem名称直接导入使用。

一份符合该结构的 JSON 示例(投票贴纸两个选项各 3 票 / 1 票):

{ "text": "Yes", "font_size": 28.0, "count": 3 }

二、它在 Reels 响应树中的挂载位置

从源码结构看,ReelsMediaFeedResponseTalliesItem并不是顶层字段,而是嵌套在互动贴纸对象内部的tallies数组元素类型,共有两处引用,都在同一个响应文件中:

  1. 投票贴纸ReelsMediaFeedResponsePollSticker(src/responses/reels-media.feed.response.ts#L94-L104):
export interface ReelsMediaFeedResponsePollSticker { id: string; poll_id: number; question: string; tallies: ReelsMediaFeedResponseTalliesItem[]; promotion_tallies: null; viewer_can_vote: boolean; viewer_vote?: number; is_shared_result: boolean; finished: boolean; }
  1. 问答贴纸ReelsMediaFeedResponseQuizSticker(src/responses/reels-media.feed.response.ts#L144-L156):
export interface ReelsMediaFeedResponseQuizSticker { id: string; quiz_id: number; question: string; tallies: ReelsMediaFeedResponseTalliesItem[]; correct_answer: number; // 正确答案在 tallies 中的下标 viewer_can_answer: boolean; finished: boolean; text_color: string; start_background_color: string; end_background_color: string; viewer_answer?: number; // 当前查看者所选答案下标 }

贴纸外层还有一层“贴纸画布”容器ReelsMediaFeedResponseStoryPollsItem/ReelsMediaFeedResponseStoryQuizsItem(L82-L93、L132-L143),携带x/y/z、width/height、rotation、is_pinned、is_hidden、is_sticker等布局字段,分别对应单条 Reels 媒体ReelsMediaFeedResponseItem上的可选数组属性story_polls、story_quizs(L76-L79)。也就是说,只有当一条 Reels 确实携带投票或问答贴纸时,你才能在story_polls[].poll_sticker.tallies/story_quizs[].quiz_sticker.tallies路径上读到ReelsMediaFeedResponseTalliesItem[]数组。

几个消费侧的实用判断点:

  • 通过count求和与比较,可以还原投票/答对的实时比例;
  • 对 quiz 而言,correct_answer与viewer_answer都是“tallies 下标”而非文本匹配,配合每个TalliesItem.text才能知道选项含义;
  • 贴纸容器的is_hidden/is_pinned等标记会影响贴纸在客户端上的展示形态,解析时建议保留;
  • font_size是可选字段,做数值运算(例如按字号渲染)前需要判空。

三、数据来源:ReelsMediaFeed 的请求与扁平化逻辑

ReelsMediaFeedResponseTalliesItem所在的完整响应由ReelsMediaFeed类拉取。该类的实现见 src/feeds/reels-media.feed.ts,类文档见 docs/classes/feeds/ReelsMediaFeed.md。其request()方法向私有接口发起签名 POST 请求:

async request() { const { body } = await this.client.request.send<ReelsMediaFeedResponseRootObject>({ url: `/api/v1/feed/reels_media/`, method: 'POST', form: this.client.request.sign({ user_ids: this.userIds, source: this.source, // 默认 'feed_timeline' _uuid: this.client.state.uuid, _uid: this.client.state.cookieUserId, _csrftoken: this.client.state.cookieCsrfToken, device_id: this.client.state.deviceId, supported_capabilities_new: JSON.stringify(SUPPORTED_CAPABILITIES), }), }); return body; }

请求参数要点:

  • user_ids:要拉取 Reels 的用户 ID 数组(Array<number | string>),来自 src/feeds/reels-media.feed.ts#L7;
  • source:请求来源模块标识,默认'feed_timeline',类型为IgAppModule(src/types/common.types.ts#L3-L33),表示该请求模拟自 App 内哪个入口;
  • 其余_uuid、_uid、_csrftoken、device_id、supported_capabilities_new由客户端登录态与设备指纹填充,其中能力清单来自 src/samples/supported-capabilities.json。

响应根对象为ReelsMediaFeedResponseRootObject,形如{ reels: { [pk]: ReelsMediaFeedResponse }, status: string }:reels是以用户pk为键的映射,每个用户对应一个包含items(Reels 媒体列表)的集合。items()方法会把各用户的items展平成一个数组返回:

async items(): Promise<ReelsMediaFeedResponseItem[]> { const body = await this.request(); return Object.values(body.reels).reduce( (accumulator, current: ReelsMediaFeedResponse) => accumulator.concat(current.items), [], ); }

调用方式经由FeedFactory创建,见 src/core/feed.factory.ts#L153-L155:

public reelsMedia(options: { userIds: Array<number | string>; source?: IgAppModule }): ReelsMediaFeed { return plainToClassFromExist(new ReelsMediaFeed(this.client), options); }

IgApiClient上的入口属性为feed(src/core/client.ts#L45 中public feed = new FeedFactory(this)),因此典型消费代码为:

import { IgApiClient } from 'instagram-private-api'; const ig = new IgApiClient(); // ... 配置设备指纹并 await ig.account.login(options) 后: const feed = ig.feed.reelsMedia({ userIds: [123456789] }); const items = await feed.items(); for (const item of items) { const polls = item.story_polls ?? []; for (const slot of polls) { console.log(slot.poll_sticker.question, slot.poll_sticker.tallies); // tallies: ReelsMediaFeedResponseTalliesItem[] // 例如 [{ text: 'Yes', font_size: 28.0, count: 3 }, { text: 'No', count: 1 }] } }

此外,ReelsMediaFeed继承自 src/core/feed.ts 的Feed基类,除了items()还可使用items$/observable()获得 RxJS 订阅,基类内置的attemptOptions提供默认重试策略(最多 10 次尝试、带抖动的指数退避,见 src/core/feed.ts#L10-L17),适合长轮询场景。注意ReelsMediaFeed覆写了set state(body) {}为空实现且未维护moreAvailable,因此isMoreAvailable()恒为false,observable()只会发出一次数据。

四、与写入侧的对照:PollSticker 与 QuizSticker 的 tallies 构造

理解ReelsMediaFeedResponseTalliesItem的读取语义后,SDK 的写入侧(sticker-builder)提供了同构的“发”向模型,二者在text/count/font_size维度上形成对照:

  • PollSticker(src/sticker-builder/stickers/poll.sticker.ts):其tallies为固定两元素的[PollStickerTallie, PollStickerTallie],其中PollStickerTallie仅含text与可选fontSize。注意 setter 会对每一项注入默认字号:
set tallies(value: Tallies) { this._tallies = value.map(t => ({ fontSize: 28.0, ...t })) as Tallies; }

这正是响应中font_size常见值为28.0的来源(显式赋值的项会覆盖默认值)。该贴纸id为polling_sticker_vibrant、序列化键为story_polls,默认宽高0.49934897/0.1266892(L28-L37)。

  • QuizSticker(src/sticker-builder/stickers/quiz.sticker.ts):options接受Array<{ text: string; count: number }>,也支持纯字符串数组自动补count: 0;其id为quiz_story_sticker_default、序列化键为story_quizs,与响应侧quiz_sticker.tallies的下标语义(correct_answer/viewer_answer)一一对应。

  • configure 参数类型StoryPollTallie(src/types/media.configure-story.options.ts#L137-L142)对font_size给出了取值约束注释range: 17.5 .. 35.0,且要求count: 0、viewer_vote: 0、viewer_can_vote: true(新建投票时的初始状态)。这与读取侧“count由服务端累计”的语义互为印证:发出去时从零开始,读回来时才是真实票数。

五、相似结构在其他响应中的复用

从源码结构看,{ text, count, font_size? }这一“计票项”三元组在多个响应文件中被重复建模,说明它是 Instagram 贴纸体系里稳定的通用形态。除本文主角外,仓库中还有:

  • ReelsTrayFeedResponseTalliesItem:Reels 托盘信息流(reelsTray)中 poll/quiz 贴纸的计票项,字段与本文接口完全一致;
  • MediaUpdatedMediaResponseTalliesItem:configure 后返回的updated_media中投票贴纸的计票项;
  • HighlightsRepositoryEditReelResponseTalliesItem:编辑精选集(highlight reel)响应中的同名数组。

这意味着如果你已在reelsMedia中解析过ReelsMediaFeedResponseTalliesItem,同样的解析逻辑(按text匹配选项、比较count、必要时判空font_size)可以平移到托盘流与 updated media 场景,只是外层贴纸字段的类型名不同。

六、使用注意事项小结

  1. 可选性:font_size为Optional,且整条链路(story_polls/story_quizs数组本身)均为可选,解析前建议逐级判空;
  2. 下标语义:quiz 的correct_answer、viewer_answer与 poll 的viewer_vote都是tallies数组下标,切勿与选项文本硬编码绑定;
  3. 状态字段:finished/viewer_can_vote/viewer_can_answer决定了贴纸当前是否仍可互动,展示结果时应结合这些布尔位判断是否展示百分比;
  4. 请求前提:reelsMedia需要已登录的IgApiClient(state中具备cookieUserId、csrfToken、deviceId等),且user_ids目标用户对当前会话可见,否则响应中对应reels键可能缺失或为空;
  5. 字段对齐:与写入侧StoryPollTallie.font_size(17.5 ~ 35.0)及PollSticker默认28.0对照,可辅助校验异常字号值。

以上结论均以当前仓库源码为准:接口定义见 src/responses/reels-media.feed.response.ts,请求实现见 src/feeds/reels-media.feed.ts,构建器实现见 src/sticker-builder/stickers/poll.sticker.ts 与 src/sticker-builder/stickers/quiz.sticker.ts。

  • 后端

【免费下载链接】instagram-private-api

NodeJS Instagram private API SDK. Written in TypeScript.

项目地址:https://gitcode.com/gh_mirrors/in/instagram-private-api
点击查看免费下载
上一篇:secGear社区贡献指南:如何参与开源机密计算项目的完整流程
下一篇:virtCCA_sdk常见问题排查:从ContainerCreating到Pending状态解决

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询