Instagram CLI

repository·main·Indexed 24 days ago

https://github.com/supreme-gg-gg/instagram-cli

An unofficial, lightweight terminal client for Instagram featuring a TUI for human interaction and non-interactive 'one-turn' commands for AI agents and scripting. Available as a TypeScript package (@i7m/instagram-cli) and a legacy Python client. Key features include keyboard-driven navigation, LaTeX rendering in chats, LLM-powered chat summarization via OpenAI-compatible servers, and scheduled messaging.

Tokens
18.5K
Snippets
40
Records
118
Agent score
84%

What's inside instagram-cli

  1. Resolve threads using IDs, usernames, or titles

    main

    Commands that target a specific conversation (e.g., send, read, reply, unsend) accept a <thread> argument. The CLI resolves this argument using the following priority order:

    1. Thread ID: A 20+ digit number (e.g., 340282366920938463...). This is the most reliable method.
    2. Username: An exact Instagram username (e.g., johndoe).
    3. Thread title: A fuzzy search across the inbox (e.g., "Book Club").

    Best Practice: For reliable automation, call inbox --output json first to retrieve the exact id for a thread, then use that ID in subsequent commands to avoid resolution errors.

  2. Understand the Instagram CLI login workflow

    main

    The Instagram CLI uses a multi-stage authentication process that transitions between different states based on the requirements of the Instagram API. The workflow typically follows these stages:

    1. Session Login (Default): The CLI first attempts to restore a session using saved data. If successful, login is complete. If the session requires 2FA or a challenge, the CLI prompts for those specifically. If the session is invalid or missing, it falls back to the manual login form.
    2. Manual Login: Triggered if no session exists or if the --username flag is provided. The user enters credentials, and the CLI calls login(username, password).
    3. Two-Factor Authentication (2FA): If the API requires 2FA, the CLI prompts for a code (TOTP or SMS) and calls twoFactorLogin().
    4. Challenge Verification: If a security challenge is triggered, the CLI initiates the flow via startChallenge() and submits the verification code via sendChallengeCode(code).

    Login States:

    • session: Attempting login with saved session data.
    • form: Username/password input.
    • 2fa: Two-factor authentication code input.
    • challenge: Challenge verification code input.
    • success: Login completed.
    • error: Login failed.
  3. How Stories UI and data flow work

    main

    The Stories feature uses a centralized, hook-based architecture to manage data fetching and state. The system follows a unidirectional data flow where a central hook manages the InstagramClient and state, while presentational components handle rendering and user input.

    UI Layout

    The viewer uses a two-panel layout:

    1. Left Panel (Users List): A vertical list of users with active stories. The currently selected user is highlighted, and users whose stories have been viewed in the current session are dimmed.
    2. Right Panel (Media Display): Displays the current story's media (image or video placeholder), metadata (username, timestamp, caption), and position (e.g., "Story 2 of 5").

    Data Flow Model

    1. useStories Hook: The central logic engine. It initializes the InstagramClient, fetches the initial reelsTray, manages loading/error states, and provides a loadMore(index) function.
    2. Stories Command: The entry point that invokes the hook and passes state to the view.
    3. StoryView: A container providing context (like InkPictureProvider).
    4. StoryDisplay: A presentational component that renders the UI and triggers actions (like loadMore or markStoryAsSeen) based on user interaction.
    graph TD
        subgraph "UI Layer (Components)"
            A[Stories Command] --> B(useStories Hook);
            B --> C{StoryDisplay};
        end
    
        subgraph "Logic & Data Layer"
            B --> D[client.getReelsTray()];
            B -- "loadMore(index)" --> E[client.getStoriesForUser(id)];
            C -- "mark as seen" --> F[client.markStoryAsSeen(stories)];
        end
    
        subgraph "Instagram API"
            D --> G[API];
            E --> G;
            F --> G;
        end
    
        C -- "User navigates to new reel" --> B;
    
        style B fill:#f9f,stroke:#333,stroke-width:2px
  4. Understand the TypeScript project structure

    main

    The TypeScript codebase is organized as follows:

    • source/cli.ts: Main CLI entry point (using meow).
    • source/client.ts: Unified Instagram API client containing all IG logic.
    • source/config.ts: YAML-based configuration management.
    • source/session.ts: Session serialization and management.
    • source/commands/: Directory containing individual CLI commands (e.g., auth/, chat.tsx, config.tsx).
    • source/ui/: UI layer built with ink:
      • components/: Stateless, reusable Ink components.
      • views/: Top-level stateful views.
      • hooks/: Custom React hooks (e.g., useClient).
      • context/: React context providers.
    • source/types/: TypeScript type definitions (instagram.ts, ui.ts).
  5. Understand the Instagram CLI Chat UI architecture

    main

    The Chat UI is built around two distinct, non-overlapping views: the Thread List View and the Chat View.

    • Thread List View: Used for navigating between different conversations. It displays a paginated list of threads. Navigation is handled via j/k or arrow keys, with Enter to select a thread.
    • Chat View: Used for reading and sending messages within a specific thread. It features a message list, an input box for messages/commands, and a status bar. Navigation uses j/k for scrolling and Esc to return to the thread list.

    Transitions between these views are complete replacements: entering a chat clears the thread list and loads messages, while exiting a chat clears the chat view and resets the state to show the thread list again.

    /* View Hierarchy Concept */
    
    // THREAD LIST VIEW
    ┌─────────────────────────────────────┐
    │ Status Bar (current view, username) │
    ├─────────────────────────────────────┤
    │  THREAD LIST VIEW                   │
    │  ┌─────────────────────────────────┐ │
    │  │ Thread 1 [selected]             │ │
    │  │ Thread 2                        │ │
    │  └─────────────────────────────────┘ │
    ├─────────────────────────────────────┤
    │ Help: j/k navigate, Enter select    │
    └─────────────────────────────────────┘
    
    // CHAT VIEW
    ┌─────────────────────────────────────┐
    │ Status Bar (chat view, thread name) │
    ├─────────────────────────────────────┤
    │  CHAT VIEW                          │
    │  ┌─────────────────────────────────┐ │
    │  │ [Message 1]                     │ │
    │  │ [Message 2]                     │ │
    │  └─────────────────────────────────┘ │
    │  ┌─────────────────────────────────┐ │
    │  │ Message: [input field]          │ │
    │  └─────────────────────────────────┘ │
    ├─────────────────────────────────────┤
    │ Help: Esc back, j/k scroll          │
    └─────────────────────────────────────┘
  6. Understand Action Handling and Fallbacks

    main

    The InstagramClient optimizes actions based on the current connection state.

    Text Messages (sendMessage()):

    • Priority: If realtimeStatus is 'connected', the client uses realtime.direct.sendText() for high-speed delivery via MQTT.
    • Fallback: If MQTT fails or is disconnected, the client falls back to the Web API using ig.entity.directThread().broadcastText().

    Media and Other Actions:

    • Because the MQTT client currently only supports text, all other direct chat actions (such as sending media) are handled exclusively via the Web API.
  7. Understand the Log File format and contexts

    main

    Log entries follow a structured format to assist in debugging:

    Format: [Timestamp] [Log Level] [Context]: [Message] (plus stack trace for errors).

    Log Contexts:

    • Application logs: Named after modules/functions (e.g., [InstagramClient], [SessionManager], [LoginCommand]).
    • API logs: Uses the context [ig-api] for all network requests captured from the instagram-private-api library.
    2025-10-18T14:30:45.123Z INFO [Logger]: Logger initialized
    2025-10-18T14:30:45.234Z INFO [useInstagramClient]: Initializing Instagram client
    2025-10-18T14:30:45.345Z DEBUG [ig-api]: ig:http POST https://i.instagram.com/api/v1/direct_v2/threads/
    2025-10-18T14:30:45.456Z ERROR [InstagramClient]: Failed to fetch threads
    Error: Network timeout
        at InstagramClient.getThreads
        ...
  8. Understand the Mouse Support Architecture

    main

    Since the underlying Ink framework is keyboard-only, the Instagram CLI implements a custom mouse system using ANSI escape sequences and Yoga layout measurement.

    Input Pipeline

    1. Terminal (stdin): Receives raw input.
    2. MouseProvider: An ANSI parser that converts raw input into mouse events.
    3. useMouse() subscribers: A priority-ordered list of subscribers.
    4. Component handlers: Specific components (like ScrollView, InputBox, or ThreadList) that consume the events.

    Key Files

    • source/utils/mouse.ts: Low-level ANSI mouse protocol parser (SGR + X11 formats).
    • source/ui/context/mouse-context.tsx: Provides the MouseProvider context and the useMouse() hook.
    • source/ui/hooks/use-content-size.ts: Contains layout utilities for hit-testing.
  9. How the Hybrid Instagram Client works

    main

    The InstagramClient uses a hybrid architecture combining instagram_mqtt for real-time Direct Message (DM) operations and the instagram-private-api Web API as a fallback.

    This design provides:

    1. Low Latency: When MQTT is connected, real-time updates and text messages are handled via MQTT.
    2. Reliability: If MQTT is disconnected or a specific action (like sending media) is not supported by MQTT, the client falls back to the Web API.

    Key properties of the InstagramClient include:

    • ig: An IgApiClientExt instance used for Web API calls.
    • realtime: A RealtimeClient instance for MQTT (initialized after login).
    • realtimeStatus: A state tracker with values 'disconnected' | 'connecting' | 'connected' | 'error'.
  10. Design Principles for Mouse Support

    main

    When building or extending components with mouse support, follow these principles:

    1. Component Ownership: Components should own their own mouse behavior via useMouse(). Avoid parent-level coordinate math or threading mouse state through props.
    2. Yoga Layout Integration: Always use the existing Yoga layout data for hit-testing. Do not use shadow layouts or hardcoded offsets.
    3. Event Consumption: The useMouse hook uses a priority system. Handlers should return true to consume an event, which prevents lower-priority handlers from processing the same event (e.g., preventing a ScrollView click from also triggering an InputBox action).