- 后端
【免费下载链接】instagram-private-api
NodeJS Instagram private API SDK. Written in TypeScript.
本篇技术指南聚焦 instagram-private-api 中故事数据洞察响应的核心数据结构——StoriesInsightsFeedResponseBusiness_manager接口。它承载着商业账户每条已发布 Story 的曝光、触达、退出、回复等关键指标,是所有 Story 级数据分析的必经数据入口。读完本文,你将掌握该响应从RootObject到单个node的完整层级与每个字段的业务含义、如何通过StoriesInsightsFeed工厂方法拉取分页数据,以及底层 GraphQL 请求的真实调用链。
一、接口概览:business_manager 在整个响应中的位置
StoriesInsightsFeedResponseBusiness_manager定义于 src/responses/stories-insights.feed.response.ts:12,属于responses命名空间。它的完整定义非常精简:
export interface StoriesInsightsFeedResponseBusiness_manager { stories_unit: StoriesInsightsFeedResponseStories_unit; }全接口只有一个属性stories_unit,类型为StoriesInsightsFeedResponseStories_unit。从命名可以推断,Instagram 商业平台将"故事数据单元(stories unit)"挂在business_manager节点之下,本 SDK 按官方响应结构原样复刻了这一层级。
需要提醒的是:该接口不应单独使用。它是
StoriesInsightsFeedResponseUser的一个属性,嵌套在RootObject → data → user → business_manager的路径中。SDK 在消费响应时,正是沿着这条路径取出stories_unit的数据(见 src/feeds/stories-insights.feed.ts:17 中body.data.user.business_manager.stories_unit.stories.edges)。
二、完整响应层级:从根对象到单条 Story 指标
business_manager只是链路中的一环。完整的数据结构定义在同一文件的连续接口中(src/responses/stories-insights.feed.response.ts),层级如下:
StoriesInsightsFeedResponseRootObject └── data: StoriesInsightsFeedResponseData └── user: StoriesInsightsFeedResponseUser ├── id: string └── business_manager: StoriesInsightsFeedResponseBusiness_manager ← 本文主角 └── stories_unit: StoriesInsightsFeedResponseStories_unit └── stories: StoriesInsightsFeedResponseStories ├── edges: StoriesInsightsFeedResponseEdgesItem[] └── page_info: StoriesInsightsFeedResponsePage_info ├── end_cursor: string └── has_next_page: boolean各层接口对应关系与定义行号:
| 接口 | 含义 | 定义位置 |
|---|---|---|
StoriesInsightsFeedResponseRootObject | 响应根对象,包裹data | src/responses/stories-insights.feed.response.ts:1 |
StoriesInsightsFeedResponseData | 数据层,含user | src/responses/stories-insights.feed.response.ts:4 |
StoriesInsightsFeedResponseUser | 用户信息,含id与business_manager | src/responses/stories-insights.feed.response.ts:7 |
StoriesInsightsFeedResponseBusiness_manager | 商业管理节点,含stories_unit | src/responses/stories-insights.feed.response.ts:11 |
StoriesInsightsFeedResponseStories_unit | 故事数据单元,含stories | src/responses/stories-insights.feed.response.ts:14 |
StoriesInsightsFeedResponseStories | 故事列表,含edges与page_info | src/responses/stories-insights.feed.response.ts:17 |
StoriesInsightsFeedResponseEdgesItem | 单条边,含node与cursor | src/responses/stories-insights.feed.response.ts:21 |
StoriesInsightsFeedResponseNode | 单条 Story 的指标节点 | src/responses/stories-insights.feed.response.ts:25 |
StoriesInsightsFeedResponseInline_insights_node | 内联洞察节点 | src/responses/stories-insights.feed.response.ts:39 |
StoriesInsightsFeedResponsePage_info | 分页信息 | src/responses/stories-insights.feed.response.ts:43 |
由此可见,business_manager是"用户 → 故事数据单元"之间的桥梁层。整棵类型树都从 src/responses/index.ts:86 统一导出,可通过import { StoriesInsightsFeedResponseRootObject } from 'instagram-private-api'直接引用。
三、核心属性:stories_unit
StoriesInsightsFeedResponseBusiness_manager唯一的属性stories_unit类型为StoriesInsightsFeedResponseStories_unit(定义于 src/responses/stories-insights.feed.response.ts:14):
export interface StoriesInsightsFeedResponseStories_unit { stories: StoriesInsightsFeedResponseStories; }它再往下是一层stories,该结构采用 Instagram 数据接口通用的GraphQL 边(edges)+ 分页(page_info)模式:
export interface StoriesInsightsFeedResponseStories { edges: StoriesInsightsFeedResponseEdgesItem[]; page_info: StoriesInsightsFeedResponsePage_info; }edges:本次请求返回的 Story 列表,每个元素是一条"边";page_info:分页游标信息,用于判断是否还有下一页(详见下文"分页机制"小节)。
StoriesInsightsFeedResponseEdgesItem本身只包含两项(src/responses/stories-insights.feed.response.ts:21):
export interface StoriesInsightsFeedResponseEdgesItem { node: StoriesInsightsFeedResponseNode; cursor: null; }注意cursor被固定声明为字面量类型null——从当前源码结构看,分页游标并未挂在每条边上,而是由page_info.end_cursor承担,这一点与部分其他 Feed 的响应结构不同。
四、单条 Story 的指标字段详解(node)
真正的业务数据集中在StoriesInsightsFeedResponseNode(src/responses/stories-insights.feed.response.ts:25),StoriesInsightsFeed.items()返回的正是edges数组,每个元素的node结构如下:
export interface StoriesInsightsFeedResponseNode { instagram_media_id: string; display_url: string; exits_count: number; impression_count: number; reach_count: number; replies_count: number; taps_back_count: number; taps_forward_count: number; story_swipe_away_count: number; inline_insights_node: StoriesInsightsFeedResponseInline_insights_node; id: string; __typename: string; }各字段的指标含义与 TypeScript 类型汇总:
| 字段 | 类型 | 业务含义 |
|---|---|---|
instagram_media_id | string | Story 在 Instagram 媒体体系中的 ID,可用于关联媒体详情 |
display_url | string | Story 封面/预览图的展示 URL |
exits_count | number | 用户退出观看的次数 |
impression_count | number | 曝光次数(impression),即 Story 被展示的次数 |
reach_count | number | 触达人数(reach),即实际看到 Story 的独立用户数 |
replies_count | number | 回复/私信回复次数 |
taps_back_count | number | 点击"返回"的次数 |
taps_forward_count | number | 点击"下一步"的次数 |
story_swipe_away_count | number | 滑走(swipe away)的次数 |
inline_insights_node | StoriesInsightsFeedResponseInline_insights_node | 内联洞察节点,见下文 |
id | string | 节点唯一 ID |
__typename | string | GraphQL 运行时类型名 |
其中inline_insights_node是嵌套的简化结构(src/responses/stories-insights.feed.response.ts:39):
export interface StoriesInsightsFeedResponseInline_insights_node { state: string; metrics: null; }它只包含一个state字符串字段,而metrics在类型层面声明为null——从源码结构看,该节点在当前响应版本中未携带附加指标数据,属于保留字段。这些计数型指标直接对应 Instagram 商业账户后台"故事洞察"面板所展示的数据,适合用于构建自定义的数据看板或导出分析。
五、获取方式:StoriesInsightsFeed 与工厂方法
5.1 通过 FeedFactory 创建
获取完整故事洞察列表的标准入口是FeedFactory.storiesInsights(timeframe)(src/core/feed.factory.ts:214):
public storiesInsights(timeframe: 'ONE_DAY' | 'ONE_WEEK' | 'TWO_WEEKS') { return plainToClassFromExist(new StoriesInsightsFeed(this.client), { timeframe }); }使用方法示例:
import { IgApiClient } from 'instagram-private-api'; const ig = new IgApiClient(); ig.state.generateDevice('username'); await ig.account.login('username', 'password'); // 获取近一周的故事数据洞察 Feed const feed = ig.feed.storiesInsights('ONE_WEEK'); const items = await feed.items(); for (const edge of items) { const story = edge.node; console.log({ id: story.id, impressions: story.impression_count, reach: story.reach_count, exits: story.exits_count, replies: story.replies_count, tapsForward: story.taps_forward_count, tapsBack: story.taps_back_count, swipeAway: story.story_swipe_away_count, }); }timeframe是必选参数,取值限定为三个字面量类型:'ONE_DAY' | 'ONE_WEEK' | 'TWO_WEEKS',分别对应近一天、近一周、近两周的数据窗口。它通过@Expose()装饰器(src/feeds/stories-insights.feed.ts:9)暴露,允许序列化/反序列化时保留该配置。
5.2 单条 Story 数据:InsightsService.story()
如果只需要某一条 Story 的洞察数据,可使用InsightsService.story(storyId)(src/services/insights.service.ts:59),它同样返回StoriesInsightsFeedResponseRootObject结构,但走的是独立查询IgInsightsStoryInsightsAppQuery:
ig.insights.story('STORY_MEDIA_ID').then(({ data }) => { const storiesUnit = data.user.business_manager.stories_unit; // ... });5.3 底层请求原理:Ads GraphQL 通道
StoriesInsightsFeed与InsightsService均不直接使用常规 REST 端点,而是经由AdsRepository.graphQL()(src/repositories/ads.repository.ts:5)向/api/v1/ads/graphql/发送请求。以StoriesInsightsFeed.request()(src/feeds/stories-insights.feed.ts:20)为例,其核心参数为:
const body = await this.client.ads.graphQL<StoriesInsightsFeedResponseRootObject>({ surface: { friendlyName: 'IgInsightsStoryGridSurfaceQuery' }, documentId: '1995528257207653', variables: { count: 15, // 单页条数 cursor: this.nextCursor, // 分页游标 IgInsightsGridMediaImage_SIZE: 256, // 缩略图尺寸 queryParams: { access_token: '', id: this.client.state.cookieUserId, // 当前登录用户 }, timeframe: this.timeframe, // ONE_DAY / ONE_WEEK / TWO_WEEKS }, });而AdsRepository.graphQL会把上述参数组装成 Facebook Relay Modern 风格的表单请求(src/repositories/ads.repository.ts:15):
form: { access_token: options.accessToken, fb_api_caller_class: 'RelayModern', fb_api_req_friendly_name: options.surface.friendlyName, // 如 IgInsightsStoryGridSurfaceQuery doc_id: options.documentId, // 如 1995528257207653 variables: JSON.stringify(options.variables), }请求还带有两个查询参数:locale(当前语言,取自client.state.language)与vc_policy: 'insights_policy'。这意味着调用故事洞察接口前必须完成登录并具备商业账户/创作者权限,因为 GraphQL 请求使用cookieUserId作为id,且access_token传空字符串,鉴权完全依赖会话 Cookie。
六、分页机制与分页信息接口
StoriesInsightsFeed的分页由page_info驱动(src/responses/stories-insights.feed.response.ts:43):
export interface StoriesInsightsFeedResponsePage_info { end_cursor: string; has_next_page: boolean; }Feed 的statesetter 每次请求后更新内部游标与可用状态(src/feeds/stories-insights.feed.ts:39):
protected set state(response: StoriesInsightsFeedResponseRootObject) { const { end_cursor, has_next_page } = response.data.user.business_manager.stories_unit.stories.page_info; this.nextCursor = end_cursor; this.moreAvailable = has_next_page; }也就是说,business_manager.stories_unit.stories.page_info不仅承载数据,还直接决定了 Feed 的isMoreAvailable()返回值与下一次请求的cursor。手动翻页时,可循环判断:
const feed = ig.feed.storiesInsights('ONE_WEEK'); let items = await feed.items(); while (feed.isMoreAvailable()) { items = items.concat(await feed.items()); }七、继承自 Feed 基类的通用能力
StoriesInsightsFeed继承自抽象基类Feed(src/core/feed.ts),因此天然具备以下能力:
items$/observable():以 RxJS Observable 形式逐个分页发射数据,并在收到 400 / 429 / 500 / 502 等瞬时错误时按attemptOptions自动重试等待(默认delay: 60000、maxAttempts: 10、指数退避,src/core/feed.ts:10);serialize()/deserialize()/toPlain():基于class-transformer的序列化工具,可将 Feed 配置(含timeframe、nextCursor)保存后恢复,实现断点续跑;isMoreAvailable():判断是否还有下一页。
示例(响应式拉取全部 Story 数据):
const feed = ig.feed.storiesInsights('ONE_DAY'); feed.items$.subscribe({ next: (edges) => { for (const edge of edges) { console.log(edge.node.display_url, edge.node.reach_count); } }, error: (e) => console.error(e), complete: () => console.log('all stories insights loaded'), });八、注意事项与使用前提
- 账户类型要求:故事洞察数据属于 Instagram 商业账户/创作者账户功能,普通个人账户调用该接口通常会失败;
- 登录状态:请求依赖
client.state.cookieUserId与会话 Cookie(src/feeds/stories-insights.feed.ts:30),必须先ig.account.login();数据仅对当前登录账号自身可见; - 频率控制:洞察接口通过
AdsRepository.graphQL高频访问易触发限流,Feed 基类的自动重试(针对 400/429/500/502)只处理瞬时抖动,长时间高频轮询仍应自行控制节奏; - 游标一致性:
timeframe在创建 Feed 时固定,翻页过程中不宜变更,否则游标与数据窗口可能错位。
结语
StoriesInsightsFeedResponseBusiness_manager虽然只是一个承载单一stories_unit属性的薄层接口,却是 instagram-private-api 故事数据洞察响应中连接"用户身份"与"Story 指标数据"的关键枢纽。结合 stories-insights.feed.response.ts、stories-insights.feed.ts、insights.service.ts 与 feed.factory.ts 四份源码,你可以完整地读取、分页、序列化并消费每一条 Story 的曝光、触达、退出与互动指标,为运营分析或自动化报表提供坚实的数据基础。
- 后端
【免费下载链接】instagram-private-api
NodeJS Instagram private API SDK. Written in TypeScript.
相关推荐
instagram-private-api 账号数据洞察(Insights)接口详解:InsightsServiceAccountResponseFollow_status 结构解析
instagram private api 账号数据洞察(Insights)接口详解:InsightsServiceAccountResponseFollow_
后端instagram-private-api 账号洞察(Insights)中 account_discovery_graph 响应结构深度解析
instagram private api 账号洞察(Insights)中 account_discovery_graph 响应结构深度解析 本文聚焦 Node
后端instagram-private-api 账号数据洞察(Insights)响应模型解读:InsightsServiceAccountResponseGraph 接口详解
instagram private api 账号数据洞察(Insights)响应模型解读:InsightsServiceAccountResponseGraph
后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考