Skip to content

Let bots move to another actor (Move and movedTo) #50

Description

@dahlia

Part of #47. This issue covers the sending side of account migration: letting a bot move its followers to another actor, which may be another BotKit bot (on a new domain, say) or an account on a different server entirely.

This is the largest of the three sub-issues and the least urgent. The receiving side (#48) is what current users are asking for; moving a bot away mostly matters when its operator changes domains, which BotKit otherwise has no answer for.

The Session.move() method

Add a method to Session:

/**
 * Moves the bot to another actor.  Sends a `Move` activity to the bot's
 * followers and marks the bot as moved, so that its actor object carries
 * `movedTo` from then on.  The target must list the bot's actor URI in its
 * `alsoKnownAs`.
 * @param target The actor to move to.
 * @throws {TypeError} If the target does not list the bot as an alias, or
 *                     if the bot has already moved.
 * @since 0.6.0
 */
move(target: Actor | URL | string): Promise<void>;

In order, it:

  1. Resolves the target and checks that its aliasIds contains the bot's actor URI. Mastodon refuses to start a migration when this fails, and receiving servers would drop the Move anyway, so throwing here is better than sending an activity that goes nowhere.
  2. Stores the target as the bot's successor in the repository.
  3. Sends an Update of the actor, which now carries movedTo (Fedify's successor), to the bot's followers.
  4. Sends a Move with the bot as both actor and object and the target as target, addressed to the public collection and the bot's followers, as in FEP-7628's push-mode example.

The moved state has to live in the repository and not in CreateBotOptions, because the bot is defined in code: a movedTo option would give no way to tell whether the Move for it had already been sent. Storing it means new required methods on the Repository interface (something like getSuccessor(identifier) and setSuccessor(identifier, successorId)), implemented in the in-memory, KV, and cached repositories and in @fedify/botkit-postgres, @fedify/botkit-redis, and @fedify/botkit-sqlite. This is a breaking change for third-party Repository implementations, which is acceptable before 1.0 and will be called out in the changelog.

What a moved bot does

FEP-7628 says an actor carrying movedTo should be considered inactive, so after the move:

  • dispatchActor() sets successor on the actor.
  • Session.publish() throws, since publishing from an inactive actor would miss the followers who moved and could confuse those who stayed.
  • Incoming follow requests are rejected regardless of followerPolicy. This matches Mastodon, where a moved account cannot be followed.
  • The profile page says the bot has moved and links to the target, and the follow button is hidden. The wording and placement should follow the Canvas mode rules in DESIGN.md.

Existing posts stay where they are. Only followers move.

Open questions

Should a move be reversible? Mastodon lets a user cancel a redirect, which removes movedTo but leaves the followers wherever they went. An unmove() (under a better name) would be easy once the successor is in the repository, but I'm not sure anyone needs it.

Should the other event handlers keep firing on a moved bot? Replies and mentions will still trickle in for a while. Letting them through is simpler and lets a bot answer with a pointer to its new home. Ignoring them is closer to “inactive.”

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions