Skip to main content

Sync Slack Lists into Things3 with two-way completion sync

Project description

Slack List -> Things3 Sync

slingsync pulls Slack List items and creates Things3 to-dos.

What It Does

  • Reads Slack List items using slackLists.items.list.
  • Creates Things3 to-dos via AppleScript.
  • Avoids duplicates using a persisted state file.
  • By default, deletes previously synced Things3 to-dos if the Slack item is gone or marked completed (--delete-missing enabled by default).
  • By default, runs two-way completion sync: marks Slack items completed when mapped Things to-dos are completed (--two-way-sync enabled by default).

Requirements

  • macOS with Things3 installed.
  • Python 3.9+.
  • uv installed (docs) only if you use uv tool, uvx, or uv run.
  • Slack token with lists:read.
  • For two-way completion sync, token also needs lists:write.

Install from PyPI

pip

pip install slingsync
slingsync --help

uv tool

uv tool install slingsync
slingsync --help

Slack Setup

  1. Create app: api.slack.com/apps
  2. Add scope lists:read
  3. Install/reinstall app to workspace
  4. Copy token (xoxb-... or user token)

IDs You Need

How to find List ID and Team ID

  1. Open the Slack List in your browser.
  2. Copy the URL. It looks like:
    • https://XXX.slack.com/lists/TXXX/FXXX
  3. Extract:
    • Team ID: the T... segment (workspace/team)
    • List ID: the F... segment (the list itself)

Use in config:

  • Required: set list_id in your config JSON.
  • Recommended: set team_id in your config JSON.

Config File

No repo clone is required for the global config flow.

Config lookup order:

  1. --config /path/to/config.json
  2. $SLINGSYNC_CONFIG
  3. ~/.config/slingsync/config.json

Global config

First run bootstrap:

slingsync --dry-run

If ~/.config/slingsync/config.json does not exist, the command auto-creates it with empty keys. Then edit ~/.config/slingsync/config.json.

Then set values:

{
  "slack_token": "xoxb-XXX",
  "list_id": "FXXX",
  "team_id": "TXXX",
  "assigned_user_id": "UXXX"
}

Look up your Slack member ID (for assigned_user_id):

curl -sS -G https://slack.com/api/users.lookupByEmail \
  -H "Authorization: Bearer xoxb-XXX" \
  --data-urlencode "email=you@XXX.com"

Read user.id from the response and put it in your config file. If you get missing_scope, add users:read.email (and usually users:read) then reinstall the app. assigned_user_id is used when you pass --filter-assigned-user-id.

Common Runs

Minimal run

uv run slingsync \
  --dry-run

Dry run + open items + configured assignee filter + deadline mapping

uv run slingsync \
  --filter-completed false \
  --filter-assigned-user-id \
  --deadline-column "todo_due_date" \
  --dry-run

Default behavior includes deletion reconcile (preview first)

uv run slingsync \
  --filter-completed false \
  --filter-assigned-user-id \
  --dry-run

Remove --dry-run to apply.

Disable Two-way completion sync

uv run slingsync \
  --no-two-way-sync \
  --dry-run

Disable deletion reconcile

uv run slingsync \
  --no-delete-missing

Argument Reference

Slack

  • --config: explicit config JSON path (highest priority).
  • $SLINGSYNC_CONFIG: config JSON path env override.
  • Default config path: ~/.config/slingsync/config.json.
  • Config values: slack_token, list_id, optional team_id, optional assigned_user_id.
  • --include-archived: Include archived Slack items.
  • --lookup-user-id: Lookup Slack member ID by email and exit.
  • --lookup-email: Email for --lookup-user-id.

Field Mapping And Filters

  • --title-column: Column key/id used as Things title.
  • --notes-column: Column key/id used as Things notes.
  • --deadline-column: Column key/id used for Things deadline.
  • --completed-column: Column key/id for completion state.
  • --assigned-column: Column key/id for assignee.
  • --status-column: Column key/id for status.
  • --filter-completed {true|false|open|completed|...}: include only matching completion state.
  • --filter-assigned-user: match assignee by name substring (case-insensitive).
  • --filter-assigned-user-id / --no-filter-assigned-user-id: enable/disable assignee filter by configured Slack member ID. If enabled and no assigned_user_id is set in the resolved config file, the script exits with an error.
  • --filter-status: include only status value.
  • --exclude-status: exclude status value.
  • --debug-filter-fields: print parsed status/assignee/completed fields per item.

Things Target

  • --target-list: Things list destination (default Inbox).
  • --target-project: Destination project (mutually exclusive with area).
  • --target-area: Destination area (mutually exclusive with project).

Execution

  • --dry-run: Preview only, no writes.
  • --state-file: Custom state file path.
  • --max-items: Process only first N fetched items.
  • --two-way-sync / --no-two-way-sync: enable/disable pushing Things completion back to Slack (default: enabled).
  • --delete-missing / --no-delete-missing: enable/disable deletion reconcile (default: enabled).
  • Reconcile deletes when a previously synced Slack item is either missing from the list or marked completed.

Safety rule:

  • --delete-missing (default on) cannot be used with --max-items.
  • If you need --max-items, add --no-delete-missing.

State File

Default:

  • ~/.config/slingsync/state/slack_to_things_<LIST_ID>.json

Use --state-file to override.

Quick API check:

curl -sS -X POST https://slack.com/api/slackLists.items.list \
  -H "Authorization: Bearer xoxb-XXX" \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"list_id":"FXXX","team_id":"TXXX","limit":1}'

Automation Permission

First run may prompt macOS automation permission to control Things3. If denied accidentally, reset and retry:

tccutil reset AppleEvents com.apple.Terminal

(or reset iTerm2 bundle id if you use iTerm).

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

slingsync-0.2.tar.gz (14.9 kB view details)

Uploaded Source

Built Distribution

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

slingsync-0.2-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

File details

Details for the file slingsync-0.2.tar.gz.

File metadata

  • Download URL: slingsync-0.2.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for slingsync-0.2.tar.gz
Algorithm Hash digest
SHA256 60acf647e218273ce55b3b46dc4d0f7c448734f78b6d17ff4a86d2dfcdb61bb5
MD5 8b962a63d2d14a07a192deb6aad4b11f
BLAKE2b-256 fef9c054da6a3d1867dca78334ec7365902eb7f8e044a1a66d41aa97d0e1f52d

See more details on using hashes here.

File details

Details for the file slingsync-0.2-py3-none-any.whl.

File metadata

  • Download URL: slingsync-0.2-py3-none-any.whl
  • Upload date:
  • Size: 17.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.30 {"installer":{"name":"uv","version":"0.9.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for slingsync-0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0fb3462936314c1caf6988159fcd9224df122cd81b7760c2ed6e9f7afc675fda
MD5 13725907d38a78bab530ea19e026fdb8
BLAKE2b-256 008653269530e08655da429d3f1cb7ce4fbcc54f8ea44dcccec393682fbb2ae9

See more details on using hashes here.

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