@storylinkpro/instagram-stories-api 0.1.0 → 0.1.2

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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 0.1.2
4
+
5
+ - The client sends the access token in the `Authorization` header, not in the URL. Proxy and server logs no longer record it. The client also removes the token from the `paging.next` URLs that Meta returns.
6
+ - The timeout now works on Node 20.0 to 20.2 when you pass your own `signal`.
7
+ - The publish workflow runs the dev dependencies in a job that cannot get an npm token.
8
+
9
+ ## 0.1.1
10
+
11
+ - The package description, keywords and README make the package easier to find.
12
+ - A GitHub Actions workflow publishes new versions with npm provenance.
13
+
14
+ ## 0.1.0
15
+
16
+ - First release. A typed client and CLI that read an Instagram account, its Stories, posts and reels, and their insights.
package/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # @storylinkpro/instagram-stories-api
2
2
 
3
- A typed client and CLI for the Instagram Graph API. It reads an account's Stories, posts and reels, and their insights. It has no dependencies. It needs Node 20+ or another runtime with `fetch`.
3
+ [![npm](https://img.shields.io/npm/v/@storylinkpro/instagram-stories-api)](https://www.npmjs.com/package/@storylinkpro/instagram-stories-api)
4
+ [![CI](https://github.com/storylinkpro/instagram-stories-api/actions/workflows/ci.yml/badge.svg)](https://github.com/storylinkpro/instagram-stories-api/actions/workflows/ci.yml)
5
+ [![types](https://img.shields.io/npm/types/@storylinkpro/instagram-stories-api)](https://www.npmjs.com/package/@storylinkpro/instagram-stories-api)
6
+ [![license](https://img.shields.io/npm/l/@storylinkpro/instagram-stories-api)](LICENSE)
4
7
 
5
- Use it in a script, a cron job or your own dashboard.
8
+ **An Instagram Graph API client and CLI for Node.js and TypeScript.** It reads Instagram Stories, posts and reels. It also reads their insights: views, reach, replies, likes, comments, saves and shares. It has no dependencies. It needs Node 20+ or another runtime with `fetch`.
9
+
10
+ Use it in a script, a cron job or your own Instagram analytics dashboard.
6
11
 
7
12
  > Unofficial. Meta did not make this package and does not support it. It calls Meta's public Graph API at `graph.facebook.com`.
8
13
 
@@ -12,7 +17,7 @@ Use it in a script, a cron job or your own dashboard.
12
17
  npm install @storylinkpro/instagram-stories-api
13
18
  ```
14
19
 
15
- ## Quick start
20
+ ## Quick start: read Instagram story insights
16
21
 
17
22
  ```ts
18
23
  import { createClient } from "@storylinkpro/instagram-stories-api";
@@ -95,7 +100,7 @@ Methods that read an account take `igUserId` to use another account than the cli
95
100
 
96
101
  A failed call throws `InstagramApiError`. It has `status`, and Meta's `code`, `subcode`, `type`, `fbtraceId` and `message`. It also has these flags:
97
102
 
98
- - `isAuthError`: code 190, or subcode 458, 460, 463 or 467. The token is expired, was revoked, or is not valid. Get a new token.
103
+ - `isAuthError`: code 190, or subcode 458, 460, 463 or 467. The token expired, someone revoked it, or it is not valid. Get a new token.
99
104
  - `isRateLimit`: code 4, 17, 32, 613, 80001 or 80002. Meta throttled the app or the account. Wait before you try again.
100
105
 
101
106
  A network error or a timeout has `status` 0. The message never contains the access token.
@@ -111,7 +116,7 @@ try {
111
116
  }
112
117
  ```
113
118
 
114
- ### Rate-limit usage
119
+ ### Instagram API rate limits
115
120
 
116
121
  Meta sends usage headers on each response. `ig.lastUsage` holds the most recent ones, and `error.usage` holds the ones of a failed call:
117
122
 
@@ -122,7 +127,7 @@ ig.lastUsage?.businessUseCase; // from x-business-use-case-usage, per business o
122
127
 
123
128
  The client does not retry. You decide when to call again.
124
129
 
125
- ## Get a token
130
+ ## Get an Instagram Graph API access token
126
131
 
127
132
  This version uses the Instagram API with Facebook Login. You need:
128
133
 
@@ -134,9 +139,10 @@ To find the Instagram account id, call `GET /me/accounts?fields=instagram_busine
134
139
 
135
140
  Keep the token on the server. Do not send it to the browser.
136
141
 
137
- ## Made by Storylink
142
+ ## Related
138
143
 
139
- Made by Storylink — schedule Instagram Stories, posts and reels: https://storylink.pro
144
+ - [Storylink](https://storylink.pro) schedules Instagram Stories, posts and reels, and shows their results. Storylink made this package.
145
+ - [`storylink-mcp`](https://www.npmjs.com/package/storylink-mcp) connects Claude and other AI assistants to your Storylink Instagram analytics.
140
146
 
141
147
  ## License
142
148
 
package/dist/client.js CHANGED
@@ -67,11 +67,23 @@ function metricValues(body) {
67
67
  }
68
68
  return out;
69
69
  }
70
+ /** Aborts when either signal aborts. `AbortSignal.any` needs Node 20.3+, so
71
+ * older runtimes link the two by hand and keep the timeout. */
70
72
  function combineSignals(a, b) {
71
73
  if (!a)
72
74
  return b;
73
75
  const any = AbortSignal.any;
74
- return any ? any([a, b]) : a;
76
+ if (any)
77
+ return any([a, b]);
78
+ const ctrl = new AbortController();
79
+ for (const s of [a, b]) {
80
+ if (s.aborted) {
81
+ ctrl.abort(s.reason);
82
+ return ctrl.signal;
83
+ }
84
+ s.addEventListener("abort", () => ctrl.abort(s.reason), { once: true });
85
+ }
86
+ return ctrl.signal;
75
87
  }
76
88
  export function createClient(options) {
77
89
  if (!options || typeof options.accessToken !== "string" || options.accessToken.length === 0) {
@@ -91,13 +103,15 @@ export function createClient(options) {
91
103
  let lastUsage = null;
92
104
  const userId = (o) => checkId(o?.igUserId ?? options.igUserId, "igUserId");
93
105
  async function call(url, signal) {
94
- url.searchParams.set("access_token", token);
106
+ // The token goes in a header, not the query string, so it stays out of
107
+ // proxy and server logs. Meta adds it to `paging.next` URLs: remove it.
108
+ url.searchParams.delete("access_token");
95
109
  const path = url.pathname;
96
110
  let res;
97
111
  try {
98
112
  res = await doFetch(url.toString(), {
99
113
  method: "GET",
100
- headers: { accept: "application/json" },
114
+ headers: { accept: "application/json", authorization: `Bearer ${token}` },
101
115
  signal: combineSignals(signal, AbortSignal.timeout(timeoutMs)),
102
116
  });
103
117
  }
package/package.json CHANGED
@@ -1,15 +1,28 @@
1
1
  {
2
2
  "name": "@storylinkpro/instagram-stories-api",
3
- "version": "0.1.0",
4
- "description": "Typed, zero-dependency client and CLI for the Instagram Graph API: read Instagram Stories, posts, reels and their insights.",
3
+ "version": "0.1.2",
4
+ "description": "Instagram Graph API client and CLI for Node.js and TypeScript: read Instagram Stories, posts, reels and their insights (views, reach, replies, likes, saves, shares). Typed, zero dependencies.",
5
5
  "keywords": [
6
6
  "instagram",
7
7
  "instagram-api",
8
8
  "instagram-graph-api",
9
9
  "instagram-stories",
10
+ "instagram-story",
10
11
  "instagram-insights",
11
- "meta",
12
- "typescript"
12
+ "instagram-analytics",
13
+ "instagram-reels",
14
+ "instagram-business",
15
+ "meta-graph-api",
16
+ "facebook-graph-api",
17
+ "graph-api",
18
+ "social-media",
19
+ "analytics",
20
+ "insights",
21
+ "api-client",
22
+ "cli",
23
+ "typescript",
24
+ "nodejs",
25
+ "zero-dependency"
13
26
  ],
14
27
  "homepage": "https://github.com/storylinkpro/instagram-stories-api#readme",
15
28
  "bugs": {
@@ -35,9 +48,10 @@
35
48
  "./package.json": "./package.json"
36
49
  },
37
50
  "files": [
38
- "dist",
51
+ "CHANGELOG.md",
52
+ "LICENSE",
39
53
  "README.md",
40
- "LICENSE"
54
+ "dist"
41
55
  ],
42
56
  "sideEffects": false,
43
57
  "engines": {