Context
aiograpi 0.9.x exposes a much broader Instagram private API surface than insto currently wraps: Direct inbox/thread APIs, saved collections/feed APIs, and newer private GraphQL helpers.
insto should keep the product boundary read-oriented and OSINT-focused. This issue tracks exposing the safe read-only subset through the CLI while explicitly excluding account automation/write operations.
Related docs PR: #3
Scope
Phase 1: read-only Direct inbox
Add CLI support for:
- Listing Direct threads for the authenticated aiograpi account.
- Showing recent messages from one Direct thread.
- Searching/filtering threads by participant username/display name where the SDK surface supports it cleanly.
Non-goals for Phase 1:
- No send-message command.
- No reactions, unsend, mute, title update, upload, voice/video attachment write flows.
- No background inbox polling or notifications.
Phase 2: saved collections / personal feed audit
Before adding commands, verify on a burner account that aiograpi collection/feed calls are stable enough for a CLI contract.
Expected outcomes:
- Either add read-only saved/collection commands with fixtures and docs.
- Or document why the surface is unstable and leave it out of the command list.
Phase 3: private GraphQL pagination audit
Compare current followers/following/media code paths against aiograpi's newer private GraphQL helpers.
Expected outcomes:
- Keep existing methods if behavior/risk is not clearly better.
- Switch only after fixture diffs and small-limit live-smoke checks show equal or better stability.
Proposed implementation plan
1. Add Direct DTOs and backend contract
Files likely involved:
insto/models.py
insto/backends/_base.py
insto/backends/_fake.py
tests/test_models.py
tests/test_backend_contract.py
Add dataclasses such as:
DirectThread: thread id, title, participants, last activity timestamp, unread count, muted/archived flags if available.
DirectMessage: message id, thread id, sender, timestamp, item type, text, media/post refs if available.
Backend methods should be optional defaults on OSINTBackend, not new abstract methods, so HikerAPI does not need a fake Direct implementation:
iter_direct_threads(limit: int | None = None)
iter_direct_messages(thread_id: str, *, limit: int | None = None)
Hiker/default behavior should fail with a clear typed backend error instead of a raw NotImplementedError leaking to users.
2. Map aiograpi Direct payloads
Files likely involved:
insto/backends/aiograpi.py
insto/backends/_aiograpi_map.py
tests/test_aiograpi_map.py
Requirements:
- Lazy login stays unchanged.
- Map SDK-specific exceptions into
insto.exceptions taxonomy.
- Do not log message bodies, credentials, session cookies, or raw Direct payloads.
- Preserve enough identifiers for OSINT export while avoiding accidental write-capable raw SDK objects above the backend layer.
3. Add command module for read-only Direct
Files likely involved:
insto/commands/direct.py
insto/commands/__init__.py
tests/test_commands_direct.py
Candidate commands:
/direct [limit]: list recent threads.
/direct-thread <thread_id> [limit]: show recent messages for one thread.
Command behavior:
- Mark commands as requiring the logged-in aiograpi capability.
- Render concise tables in REPL/one-shot mode.
- Support
--json; reject --csv initially unless the schema is deliberately flattened.
- Keep output redaction consistent with existing command/export patterns.
4. Add tests without live Instagram dependency
Minimum test coverage:
- DTO round-trip/export shape.
- aiograpi mapper fixtures for representative text, media, shared-post, and empty-message cases.
- Command rendering for
/direct and /direct-thread using FakeBackend.
- JSON export path and
--json - stdout behavior.
- Hiker/default backend gives a clean unsupported-backend message.
- CSV rejection message if CSV is intentionally out of scope.
Live tests should remain opt-in only under tests/live/, using a burner account and small limits.
5. Update docs
Files likely involved:
docs/cli-reference.md
docs/backends.md
docs/roadmap.md
README.md if the public command list changes.
Docs must state:
- Direct support is read-only.
- It requires
insto[aiograpi] and a real logged-in Instagram account.
- Account-ban risk applies.
- No Direct write operations are exposed.
Acceptance criteria
/direct and /direct-thread work with aiograpi in one-shot and REPL dispatch.
- Unsupported backends fail with a clear user-facing message.
- JSON export works for Direct data.
- No Direct write operations are exposed in CLI, facade, or docs.
- Unit tests pass without network access.
- Docs build with
mkdocs build --strict.
Context
aiograpi0.9.x exposes a much broader Instagram private API surface thaninstocurrently wraps: Direct inbox/thread APIs, saved collections/feed APIs, and newer private GraphQL helpers.instoshould keep the product boundary read-oriented and OSINT-focused. This issue tracks exposing the safe read-only subset through the CLI while explicitly excluding account automation/write operations.Related docs PR: #3
Scope
Phase 1: read-only Direct inbox
Add CLI support for:
Non-goals for Phase 1:
Phase 2: saved collections / personal feed audit
Before adding commands, verify on a burner account that aiograpi collection/feed calls are stable enough for a CLI contract.
Expected outcomes:
Phase 3: private GraphQL pagination audit
Compare current followers/following/media code paths against aiograpi's newer private GraphQL helpers.
Expected outcomes:
Proposed implementation plan
1. Add Direct DTOs and backend contract
Files likely involved:
insto/models.pyinsto/backends/_base.pyinsto/backends/_fake.pytests/test_models.pytests/test_backend_contract.pyAdd dataclasses such as:
DirectThread: thread id, title, participants, last activity timestamp, unread count, muted/archived flags if available.DirectMessage: message id, thread id, sender, timestamp, item type, text, media/post refs if available.Backend methods should be optional defaults on
OSINTBackend, not new abstract methods, so HikerAPI does not need a fake Direct implementation:iter_direct_threads(limit: int | None = None)iter_direct_messages(thread_id: str, *, limit: int | None = None)Hiker/default behavior should fail with a clear typed backend error instead of a raw
NotImplementedErrorleaking to users.2. Map aiograpi Direct payloads
Files likely involved:
insto/backends/aiograpi.pyinsto/backends/_aiograpi_map.pytests/test_aiograpi_map.pyRequirements:
insto.exceptionstaxonomy.3. Add command module for read-only Direct
Files likely involved:
insto/commands/direct.pyinsto/commands/__init__.pytests/test_commands_direct.pyCandidate commands:
/direct [limit]: list recent threads./direct-thread <thread_id> [limit]: show recent messages for one thread.Command behavior:
--json; reject--csvinitially unless the schema is deliberately flattened.4. Add tests without live Instagram dependency
Minimum test coverage:
/directand/direct-threadusingFakeBackend.--json -stdout behavior.Live tests should remain opt-in only under
tests/live/, using a burner account and small limits.5. Update docs
Files likely involved:
docs/cli-reference.mddocs/backends.mddocs/roadmap.mdREADME.mdif the public command list changes.Docs must state:
insto[aiograpi]and a real logged-in Instagram account.Acceptance criteria
/directand/direct-threadwork with aiograpi in one-shot and REPL dispatch.mkdocs build --strict.