@eryxenx/insta-chat 2.0.8 → 2.0.9

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 CHANGED
@@ -4,6 +4,21 @@ All notable changes to `@eryxenx/insta-chat` are documented here.
4
4
  The format follows [Keep a Changelog](https://keepachangelog.com/) and uses
5
5
  [Semantic Versioning](https://semver.org/).
6
6
 
7
+ ## [2.0.9] - 2026-10-11
8
+
9
+ ### Fixed
10
+
11
+ - **`unsendMessage` still never deleted the message.** The 2.0.8 fix sent
12
+ `_csrftoken` + `_uuid` to the REST delete endpoint
13
+ (`/api/v1/direct_v2/threads/<t>/items/<id>/delete/`), but Instagram retired
14
+ that endpoint: on `www.instagram.com` the whole `/api/v1` namespace now
15
+ returns `{"message":"useragent mismatch","status":"fail"}` /
16
+ `not-logged-in` 404, and on `i.instagram.com` it needs the mobile app
17
+ identity. Unsend now goes through the web DM client's Relay mutation
18
+ `IGDMessageUnsendDialogOffMsysMutation` (doc_id `26948700068153789`) with
19
+ `{ message_id, send_data: { thread_id } }`, which answers
20
+ `{ data: { direct_unsend_message: true } }`. Verified against a real message.
21
+
7
22
  ## [2.0.8] - 2026-10-11
8
23
 
9
24
  ### Fixed
package/DOCS.md CHANGED
@@ -182,6 +182,7 @@ Relay **doc_ids** (stable per friendly-name, rotate rarely):
182
182
  | `IGDirectCutoutStickerSendMutation` | `26601474479505807` |
183
183
  | `PolarisDirectInboxQuery` | `27909866362025854` |
184
184
  | `useFeatureLimitsOffMsysQuery` (login probe) | `28374543635529813` |
185
+ | `IGDMessageUnsendDialogOffMsysMutation` (unsend) | `26948700068153789` |
185
186
  | Thread detail | `29619996517588618` |
186
187
 
187
188
  ### Text send
@@ -213,6 +214,21 @@ Relay **doc_ids** (stable per friendly-name, rotate rarely):
213
214
  `reaction_status` is `"created"` or `"deleted"`. (Reverse-engineered from the
214
215
  live `comet/CometDirectPageWeb` bundle; the legacy REST reaction endpoint 404s.)
215
216
 
217
+ ### Unsend (delete for everyone)
218
+
219
+ `IGDMessageUnsendDialogOffMsysMutation` (doc_id `26948700068153789`) with
220
+ variables:
221
+
222
+ ```javascript
223
+ { message_id: "<mid.$...>", send_data: { thread_id: "<threadID>" } }
224
+ ```
225
+
226
+ It answers `{ data: { direct_unsend_message: true } }`. The legacy REST delete
227
+ endpoint (`/api/v1/direct_v2/threads/<t>/items/<id>/delete/`) is gone: on
228
+ `www.instagram.com` the whole `/api/v1` namespace returns `not-logged-in` 404,
229
+ and on `i.instagram.com` it needs the mobile app identity. (Reverse-engineered
230
+ from the live `IGDMessageUnsendDialogOffMsys.react` chunk.)
231
+
216
232
  ### Session validation
217
233
 
218
234
  The REST probe endpoints lie (they 302 to login even for healthy sessions), so
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eryxenx/insta-chat",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": " Unofficial Instagram Chat API for Node.js | Build Instagram DM bots on personal accounts \u2014 send messages, media, voice notes, reactions, edit & unsend, listen for incoming chats. No browser at runtime",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "CHANGELOG.md"
24
24
  ],
25
25
  "scripts": {
26
- "test": "node test/smoke.js && node test/antiSuspension.test.js && node test/replyContent.test.js && node test/edit.test.js && node test/sendReply.test.js && node test/client.test.js && node test/relayError.test.js && node test/safetyWiring.test.js && node test/mediaOrder.test.js && node test/sessionSafety.test.js && node test/emptySend.test.js && node test/pollFloor.test.js && node test/unsend.test.js",
26
+ "test": "node test/smoke.js && node test/antiSuspension.test.js && node test/replyContent.test.js && node test/edit.test.js && node test/sendReply.test.js && node test/client.test.js && node test/relayError.test.js && node test/safetyWiring.test.js && node test/mediaOrder.test.js && node test/sessionSafety.test.js && node test/emptySend.test.js && node test/pollFloor.test.js && node test/unsend.test.js && node test/unsendGraphQL.test.js",
27
27
  "build": "node scripts/build.js"
28
28
  },
29
29
  "keywords": [
package/src/constants.js CHANGED
@@ -25,7 +25,8 @@ const DOC_ID = {
25
25
  CUTOUT_STICKER_SEND: "26601474479505807",
26
26
  MARK_THREAD_READ: "27399783383056109",
27
27
  THREAD_DETAIL: "29619996517588618",
28
- INBOX: "27909866362025854"
28
+ INBOX: "27909866362025854",
29
+ UNSEND_MESSAGE: "26948700068153789"
29
30
  };
30
31
 
31
32
  const EP = {
@@ -99,15 +99,24 @@ class MessageMethods {
99
99
  });
100
100
  }
101
101
 
102
- // Instagram's REST delete requires the request to look like the web client's:
103
- // a `_csrftoken` (the csrftoken cookie) and a `_uuid` (the browser/device id).
104
- // An empty body is rejected — Instagram answers with `status: "fail"` (or a
105
- // 404/redirect), which made `unsend` a silent no-op.
102
+ // Unsend (delete for everyone) via the Relay mutation the web DM client uses:
103
+ // `IGDMessageUnsendDialogOffMsysMutation` (doc_id 26948700068153789). The
104
+ // legacy REST delete path (`/direct_v2/threads/<t>/items/<id>/delete/`) is
105
+ // dead on www.instagram.com (the whole /api/v1 namespace 404s) and on
106
+ // i.instagram.com it needs the mobile app identity, so we go straight to
107
+ // GraphQL. Captured live; verified against a real message.
106
108
  async unsend(threadID, itemID) {
107
- const csrf = this.http.getCookie("csrftoken");
108
- const body = { _csrftoken: csrf, _uuid: this.identity?.uuid || this.http.uuid() };
109
- const res = await this.http.postForm(EP.ITEM_DELETE(threadID, itemID), body);
110
- return res?.status === "ok";
109
+ try {
110
+ const res = await this.http.postGraphQL(
111
+ "IGDMessageUnsendDialogOffMsysMutation",
112
+ DOC_ID.UNSEND_MESSAGE,
113
+ { message_id: String(itemID), send_data: { thread_id: String(threadID) } },
114
+ `https://www.instagram.com/direct/t/${threadID}/`
115
+ );
116
+ return Boolean(res && res.data && res.data.direct_unsend_message) && !res.errors;
117
+ } catch (_) {
118
+ return false;
119
+ }
111
120
  }
112
121
 
113
122
  // Instagram lets you edit an outgoing DM within 15 minutes of sending it.