194 lines
7.9 KiB
Markdown
194 lines
7.9 KiB
Markdown
# 🕒 insta-note-clock
|
||
|
||
> **A high-resilience Rust CLI daemon that synchronizes your Instagram Note with a live digital clock at a safe, configurable interval.**
|
||
|
||
---
|
||
|
||
### ⚠️ IMPORTANT LEGAL & TERMS OF SERVICE WARNING
|
||
|
||
> [!CAUTION]
|
||
> **USE AT YOUR OWN RISK.**
|
||
>
|
||
> 1. Instagram / Meta has **no public API** for Notes. This tool interacts directly with Instagram's private Android mobile application endpoints.
|
||
> 2. Automating actions on Instagram directly violates **Section 3.2 of Instagram's Terms of Use** (*"You can't attempt to create accounts or access or collect information in unauthorized ways"* and *"You must not access Instagram's private API by means other than the Instagram app or website"*).
|
||
> 3. Instagram utilizes aggressive automated fraud detection and rate limiting. Frequent Note mutations (e.g., updating every 60 seconds) will almost certainly trigger HTTP 429 errors, action blocks, checkpoint challenges, or **permanent account suspension / ban**.
|
||
> 4. This tool enforces a **minimum safe default of 120 seconds**, a **rolling 30 requests/hour cap**, and **exponential backoff + jitter**. **Never use your primary personal account if you cannot afford to lose it.** Test with a secondary or disposable account first.
|
||
|
||
---
|
||
|
||
## 🏗️ Architecture & Reverse Engineered Endpoints
|
||
|
||
Existing open-source Rust crates were evaluated:
|
||
- `insta-rs`, `qinstagram`: Outdated and predate Instagram Notes (introduced in 2022/2023).
|
||
- `goofy`, `rocketapi`: Unofficial wrapper services or SaaS requiring third-party API keys and recurring subscriptions.
|
||
|
||
Consequently, `insta-note-clock` implements a **native Rust HTTP engine using `reqwest`**, reverse-engineered directly from Instagram's Android client and referenced from the Python `instagrapi` library (`instagrapi.mixins.note`).
|
||
|
||
### Endpoint Specification
|
||
|
||
| Action | HTTP Method & Path | Form Payload | Headers / Cookies |
|
||
| :--- | :--- | :--- | :--- |
|
||
| **Create/Update Note** | `POST https://i.instagram.com/api/v1/notes/create_note` | `signed_body=SIGNATURE.{"note_style":0,"text":"...","_uuid":"...","audience":0}` | `sessionid`, `ds_user_id`, `csrftoken`, `X-IG-App-ID: 936619743392459`, `User-Agent: Android` |
|
||
| **Delete Note** | `POST https://i.instagram.com/api/v1/notes/delete_note/` | `signed_body=SIGNATURE.{"id":"<note_id>","_uuid":"..."}` | Same as above |
|
||
| **Get Notes Tray** | `POST https://i.instagram.com/api/v1/notes/get_notes` | `signed_body=SIGNATURE.{"_uuid":"..."}` | Same as above |
|
||
| **Account Login** | `POST https://i.instagram.com/api/v1/accounts/login/` | `signed_body=SIGNATURE.{"username":"...","enc_password":"#PWD_INSTAGRAM:0:<ts>:<pwd>",...}` | Mobile device headers |
|
||
| **2FA Verification** | `POST https://i.instagram.com/api/v1/accounts/two_factor_login/` | `signed_body=SIGNATURE.{"username":"...","verification_code":"...","two_factor_identifier":"...",...}` | Mobile device headers |
|
||
|
||
> **Note on Atomic Replacement:** Instagram enforces a strict limit of **one active Note per account**. Calling `create_note` automatically replaces any prior note on Instagram's server side without needing an explicit deletion step.
|
||
|
||
---
|
||
|
||
## 🛡️ Safety & Rate Limiting Mechanics
|
||
|
||
- **Default Interval:** 120 seconds (warns visibly if configured lower).
|
||
- **Hourly Budget Cap:** Limits mutations to a rolling maximum of 30 requests/hour by default.
|
||
- **HTTP 429 Backoff:** On receiving rate limit code 429, the daemon pauses for an exponential backoff starting at **5 minutes (300 seconds)** + random jitter (5–30s), retrying up to 3 times before halting.
|
||
- **Immediate Fatal Exit on 401/403:** The daemon never loops or retries authentication failures, preventing credential lockout.
|
||
- **Dry Run Mode:** Test payloads, formatting, and time calculations without making any network requests.
|
||
|
||
---
|
||
|
||
## 📦 Project Structure
|
||
|
||
```
|
||
insta-note-clock/
|
||
├── Cargo.toml # Rust package & dependency definitions
|
||
├── .env.example # Template for environment variable overrides
|
||
├── config.example.toml # Example TOML configuration file
|
||
├── config.toml # Active configuration file
|
||
├── .gitignore # Prevents secrets or session.json from leaking
|
||
├── README.md # Comprehensive documentation
|
||
├── src/
|
||
│ ├── lib.rs # Library root re-exporting core modules
|
||
│ ├── main.rs # CLI entrypoint, argument parsing & daemon loop
|
||
│ ├── client.rs # Instagram private API client, signing & backoff
|
||
│ ├── clock.rs # Timezone parsing & note formatting logic
|
||
│ ├── config.rs # Configuration loading & validation logic
|
||
│ └── session.rs # Session persistence & secure disk storage
|
||
└── tests/
|
||
└── mock_test.rs # WireMock integration tests (zero live API calls)
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 Installation & Building
|
||
|
||
### Prerequisites
|
||
- Rust stable (1.75+) with `cargo`
|
||
|
||
```bash
|
||
git clone <repo-url> insta-note-clock
|
||
cd insta-note-clock
|
||
cargo build --release
|
||
```
|
||
The compiled binary will be located at `target/release/insta-note-clock`.
|
||
|
||
---
|
||
|
||
## ⚙️ Configuration
|
||
|
||
You can configure `insta-note-clock` via `config.toml` or environment variables (prefixed with `INSTA_`).
|
||
|
||
### `config.toml`
|
||
|
||
```toml
|
||
[instagram]
|
||
username = "your_username"
|
||
password = "" # Optional: leave blank for interactive login or session cookies
|
||
session_file = "./session.json"
|
||
timezone = "Asia/Kolkata" # Any valid IANA timezone (e.g., "America/New_York", "UTC")
|
||
|
||
[note]
|
||
interval_seconds = 120 # Minimum recommended: 120 seconds
|
||
time_format = "%H:%M" # strftime format (%H:%M for 24h, %I:%M %p for 12h)
|
||
prefix = "🕒 " # Prefix placed before time
|
||
suffix = "" # Optional suffix (Note limit: 60 chars)
|
||
max_requests_per_hour = 30 # Rolling hourly safety cap
|
||
```
|
||
|
||
---
|
||
|
||
## 🔑 Authentication Guide
|
||
|
||
`insta-note-clock` supports two methods:
|
||
|
||
### Method 1: Direct Session Cookie Import (Recommended ⭐)
|
||
*This is the safest method because it bypasses Instagram's mobile automated login bot detection.*
|
||
|
||
1. Log in to [instagram.com](https://instagram.com) in Chrome, Firefox, or Edge.
|
||
2. Press `F12` to open Developer Tools, go to **Application** (or **Storage**) -> **Cookies** -> `https://www.instagram.com`.
|
||
3. Locate the `sessionid` and `ds_user_id` cookies.
|
||
4. Run:
|
||
```bash
|
||
insta-note-clock login --session-id "YOUR_SESSION_ID" --user-id "YOUR_DS_USER_ID"
|
||
```
|
||
Or launch `insta-note-clock login` and select Option `2`.
|
||
|
||
### Method 2: Interactive Login (with 2FA)
|
||
Run:
|
||
```bash
|
||
insta-note-clock login
|
||
```
|
||
Select option `1`. You will be prompted for your username, password (hidden input), and 2FA SMS / Authenticator verification code if enabled.
|
||
|
||
Once authenticated, your session is securely saved to `session.json` with `0600` permissions and reused on subsequent runs.
|
||
|
||
---
|
||
|
||
## 💻 CLI Usage
|
||
|
||
### 1. Test in Dry-Run Mode (Safe)
|
||
Simulate formatting and verify the request payload without hitting Instagram:
|
||
```bash
|
||
cargo run -- --dry-run once
|
||
```
|
||
|
||
### 2. Update Note Once
|
||
Post a single timestamp Note update and exit:
|
||
```bash
|
||
cargo run -- once
|
||
```
|
||
|
||
### 3. Run Daemon Loop
|
||
Start the clock synchronization daemon:
|
||
```bash
|
||
cargo run -- run
|
||
```
|
||
To exit cleanly, press `Ctrl+C`.
|
||
|
||
---
|
||
|
||
## 📱 Running on Android Tablet Server (Termux)
|
||
|
||
If deploying to your Android tablet server running Termux:
|
||
|
||
1. Install prerequisites in Termux:
|
||
```bash
|
||
pkg update
|
||
pkg install rust binutils openssl
|
||
```
|
||
2. Copy or clone the project into Termux:
|
||
```bash
|
||
cd ~/insta-note-clock
|
||
cargo build --release
|
||
```
|
||
3. Authenticate:
|
||
```bash
|
||
./target/release/insta-note-clock login
|
||
```
|
||
4. Run under `tmux` or `nohup`:
|
||
```bash
|
||
tmux new -s note-clock
|
||
./target/release/insta-note-clock run
|
||
# Detach with Ctrl+B then D
|
||
```
|
||
|
||
---
|
||
|
||
## 🧪 Testing
|
||
|
||
Run unit tests and mocked integration tests:
|
||
```bash
|
||
cargo test
|
||
```
|
||
All integration tests utilize `wiremock` to simulate Instagram's API responses locally without ever sending external network packets.
|