Skip to content

Learn from X (Twitter) posts alongside Misskey notes - #5

Merged
otnc merged 1 commit into
mainfrom
feat/twitter-learning-source
Oct 2, 2026
Merged

otnc merged 1 commit into
mainfrom
feat/twitter-learning-source

Conversation

@otnc

@otnc otnc commented Oct 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds X (Twitter) as a second learning source, fetched through the FxTwitter API with the fxtwitter package. No X account or token is required; protected accounts cannot be fetched.

  • Fetching: posts are fetched with a from:<user> search rather than the profile timeline. The timeline only reaches back about 120 posts per user, while the search excludes reposts and reaches back through the whole history (verified back to 2022 with 1,200+ posts). Reposts are also filtered out in code.
  • Incremental sync: after a backfill up to learnNotesLimit, new posts are polled every twitter.pollIntervalMinutes (default 30) using a since_id: cursor, since X has no streaming API. The initial backfill runs in the background after the WebSocket connects, and a failure for one user is logged without stopping the bot.
  • Multiple accounts and per-user start date: target users are now MISSKEY_TARGET_USERS and TWITTER_TARGET_USERS (at least one is required), both comma separated. An optional :yyyy/mm/dd suffix per user restricts learning to posts from 00:00 JST of that date onward (since_time: on X, a createdAt filter and early stop on Misskey).
  • Exclude words: excludeWords stays as the common setting; misskey.excludeWords and twitter.excludeWords apply on top of it per platform.
  • User-Agent: requests carry mimicskey (+<UUIDv7>), generated once per install and stored in the DB, instead of the repository URL, so forks do not present themselves as this repository.

Breaking changes

  • TARGET_USERS is renamed to MISSKEY_TARGET_USERS.
  • learnVisibilities moves to misskey.learnVisibilities. The config file schema is now strict, so a leftover top-level key fails at startup instead of being silently ignored.
  • The learn-config fingerprint now covers both sources, so the first start after upgrading resets the learning data and backfills again.

Test plan

  • npm run typecheck, npm run lint, npm run format:check, npm test, npm run build pass
  • New unit tests for target-user / date parsing and for tweet learnability and search query building
  • Ran the X sync against the live API with a temporary DB: backfill stored 99 posts, the following diff sync fetched 0, and a :yyyy/mm/dd start date limited the backfill to posts after that date
  • Confirmed the API accepts the UUIDv7 User-Agent
  • Loaded the config with only TWITTER_TARGET_USERS set, and confirmed the error when neither target variable is set

Add X as a second learning source, fetched through the FxTwitter API
with the fxtwitter package, so no X account or token is needed.

- Fetch posts with a `from:<user>` search instead of the profile
  timeline: the timeline only reaches back about 120 posts, while the
  search excludes reposts and reaches back through the whole history.
  Backfill up to learnNotesLimit, then poll every
  twitter.pollIntervalMinutes for posts after the stored since_id
  cursor, since X has no streaming API. The initial backfill runs in
  the background after the WebSocket connects, and a failure for one
  user is logged without stopping the bot.
- Split the target users into MISSKEY_TARGET_USERS and
  TWITTER_TARGET_USERS (at least one is required), both comma
  separated. An optional `:yyyy/mm/dd` suffix per user restricts
  learning to posts from that JST date onward.
- Keep excludeWords as the common setting and add
  misskey.excludeWords / twitter.excludeWords, which apply on top of
  it. Move learnVisibilities under misskey, and make the file config
  schema strict so stale keys fail loudly.
- Identify API calls with a per-install UUIDv7 User-Agent instead of
  the repository URL, so forks do not present themselves as this
  repository.
- Store tweets with a `twitter:` id prefix so they cannot collide with
  Misskey note ids, and move the learn-config fingerprint into its own
  module now that it covers both sources.
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​fxtwitter@​2.0.07410010088100
Addednpm/​uuid@​14.0.210010010087100

View full report

@otnc
otnc merged commit f24430c into main Oct 2, 2026
3 checks passed
@otnc
otnc deleted the feat/twitter-learning-source branch October 2, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant