You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-ups on the X/Twitter (#175) and YouTube (#177) connectors after running
both live, plus a shared cleanup.
Twitter:
- Session config (cookies/proxy/credentials dir) flows through Django settings
(TWITTER_COOKIES_JSON / COOKIE_AUTH_TOKEN / COOKIE_CT0 / COOKIES_FILE /
CREDENTIALS_DIR / PROXY), resolved per search call so a rotated cookie export
applies without a restart; the documented-but-unwired JSON/file routes now
work. CREDENTIALS_DIR defaults to an absolute path.
- Skip timestamp-less tweets instead of minting now() (which would poison the
watermark and strand every older-but-new tweet).
- Honor X's rate-limit reset with an in-cycle retry loop (mirrors Reddit's 429
loop; X's x-rate-limit-reset is an absolute epoch), ticking the poll-lease
heartbeat through the wait.
- Watermark filter uses strict < not <= (same-second tweets were lost).
- Pin twikit to the locked rev.
Shared:
- Promote sleep_with_heartbeat and rate_limit_delay to connectors/base so
Reddit and Twitter share one definition each.
- Rename ListenerError -> TwitterError (mirrors YouTubeError; drops the
'Listener' name AGENTS.md reserves).
Docs/examples:
- Twitter starter (feed + watch); list twitter + youtube in the examples README.
- Per-connector credentials/ directory convention (gitignored) with a guide for
generating the Twitter and YouTube cookie exports.
- README: product mentions in 'What it does', YouTube in the listeners + diagram,
and the changelog-style section replaced by a credentials/changelog pointer.
Both connectors verified live end to end (feed -> watch -> judge). Full core
suite, ruff, and ty green; reviewed via /review-pr with findings addressed.
X/Twitter listening is the first connector added beyond the original Reddit / HN / RSS set. What shipped in this branch:
246
-
247
-
-**`twitter_search` source kind** — a twikit-based connector that runs X search queries (mode Top/Latest, count) and maps results to a schema-parity `NewTweetPayload`, registered alongside the existing kinds with the same feed/watch/webhook pipeline.
248
-
-**Live-cookie auth** — the connector authenticates with an existing X session cookie JSON (`TWITTER_COOKIES_JSON` → `auth_token`/`ct0`, a cookies file, or a login fallback), so no API key, proxy, or vendor API is required — the same live cookies the listening kit already used keep working.
249
-
-**Reliability fixes from live polling** — a per-call twikit client (multi-source polls no longer crash with "Event loop is closed") and X's transient empty-body 404 mapped retryable instead of "tweet deleted", with a regression test. 587 tests green; all CI gates pass.
250
-
-**Verified live end-to-end** — a real X poll through a feed → watch → webhook chain delivered 44/44 items with HTTP 200, payload matched field-for-field against the Twenty `socialEvent` intake contract (`item.handle → actorHandle`, `author → actorName`, `content → eventText`, `occurred_at → occurredAt`, `url → sourceUrl`, `key → dedupeKey`).
251
-
252
-
YouTube listening followed via yt-dlp:
253
-
254
-
-**`youtube_search` source kind** — a yt-dlp-based connector that runs YouTube search queries and maps results to a schema-parity `NewVideoPayload`, registered alongside the existing kinds with the same feed/watch/webhook pipeline.
255
-
-**No authentication required** — public YouTube search works without credentials; optional cookie file for age-restricted content.
-**Watermark-based deduplication** — videos newer than the source's `last_event_at` are surfaced.
258
-
-**Metrics extraction** — views, likes, comments mapped from YouTube metadata.
259
-
-**Thumbnail media** — full thumbnail URLs attached to payloads for rich display.
260
-
261
-
Next up on the roadmap: **Facebook, TikTok, and Instagram connectors** (soon to be added), then Slack, LinkedIn, GitHub, Bluesky, and Mastodon.
243
+
Two connectors ride an unofficial route and need a browser session cookie (X/Twitter always, YouTube only for age-restricted videos); see [apps/core/credentials/README.md](apps/core/credentials/README.md) for setup and the terms-of-service caveat. Per-release history is in the [changelog](CHANGELOG.md).
Copy file name to clipboardExpand all lines: apps/core/pyproject.toml
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -24,7 +24,7 @@ dependencies = [
24
24
"python-dotenv>=1.1",
25
25
"pyyaml>=6.0", # reads the examples/starters/*.yaml in seed_quickstart
26
26
"trafilatura>=1.7", # HTML -> readable article text for the engine's lazy external-link fetch
27
-
"twikit @ git+https://github.com/unclecode/twikit.git", # X (Twitter) unofficial route (listeningkit-verified 2026 fork of d60/twikit)
27
+
"twikit @ git+https://github.com/unclecode/twikit.git@6a73ab97f4de09f79139f6308c9fb80029a9f5f7", # X (Twitter) unofficial route (listeningkit-verified 2026 fork of d60/twikit), pinned: the fork's default branch floats and this code handles auth
28
28
"yt-dlp>=2026.07.04", # YouTube search connector (public API only)
0 commit comments