@eryxenx/insta-chat 2.0.5 → 2.0.7
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 +26 -0
- package/DOCS.md +5 -2
- package/package.json +2 -2
- package/src/api/messaging/unsendMessage.js +7 -3
- package/src/api.js +3 -1
- package/src/app/InstaContext.js +1 -1
- package/src/events/normalizeEvent.js +6 -0
- package/src/methods/inbox.js +7 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,32 @@ 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.7] - 2026-10-11
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **`unsendMessage` silently failed for a message the bot did not send in this
|
|
12
|
+
process.** The thread of the id being unsent was resolved only from the
|
|
13
|
+
in-memory `messageID -> threadID` map, so unsending a message sent before a
|
|
14
|
+
restart (or a reply to someone else's message) threw `Unknown thread for
|
|
15
|
+
message` internally and returned `false` — `/unsend` appeared to do nothing.
|
|
16
|
+
`unsendMessage(messageID, callback?, threadID?)` now accepts the thread
|
|
17
|
+
explicitly, and the normalizer remembers the replied-to message id (whose
|
|
18
|
+
thread is known) so the map lookup succeeds. The thread the message was seen
|
|
19
|
+
in is always a safe explicit value for `/unsend`.
|
|
20
|
+
|
|
21
|
+
## [2.0.6] - 2026-10-10
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- **Configurable poll floor.** `new InstaAPI(cookie, { minPollIntervalMs })` (and
|
|
26
|
+
the same option on `InstaClient`) sets the lowest interval `listen()` will
|
|
27
|
+
honour, defaulting to 15000 ms as before with a hard 2000 ms minimum.
|
|
28
|
+
Instagram has no DM push, so reply latency is one poll cycle; operators on a
|
|
29
|
+
residential/mobile proxy can lower it (e.g. 2000) for snappier replies.
|
|
30
|
+
`api.listen(cb, interval)` still cannot go below this floor, so the bot can no
|
|
31
|
+
longer pass an interval the package silently raises.
|
|
32
|
+
|
|
7
33
|
## [2.0.5] - 2026-10-10
|
|
8
34
|
|
|
9
35
|
### Fixed
|
package/DOCS.md
CHANGED
|
@@ -48,6 +48,7 @@ commands call). Pass `{ native: true }` to get the bare `InstaAPI` instead.
|
|
|
48
48
|
| `sessionParamsFile` | `./session-params.json` | Load params from disk. |
|
|
49
49
|
| `deviceFile` | `./device.json` | Persisted device identity. |
|
|
50
50
|
| `pollInterval` | `15000` | `listen()` poll interval (ms). |
|
|
51
|
+
| `minPollIntervalMs` | `15000` | Lowest interval `listen()` will honour (floor, min 2000). |
|
|
51
52
|
|
|
52
53
|
## `InstaClient` (FCA surface)
|
|
53
54
|
|
|
@@ -57,7 +58,7 @@ Facebook-Chat-API shape. Its methods live one-per-file under
|
|
|
57
58
|
|
|
58
59
|
| Group | Methods |
|
|
59
60
|
|-------|---------|
|
|
60
|
-
| messaging | `sendMessage(form, threadID, cb?, replyToMessage?)`, `sendMessageSync`, `editMessage(text, messageID)`, `unsendMessage(messageID)`, `setMessageReaction(emoji, messageID, cb?, threadID?)`, `sendTypingIndicator`, `markAsRead`, `shareContact`, `resolvePhotoUrl` |
|
|
61
|
+
| messaging | `sendMessage(form, threadID, cb?, replyToMessage?)`, `sendMessageSync`, `editMessage(text, messageID)`, `unsendMessage(messageID, cb?, threadID?)`, `setMessageReaction(emoji, messageID, cb?, threadID?)`, `sendTypingIndicator`, `markAsRead`, `shareContact`, `resolvePhotoUrl` |
|
|
61
62
|
| threads | `getThreadInfo`, `getThreadList`, `getThreadHistory` |
|
|
62
63
|
| users | `getUserInfo`, `getUID`, `getProfilePictureUrl` |
|
|
63
64
|
| account | `getCurrentUserID`, `getAppState`, `getCookies`, `setOptions` |
|
|
@@ -140,7 +141,9 @@ All take `(threadID, source, options)` where `options = { filename, text }`.
|
|
|
140
141
|
|
|
141
142
|
`getInbox()` returns `{ threads }`. `listen(callback, intervalMs)` polls and
|
|
142
143
|
emits normalized `message` events; it returns a `stop()` function.
|
|
143
|
-
`stopListening()` also stops polling.
|
|
144
|
+
`stopListening()` also stops polling. The interval is raised to the client's
|
|
145
|
+
`minPollIntervalMs` floor (set via the constructor options; default 15000 ms,
|
|
146
|
+
minimum 2000 ms), so pass that option if you want a shorter cycle than 15 s.
|
|
144
147
|
|
|
145
148
|
### Event shape
|
|
146
149
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eryxenx/insta-chat",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.7",
|
|
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",
|
|
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",
|
|
27
27
|
"build": "node scripts/build.js"
|
|
28
28
|
},
|
|
29
29
|
"keywords": [
|
|
@@ -5,12 +5,16 @@
|
|
|
5
5
|
* Original author credit must be retained in all copies and derivatives.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
// fca.unsendMessage(messageID) — the thread
|
|
8
|
+
// fca.unsendMessage(messageID, callback, threadID) — the thread may be passed
|
|
9
|
+
// explicitly; otherwise it is resolved from the id. A bot that only knows the
|
|
10
|
+
// replied-to message id (it did not send that message in this process, e.g.
|
|
11
|
+
// after a restart) cannot resolve the thread, so the explicit thread is what
|
|
12
|
+
// makes /unsend work reliably.
|
|
9
13
|
module.exports = function (client) {
|
|
10
|
-
return async function unsendMessage(messageID, callback) {
|
|
14
|
+
return async function unsendMessage(messageID, callback, threadID) {
|
|
11
15
|
const cb = typeof callback === "function" ? callback : null;
|
|
12
16
|
try {
|
|
13
|
-
const tid = client._resolveThread(messageID);
|
|
17
|
+
const tid = client._resolveThread(messageID, threadID);
|
|
14
18
|
const ok = await client.api.unsendMessage(tid, String(messageID));
|
|
15
19
|
if (cb) cb(null, ok);
|
|
16
20
|
return ok;
|
package/src/api.js
CHANGED
|
@@ -48,7 +48,9 @@ class InstaAPI {
|
|
|
48
48
|
this.typing = new TypingMethods(this.http);
|
|
49
49
|
this.thread = new ThreadMethods(this.http);
|
|
50
50
|
this.user = new UserMethods(this.http);
|
|
51
|
-
this.inbox = new InboxMethods(this.http, () => this.userID
|
|
51
|
+
this.inbox = new InboxMethods(this.http, () => this.userID, {
|
|
52
|
+
minPollIntervalMs: options.minPollIntervalMs
|
|
53
|
+
});
|
|
52
54
|
this.media = new MediaMethods(this.http, this.identity);
|
|
53
55
|
}
|
|
54
56
|
|
package/src/app/InstaContext.js
CHANGED
|
@@ -139,6 +139,12 @@ class EventNormalizer {
|
|
|
139
139
|
// client must know which thread it belongs to.
|
|
140
140
|
if (typeof this.client.rememberThread === "function") {
|
|
141
141
|
this.client.rememberThread(event.messageID, threadID);
|
|
142
|
+
// Remember the replied-to message too: /unsend resolves its thread from
|
|
143
|
+
// that id, and the bot may be unssending a message it sent in an earlier
|
|
144
|
+
// process (so it is not in _msgThread otherwise).
|
|
145
|
+
if (event.messageReply && event.messageReply.messageID) {
|
|
146
|
+
this.client.rememberThread(event.messageReply.messageID, threadID);
|
|
147
|
+
}
|
|
142
148
|
}
|
|
143
149
|
|
|
144
150
|
return event;
|
package/src/methods/inbox.js
CHANGED
|
@@ -24,9 +24,14 @@ const INBOX_VARIABLES = {
|
|
|
24
24
|
const SKIP_TYPES = new Set(["like", "action_log", "video_call_event", "reaction_log"]);
|
|
25
25
|
|
|
26
26
|
class InboxMethods {
|
|
27
|
-
constructor(http, getUserID) {
|
|
27
|
+
constructor(http, getUserID, options = {}) {
|
|
28
28
|
this.http = http;
|
|
29
29
|
this.getUserID = getUserID;
|
|
30
|
+
// Lowest poll interval listen() will honour, in ms. Instagram has no DM
|
|
31
|
+
// push, so reply latency is bounded by one poll cycle. The 15000 default is
|
|
32
|
+
// the conservative safe floor for a personal account; operators on a
|
|
33
|
+
// residential/mobile proxy can lower it (e.g. 2000) for snappier replies.
|
|
34
|
+
this.minPollIntervalMs = Math.max(2000, Number(options.minPollIntervalMs) || 15000);
|
|
30
35
|
this._seen = new Map();
|
|
31
36
|
this._pollTimer = null;
|
|
32
37
|
this._selfFbid = null;
|
|
@@ -309,7 +314,7 @@ class InboxMethods {
|
|
|
309
314
|
}
|
|
310
315
|
|
|
311
316
|
listen(callback, intervalMs = 20000) {
|
|
312
|
-
const MIN_INTERVAL_MS =
|
|
317
|
+
const MIN_INTERVAL_MS = this.minPollIntervalMs;
|
|
313
318
|
const BASE_INTERVAL_MS = Math.max(Number(intervalMs) || 20000, MIN_INTERVAL_MS);
|
|
314
319
|
const BACKOFF_START_MS = 30000;
|
|
315
320
|
const BACKOFF_MAX_MS = 10 * 60 * 1000;
|