Skip to content

Commit 41afa01

Browse files
committed
Merge remote-tracking branch 'upstream/main'
2 parents b877608 + c8a63ba commit 41afa01

9 files changed

Lines changed: 584 additions & 93 deletions

File tree

README.md

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ docker pull misiektoja/instagram-monitor:latest
3434

3535
### 🔍 Real-time Tracking
3636
- **Profile Activity**: Monitor **new posts, reels** and **stories** in real-time.
37+
- **Private Posts**: Detects **collab posts** leaking from **private accounts** via public collaborators.
3738
- **Audience Insights**: Track changes in **followings** and **followers**.
3839
- **Visual Changes**: Detect updates to **profile pictures** and **visibility** (public/private).
3940
- **Bio Updates**: Stay informed about changes to **user bio**.
@@ -58,6 +59,7 @@ docker pull misiektoja/instagram-monitor:latest
5859
- **Jitter Mode**: Adds human-like delays to HTTP requests.
5960
- **Hour-Range Checking**: Limits activity to specific hours of the day.
6061
- **Account Flexibility**: Works with or without a logged-in Instagram account.
62+
- **Browser TLS Impersonation**: Routes traffic through curl_cffi to mimic a real browser's TLS fingerprint and dodge fingerprint-based blocks.
6163
- **Proxy Support**: Route Instagram and webhook traffic through your own proxy.
6264
- **Privacy Substitutions**: Mask or rename identities across all output, logs and notifications.
6365
- **Block Awareness**: Detects shadowbans and flagged sessions to avoid false alerts.
@@ -112,12 +114,14 @@ docker pull misiektoja/instagram-monitor:latest
112114
* [Skipping Follow Changes](#skipping-follow-changes)
113115
* [Advanced Follower/Following Fetching](#advanced-followerfollowing-fetching)
114116
* [Routing Traffic Through a Proxy](#routing-traffic-through-a-proxy)
117+
* [HTTP Transport Backend](#http-transport-backend)
115118
* [Privacy Substitutions](#privacy-substitutions)
116119
* [Shadowban and Flagged Account Detection](#shadowban-and-flagged-account-detection)
117120
* [Reducing Jitter Log Noise](#reducing-jitter-log-noise)
118121
* [CSV Export](#csv-export)
119122
* [Output Directory](#output-directory)
120123
* [Detection of Changed Profile Pictures](#detection-of-changed-profile-pictures)
124+
* [Detecting Collab Posts on Private Accounts](#detecting-collab-posts-on-private-accounts)
121125
* [Displaying Images in Your Terminal](#displaying-images-in-your-terminal)
122126
* [Check Intervals](#check-intervals)
123127
* [Signal Controls (macOS/Linux/Unix)](#signal-controls-macoslinuxunix)
@@ -136,7 +140,7 @@ Choose one runtime path:
136140

137141
* **Python path**:
138142
* [Python](https://www.python.org/downloads/) 3.9 or higher
139-
* Libraries: [instaloader](https://github.com/instaloader/instaloader), `requests`, `python-dateutil`, `pytz`, `tzlocal`, `python-dotenv`, `tqdm`, `rich` (for Terminal Dashboard), `flask` (for Web Dashboard)
143+
* Libraries: [instaloader](https://github.com/instaloader/instaloader), `requests`, [curl_cffi](https://github.com/lexiforest/curl_cffi) (for browser TLS impersonation), `python-dateutil`, `pytz`, `tzlocal`, `python-dotenv`, `tqdm`, `rich` (for Terminal Dashboard), `flask` (for Web Dashboard)
140144
* **Container path** (Python is not required on host):
141145
* Any Docker-compatible runtime such as:
142146
* [Docker Desktop](https://docs.docker.com/get-started/get-docker/) (macOS, Windows, Linux)
@@ -315,6 +319,8 @@ instaloader -l <your_insta_user>
315319

316320
This saves the session locally. However, frequent follower/following/stories changes can still lead to detection, as Instagram may flag this as automated behavior.
317321

322+
For device consistency, set `USER_AGENT` to match Instaloader's Chrome user agent (see [User Agent](#user-agent) below).
323+
318324
<a id="option-3-session-login-using-firefox-cookies-recommended"></a>
319325
#### Option 3: Session Login Using Firefox Cookies (recommended)
320326

@@ -348,6 +354,14 @@ It is also recommended to use the exact user agent string from your Firefox web
348354
- find the `User Agent` value under the `Application Basics` section and copy it
349355
- set this value via the `USER_AGENT` configuration option or by using the `--user-agent` flag (since **v3.0**, you can also do it easily via the **[Web Dashboard](#web-dashboard-mode)**)
350356

357+
If you created the session with Instaloader instead (Option 2 above), match Instaloader's user agent rather than Firefox's. Instaloader logs in with a Chrome user agent, so set `USER_AGENT` to a matching Chrome string to keep the same device consistency. You can print the exact value Instaloader uses with:
358+
359+
```sh
360+
python3 -c "from instaloader.instaloadercontext import default_user_agent; print(default_user_agent())"
361+
```
362+
363+
With the default `auto` impersonation (see [HTTP Transport Backend](#http-transport-backend)) the curl_cffi TLS fingerprint follows whichever user agent you set, so a Chrome user agent here yields a Chrome TLS fingerprint.
364+
351365
<a id="time-zone"></a>
352366
### Time Zone
353367

@@ -883,6 +897,31 @@ PROXY_WEBHOOKS = False
883897

884898
**Note**: Even when `PROXY_ENABLED` is `False`, the underlying `requests` library still honors the `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY` environment variables. If those are set in your shell or service unit they are applied silently, so unset them if you want a guaranteed direct connection.
885899

900+
<a id="http-transport-backend"></a>
901+
### HTTP Transport Backend
902+
903+
All Instagram traffic flows through a configurable HTTP transport backend:
904+
905+
- `curl_cffi` (default): sends requests via [curl_cffi](https://github.com/lexiforest/curl_cffi), impersonating a real browser's TLS (JA3/JA4) and HTTP/2 fingerprint. This avoids fingerprint-based blocks where Instagram returns a spurious `HTTP 429` on the very first request even from a clean IP, a pattern most often seen on Linux builds (including Raspberry Pi OS) whose system TLS stack presents a fingerprint Instagram treats as automation.
906+
- `requests`: the stock `requests` / `urllib3` transport using the system TLS stack (the historical behavior).
907+
908+
Both the anonymous and logged-in paths use the selected backend. If `curl_cffi` is selected but not installed, the tool prints a warning and transparently falls back to `requests`.
909+
910+
Select the backend with `HTTP_BACKEND` (or `--http-backend`) and choose which browser curl_cffi impersonates with `CURL_CFFI_IMPERSONATE` (or `--impersonate`):
911+
912+
```ini
913+
HTTP_BACKEND = "curl_cffi"
914+
CURL_CFFI_IMPERSONATE = "auto"
915+
```
916+
917+
`CURL_CFFI_IMPERSONATE` defaults to `auto`, which picks the impersonation target that matches your `USER_AGENT` so the TLS, HTTP/2 and client-hint headers stay consistent with the browser identity. This matters when you import a Firefox session and set a matching Firefox `USER_AGENT`: `auto` then presents a Firefox TLS fingerprint instead of pairing a Firefox user agent with Chrome client-hint headers. You can also pin a specific target such as `chrome`, `safari`, `safari_ios`, `edge` or `firefox`:
918+
919+
```sh
920+
instagram_monitor <target_insta_user> --http-backend curl_cffi --impersonate firefox
921+
```
922+
923+
See the [curl_cffi documentation](https://github.com/lexiforest/curl_cffi) for the full list of impersonation targets available in your installed version.
924+
886925
<a id="privacy-substitutions"></a>
887926
### Privacy Substitutions
888927

@@ -1013,6 +1052,25 @@ To enable this:
10131052

10141053
Without this file, the tool will treat an empty profile picture as a regular image. For example, if a user removes their profile picture, it would be treated as a change rather than a removal.
10151054

1055+
<a id="detecting-collab-posts-on-private-accounts"></a>
1056+
### Detecting Collab Posts on Private Accounts
1057+
1058+
Instagram's collaboration feature lets two accounts co-author a single post. When a **private** account co-authors a post with a **public** account, that post stays visible on the private account's profile through the public `web_profile_info` endpoint even though the rest of the account is hidden. The tool surfaces these otherwise hidden posts.
1059+
1060+
This feature is enabled by default. To disable it, either:
1061+
1062+
- set the `DETECT_COLLAB_POSTS` to `False`
1063+
- or use the `--no-detect-collab-posts` flag
1064+
1065+
<a id="collab-posts-how-it-works"></a>
1066+
#### How It Works
1067+
1068+
The probe runs only for accounts whose posts are not otherwise viewable, meaning private profiles you do not follow.
1069+
1070+
On the first run the tool displays the newest collab post currently visible, the same way it shows a regular account's latest post and records a baseline so it does not re-alert on the ones already there. On later checks, when the account's post or reel count changes, it looks for newly leaked collab posts and reports each one with its date, owner, collaborators, likes, comments, caption and media through the console, email and webhook notifications. Media is saved like any other post.
1071+
1072+
This was inspired by [InstagramPrivSniffer](https://github.com/obitouka/InstagramPrivSniffer). Meta has confirmed that this visibility is intended behavior of the [collaboration feature](https://help.instagram.com/3526836317546926) rather than a vulnerability. Use it only for legitimate research and investigation.
1073+
10161074
<a id="displaying-images-in-your-terminal"></a>
10171075
### Displaying Images in Your Terminal
10181076

RELEASE_NOTES.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# instagram_monitor release notes
22

3+
# Changes in 3.4 (16 Jun 2026)
4+
5+
**Features and Improvements**:
6+
7+
- **NEW:** Added a **pluggable HTTP transport backend** with browser TLS (JA3/JA4) impersonation via [curl_cffi](https://github.com/lexiforest/curl_cffi), now the default, to avoid fingerprint-based blocks where Instagram returns a spurious `HTTP 429` on the very first request even from a clean IP (most often on Linux OS TLS stacks whose fingerprint Instagram treats as automation). Both the anonymous and logged-in paths use the selected backend and it transparently falls back to `requests` when curl_cffi is unavailable. Configurable via the `HTTP_BACKEND` / `CURL_CFFI_IMPERSONATE` config options or the `--http-backend` / `--impersonate` flags, with `CURL_CFFI_IMPERSONATE` defaulting to `auto` so the impersonated browser is aligned with the configured user agent, keeping the TLS and client-hint headers consistent (including with a Firefox-imported session)
8+
- **NEW:** Added **detection of leaked collab posts on private accounts** (enabled by default). When a private account co-authors a post with a public account, that post stays visible in the private account's timeline media via the public `web_profile_info` endpoint. The monitor surfaces these otherwise hidden posts (with owner, collaborators, media download and notifications) and reports new ones over time, even for accounts you do not follow. Only probes accounts whose posts are not otherwise viewable. Disable via the `DETECT_COLLAB_POSTS` config option or the `--no-detect-collab-posts` flag. Inspired by [InstagramPrivSniffer](https://github.com/obitouka/InstagramPrivSniffer)
9+
- **IMPROVE:** The anonymous post path now populates **tagged users and co-authors** from `web_profile_info` instead of leaving the list empty
10+
- **IMPROVE:** Centralized repeated timestamp label and newline handling in `print_cur_ts()` (thanks [@tomballgithub](https://github.com/tomballgithub), from [#100](https://github.com/misiektoja/instagram_monitor/pull/100))
11+
- **IMPROVE:** Added Jinja2 as a direct dependency for Web Dashboard template rendering
12+
13+
**Bug fixes**:
14+
15+
- **BUGFIX:** Fixed the configured proxy and TLS certificate settings being dropped on the anonymous mobile profile lookup (`web_profile_info`), which caused that request to bypass the proxy and go out over the real IP
16+
- **BUGFIX:** Restored the progress bar unit label after paused follower/following batch waits so later progress output keeps the expected label (thanks [@tomballgithub](https://github.com/tomballgithub), from [#103](https://github.com/misiektoja/instagram_monitor/pull/103))
17+
- **BUGFIX:** Fixed **flagged-account detection** not sending email or webhook alerts. The notification was gated behind `ERROR_FAILURE_THRESHOLD` so the script terminated before the count was reached. A flagged session or IP now alerts the operator immediately, bypassing the threshold and de-duped so one shared flag alerts once across all monitored targets (fixes [#108](https://github.com/misiektoja/instagram_monitor/issues/108))
18+
319
# Changes in 3.3 (01 Jun 2026)
420

521
Huge thanks to everyone who contributed to this release, with a special shout-out to [@tomballgithub](https://github.com/tomballgithub) who drove most of the work behind these changes and to [@BlueXAyman](https://github.com/BlueXAyman) for the Instaloader GraphQL profile metadata patch.

0 commit comments

Comments
 (0)