Add a Notion connector so users can ask questions across each employee's Notion workspace. Per-user OAuth (each user grants townsquare access to their Notion); the federation router will fan queries to each user's token automatically.
Why this is a good first issue
The contract for new connectors is well-defined and there are two reference implementations to copy from:
You don't need to know the agent loop, the LLM, or the federation internals. A connector is a small, self-contained module.
What to build
src/townsquare/connectors/notion.py — implements the Connector protocol:
source_id = \"notion\"
required_scopes = [...]
async def search(query, access_token, limit) — call Notion's POST /v1/search API with the user's bearer token, return a list of Item.
async def fetch(item_id, access_token) — call POST /v1/blocks/{block_id}/children (optional in v1; can return None initially).
- OAuth flow in
src/townsquare/web/routes/connections_oauth.py:
GET /connections/notion/connect — redirect to Notion's authorize URL
GET /connections/notion/callback — exchange code, store via upsert_connection(...)
POST /connections/notion/disconnect — deactivate_connection(...)
- Register in
src/townsquare/connectors/registry.py's default_registry().
- Connections UI entry in
src/townsquare/web/routes/connections.py's SOURCE_CATALOG — change connect_url from None to /connections/notion/connect.
- Tests in
tests/test_connectors_slack_github.py (or split out test_connectors_notion.py):
- Scope advertisement
- Mocked HTTP — auth-fail returns
[]
- Payload parsing returns the expected
Item shape
- Settings in
src/townsquare/settings.py already has NOTION_CLIENT_ID / NOTION_CLIENT_SECRET. Wire them through.
example.env — add OAuth setup walkthrough lines like the Slack ones.
References
Tips
- Notion bearer tokens look like
secret_…; store them via upsert_connection exactly like Slack/GitHub.
- Only return text-bearing blocks in
search v1. Page rendering can come later.
- Run
make test and make lint before opening the PR. Both must pass before merge (CI enforces).
Reach out
Comment here before starting if you want feedback on your approach. Happy to review early.
Add a Notion connector so users can ask questions across each employee's Notion workspace. Per-user OAuth (each user grants townsquare access to their Notion); the federation router will fan queries to each user's token automatically.
Why this is a good first issue
The contract for new connectors is well-defined and there are two reference implementations to copy from:
src/townsquare/connectors/slack.py— closest analogue. Slack and Notion both use OAuth-via-our-app +xo*pstyle user tokens.src/townsquare/connectors/github.py— simpler shape (single REST endpoint).You don't need to know the agent loop, the LLM, or the federation internals. A connector is a small, self-contained module.
What to build
src/townsquare/connectors/notion.py— implements theConnectorprotocol:source_id = \"notion\"required_scopes = [...]async def search(query, access_token, limit)— call Notion's POST/v1/searchAPI with the user's bearer token, return a list ofItem.async def fetch(item_id, access_token)— call POST/v1/blocks/{block_id}/children(optional in v1; can return None initially).src/townsquare/web/routes/connections_oauth.py:GET /connections/notion/connect— redirect to Notion's authorize URLGET /connections/notion/callback— exchange code, store viaupsert_connection(...)POST /connections/notion/disconnect—deactivate_connection(...)src/townsquare/connectors/registry.py'sdefault_registry().src/townsquare/web/routes/connections.py'sSOURCE_CATALOG— changeconnect_urlfromNoneto/connections/notion/connect.tests/test_connectors_slack_github.py(or split outtest_connectors_notion.py):[]Itemshapesrc/townsquare/settings.pyalready hasNOTION_CLIENT_ID/NOTION_CLIENT_SECRET. Wire them through.example.env— add OAuth setup walkthrough lines like the Slack ones.References
Tips
secret_…; store them viaupsert_connectionexactly like Slack/GitHub.searchv1. Page rendering can come later.make testandmake lintbefore opening the PR. Both must pass before merge (CI enforces).Reach out
Comment here before starting if you want feedback on your approach. Happy to review early.