Skip to main content

Sync Instagram saved event posts to calendar exports.

Project description

InstaCalendar logo

Instacalendar

Scenario: you're like me and save lots of gigs and events in Instagram. Then you forget about them. Life's busy and it's hard to keep track of all those fun events without aligning them with your boring, grown-up calendar. Meet Instacalendar: seamlessly sync an entire Instragram saved post collection to your Google (or other) calendar. Keep track of those events, plan better, go out and explore!

instacalendar is a command-line wizard that reads an Instagram saved posts collection, asks OpenRouter models through LiteLLM to infer calendar events, lets you review each candidate event, and exports approved events to .ics or Google Calendar.

The app can be installed as a Python package or as a Windows executable bundled with PyInstaller.

TLDR

git clone https://github.com/lkoelman/instacalendar.git
cd instalendar && uv sync

# run setup
uv run instacalendar init

# run interactively (fetch Instagram collections and select one)
uv run instacalendar

# export specific collection
uv run instacalendar run --collection "Concerts" --ics-output events.ics

Installation

Install From PyPI

uv tool install instacalendar

Then run:

instacalendar init
instacalendar

Install From Source

git clone https://github.com/lkoelman/instacalendar.git
cd instacalendar
uv sync --dev

Because instagrapi tracks the undocumented Instagram API at a fast-changing pace, upgrading this dependency regularly could prevent bugs arising due to API divergence:

# upgrade out environment and uv.lock file:
uv sync --upgrade-package instagrapi

# upgrade instagrapi before running a command
uv run --upgrade-package instagrapi instacalendar <command>

Configure

Run the guided setup:

uv run instacalendar init

Or provide values non-interactively:

uv run instacalendar init \
  --instagram-username your_user \
  --instagram-password your_password \
  --openrouter-api-key sk-or-v1-... \
  --openrouter-text-model google/gemini-3-flash-preview \
  --openrouter-vision-model google/gemini-3-flash-preview \
  --openrouter-video-model google/gemini-3-flash-preview \
  --default-export ics

If OPENROUTER_API_KEY or INSTAGRAM_PASSWORD is set in your environment, setup asks whether to use that value before prompting you to type one.

Secrets are stored in the operating system keyring. Instagram session settings are stored under the app data directory to avoid repeated logins.

Google Calendar Export

For now, just import the .ics file in your Google Calendar. In the future, an OAuth Client ID will be created so you can directly push events to your Google calendar.

For Google Calendar export, authenticate during setup:

uv run instacalendar init --default-export google --google-auth

The command opens a Google consent link in your browser and stores the resulting OAuth token under the app data directory. Later Google Calendar exports reuse and refresh that token when possible.

Release builds can ship an Instacalendar desktop OAuth client so normal users do not need to create Google Cloud credentials. For development, private forks, or builds without a bundled OAuth client, set one of these environment variables before running --google-auth:

export GOOGLE_OAUTH_CLIENT_FILE=/path/to/oauth-client.json
# or
export GOOGLE_OAUTH_CLIENT_JSON='{"installed": ... }'

The OAuth client must be a Google desktop app. The app requests the calendar.events scope needed to read and write calendar events.

Run

Start the guided wizard:

uv run instacalendar

Export a collection directly:

uv run instacalendar run --collection "Concerts" --ics-output events.ics

Extracted event results are cached locally as each post is processed, so a failed or interrupted run can resume without sending already processed posts back to OpenRouter when the configured model set still matches. To force a fresh extraction pass, use:

uv run instacalendar run --collection "Concerts" --ignore-event-cache

By default, cache hits require the same post, same configured OpenRouter model set, and same extraction source type (text, image, or video). You can relax matching when needed:

uv run instacalendar run --collection "Concerts" --event-cache-key post,media

Retry extraction/export from posts already saved in the local cache:

uv run instacalendar run --from-cache --collection "Concerts" --ics-output events.ics

Limit processing to recent posts, or cap how many matching posts are reviewed:

uv run instacalendar run --collection "Concerts" --posted-since 2026-04-01 --limit 25

While extraction is running, the progress output shows runtime-only estimated LLM cost and token usage for each post and for the run so far, grouped by model. The final summary prints the same per-model token and estimated cost totals. These estimates come from LiteLLM/OpenRouter response usage metadata and are not persisted in the local cache.

Inspect cached posts and processed exports:

uv run instacalendar cache list-posts
uv run instacalendar cache calendar
uv run instacalendar cache events
uv run instacalendar cache info

Clear the local cache:

uv run instacalendar cache clear --yes

Privacy

Instagram captions, post metadata, image content, and cached local video content for posts being processed may be sent to OpenRouter for extraction. Remote Instagram video URLs are not sent when the local video download failed. Google Calendar export sends approved event details to Google. The local cache stores post metadata, downloaded image and video files, extracted event results, review decisions, and export records so reruns can resume extraction/export without contacting Instagram unnecessarily, avoid repeated OpenRouter calls for matching posts, and avoid duplicate exports. Model responses are validated against the app's Pydantic extraction schema before they are cached or reviewed.

Test And Lint

uv run pytest
uv run ruff check

Build A Windows Executable

On Windows:

uv sync --dev
uv run pyinstaller --onefile --name instacalendar src/instacalendar/cli.py

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

instacalendar-0.1.0.tar.gz (24.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

instacalendar-0.1.0-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file instacalendar-0.1.0.tar.gz.

File metadata

  • Download URL: instacalendar-0.1.0.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for instacalendar-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b1e120dce5053ae7675511ba96d3a4ebd338a263988c0ffc37c7fd9a8d375ad5
MD5 9fad2eeacfd9be31ac573fe9dcebc9c4
BLAKE2b-256 654c652f5009d0ce3186950b57f96bd4553722856116f7ac43177d45593f3cc9

See more details on using hashes here.

Provenance

The following attestation bundles were made for instacalendar-0.1.0.tar.gz:

Publisher: publish.yml on lkoelman/instacalendar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file instacalendar-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: instacalendar-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for instacalendar-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 21cff468e2b551f08887503a2021af10fb8427e12f63446b86988f48ab6b0702
MD5 e7b210e8d4532858a9b75b16e1597163
BLAKE2b-256 f815b259902a81ea06e3fa3a1895c93f304d646ad6b11bf793dda89019316394

See more details on using hashes here.

Provenance

The following attestation bundles were made for instacalendar-0.1.0-py3-none-any.whl:

Publisher: publish.yml on lkoelman/instacalendar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page