Populate a rail line's stations in the Notion database.
The user will provide: $ARGUMENTS (a line name, e.g. "Yamanote", "Ginza", "Yurikamome")
Look up the line in the Notion Lines database to get its page ID. First list ALL existing lines (query the Lines DB with no filter) and match against them, because line names in Notion use macrons/diacritics (e.g. "Chūō Rapid", "Tōkaidō", "Ōedo") which won't match a plain ASCII search like "Chuo Rapid". If no existing line matches, create it (using the correct diacritics in the name).
Research stations by searching the web for the complete station list for this line, including:
Determine badge style from the line code:
jre style (square badges)tssn style (circle badges)yk style (solid circle badges)Create stations and StationLine entries using the Notion API:
{BASE}/{style}/{code}/{number}.png?size=120Research station coordinates for each station (latitude/longitude). Then set the Place property on each StationLine entry using the Notion private API (see "Setting Place on StationLine" below).
Show a summary of what was created.
Read the token from .env file (NOTION_TOKEN=...).
https://api.notion.com/v12022-06-28https://jdan--73a2eeba09df11f1a30442dde27851f2.web.val.run3076fc0faa7d8093b3afce6b0c25966d3076fc0faa7d8073b3eed1db67a8bcbc3076fc0faa7d80bda742cc7fa4041b06POST /pages
{
"parent": {"database_id": "<STATIONS_DB>"},
"icon": {"type": "emoji", "emoji": "🚉"},
"properties": {
"Name": {"title": [{"text": {"content": "Shiodome 汐留"}}]}
}
}
POST /pages
{
"parent": {"database_id": "<STATIONLINE_DB>"},
"icon": {"type": "external", "external": {"url": "<badge_url>"}},
"properties": {
"Name": {"title": [{"text": {"content": " "}}]},
"Station": {"relation": [{"id": "<station_id>"}]},
"Line": {"relation": [{"id": "<line_id>"}]},
"Stop": {"number": <stop_number>}
}
}
The Place property (dsOX) on StationLine entries is not writable via the public Notion API. Use the private API instead. Read token_v2 from .env (NOTION_TOKEN_V2=...).
POST https://www.notion.so/api/v3/saveTransactionsFanout
Headers:
Content-Type: application/json
Cookie: token_v2=<NOTION_TOKEN_V2>
x-notion-space-id: e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a
x-notion-active-user-header: 84cb4838-4dc9-4d38-8cf8-c186b662dee9
notion-client-version: 23.13.20260214.1755
notion-audit-log-platform: web
Body:
{
"requestId": "<uuid>",
"transactions": [{
"id": "<uuid>",
"spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a",
"debug": {"userAction": "BlockPropertyValueOverlay.handlePlaceChange"},
"operations": [
{
"pointer": {"table": "block", "id": "<stationline_page_id>", "spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a"},
"path": ["properties", "dsOX"],
"command": "set",
"args": [["\u2023", [["plc", {"lat": <lat>, "lon": <lon>, "name": "<Station Name>"}]]]]
},
{
"pointer": {"table": "block", "id": "<stationline_page_id>", "spaceId": "e8bd2e4a-c367-4d7e-8c8b-ef47b27ac37a"},
"path": [],
"command": "update",
"args": {"last_edited_time": <epoch_ms>, "last_edited_by_id": "84cb4838-4dc9-4d38-8cf8-c186b662dee9", "last_edited_by_table": "notion_user"}
}
]
}],
"unretryable_error_behavior": "continue"
}
The name field should be the English station name (e.g. "Shinjuku Station"). The awsPlaceId and address fields are optional and can be omitted.
urllib.request for all API calls (no external dependencies).01, 02)."English 日本語" (e.g. "Shimbashi 新橋").