@fedify/botkit 0.3.0-dev.111 → 0.3.0-dev.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@ import { Text } from "./text.js";
4
4
  import { MessageClass } from "./message.js";
5
5
  import { Session } from "./session.js";
6
6
  import { CustomEmoji, DeferredCustomEmoji } from "./emoji.js";
7
- import { AcceptEventHandler, FollowEventHandler, LikeEventHandler, MentionEventHandler, MessageEventHandler, QuoteEventHandler, ReactionEventHandler, RejectEventHandler, ReplyEventHandler, SharedMessageEventHandler, UndoneReactionEventHandler, UnfollowEventHandler, UnlikeEventHandler } from "./events.js";
7
+ import { AcceptEventHandler, FollowEventHandler, LikeEventHandler, MentionEventHandler, MessageEventHandler, QuoteEventHandler, ReactionEventHandler, RejectEventHandler, ReplyEventHandler, SharedMessageEventHandler, UndoneReactionEventHandler, UnfollowEventHandler, UnlikeEventHandler, VoteEventHandler } from "./events.js";
8
8
  import { Repository } from "./repository.js";
9
9
  import { Bot, CreateBotOptions, PagesOptions } from "./bot.js";
10
10
  import { SessionImpl } from "./session-impl.js";
@@ -46,6 +46,7 @@ declare class BotImpl<TContextData> implements Bot<TContextData> {
46
46
  onUnlike?: UnlikeEventHandler<TContextData>;
47
47
  onReact?: ReactionEventHandler<TContextData>;
48
48
  onUnreact?: UndoneReactionEventHandler<TContextData>;
49
+ onVote?: VoteEventHandler<TContextData>;
49
50
  constructor(options: BotImplOptions<TContextData>);
50
51
  initialize(): void;
51
52
  getActorSummary(session: Session<TContextData>): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"bot-impl.d.ts","names":[],"sources":["../src/bot-impl.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"bot-impl.d.ts","names":[],"sources":["../src/bot-impl.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/bot-impl.js CHANGED
@@ -10,7 +10,7 @@ import { app } from "./pages.js";
10
10
  import { KvRepository } from "./repository.js";
11
11
  import { SessionImpl } from "./session-impl.js";
12
12
  import { Accept, Announce, Article, ChatMessage, Create, Emoji, EmojiReact, Endpoints, Follow, Image, Like, Link, Mention, Note, PUBLIC_COLLECTION, PropertyValue, Question, Reject, Service, Undo, isActor } from "@fedify/fedify/vocab";
13
- import { Object as Object$2, createFederation, generateCryptoKeyPair } from "@fedify/fedify";
13
+ import { Object as Object$2, Update as Update$1, createFederation, generateCryptoKeyPair } from "@fedify/fedify";
14
14
  import { getLogger } from "@logtape/logtape";
15
15
  import mimeDb from "mime-db";
16
16
  import fs from "node:fs/promises";
@@ -49,6 +49,7 @@ var BotImpl = class {
49
49
  onUnlike;
50
50
  onReact;
51
51
  onUnreact;
52
+ onVote;
52
53
  constructor(options) {
53
54
  this.identifier = options.identifier ?? "bot";
54
55
  this.class = options.class ?? Service;
@@ -362,7 +363,7 @@ var BotImpl = class {
362
363
  }
363
364
  async onCreated(ctx, create) {
364
365
  const object = await create.getObject(ctx);
365
- if (!(object instanceof Article || object instanceof ChatMessage || object instanceof Note || object instanceof Question)) return;
366
+ if (!(object instanceof Article || object instanceof ChatMessage || object instanceof Note || object instanceof Question) || object.attributionId?.href !== create.actorId?.href) return;
366
367
  const session = this.getSession(ctx);
367
368
  let messageCache = null;
368
369
  const getMessage = async () => {
@@ -370,6 +371,83 @@ var BotImpl = class {
370
371
  return messageCache = await createMessage(object, session, {});
371
372
  };
372
373
  const replyTarget = ctx.parseUri(object.replyTargetId);
374
+ if (this.onVote != null && object instanceof Note && replyTarget?.type === "object" && messageClasses.includes(replyTarget.class) && object.name != null) {
375
+ if (create.actorId?.href === session.actorId.href) return;
376
+ const actor = await create.getActor(ctx);
377
+ if (actor == null) return;
378
+ const pollMessage = await this.repository.getMessage(replyTarget.values.id);
379
+ if (!(pollMessage instanceof Create)) return;
380
+ const question = await pollMessage.getObject(ctx);
381
+ if (!(question instanceof Question) || question.endTime == null || Temporal.Instant.compare(question.endTime, Temporal.Now.instant()) < 0) return;
382
+ const optionNotes = [];
383
+ const options = [];
384
+ for await (const note of question.getInclusiveOptions(ctx)) {
385
+ if (!(note instanceof Note)) continue;
386
+ optionNotes.push(note);
387
+ if (note.name != null) options.push(note.name.toString());
388
+ }
389
+ const multiple = options.length > 0;
390
+ for await (const note of question.getExclusiveOptions(ctx)) {
391
+ if (!(note instanceof Note)) continue;
392
+ optionNotes.push(note);
393
+ if (note.name != null) options.push(note.name.toString());
394
+ }
395
+ const option = object.name.toString();
396
+ if (!options.includes(option)) return;
397
+ const updatedOptionNotes = [...optionNotes];
398
+ let i = 0;
399
+ for (const note of updatedOptionNotes) {
400
+ if (note.name === option) {
401
+ const replies = await note.getReplies(ctx);
402
+ if (replies != null && replies.totalItems != null) updatedOptionNotes[i] = note.clone({ replies: replies.clone({ totalItems: replies.totalItems + 1 }) });
403
+ }
404
+ i++;
405
+ }
406
+ const updatedQuestion = question.clone({
407
+ inclusiveOptions: multiple ? updatedOptionNotes : [],
408
+ exclusiveOptions: !multiple ? updatedOptionNotes : []
409
+ });
410
+ const updatedPollMessage = pollMessage.clone({ object: updatedQuestion });
411
+ await this.repository.updateMessage(replyTarget.values.id, () => updatedPollMessage);
412
+ const message = await createMessage(updatedQuestion, session, {});
413
+ const vote = {
414
+ raw: object,
415
+ actor,
416
+ message,
417
+ poll: {
418
+ multiple,
419
+ options,
420
+ endTime: question.endTime
421
+ },
422
+ option
423
+ };
424
+ await this.onVote(session, vote);
425
+ const update = new Update$1({
426
+ id: new URL(`#update-votes/${Date.now()}`, updatedQuestion.id ?? ctx.origin),
427
+ actor: ctx.getActorUri(this.identifier),
428
+ object: updatedPollMessage.id,
429
+ tos: updatedPollMessage.toIds,
430
+ ccs: updatedPollMessage.ccIds
431
+ });
432
+ if (message.visibility === "direct") {
433
+ await ctx.forwardActivity(this, [...message.mentions], {
434
+ skipIfUnsigned: true,
435
+ excludeBaseUris: [new URL(ctx.origin)]
436
+ });
437
+ await ctx.sendActivity(this, [...message.mentions], update, { excludeBaseUris: [new URL(ctx.origin)] });
438
+ } else {
439
+ await ctx.forwardActivity(this, "followers", {
440
+ skipIfUnsigned: true,
441
+ preferSharedInbox: true,
442
+ excludeBaseUris: [new URL(ctx.origin)]
443
+ });
444
+ await ctx.sendActivity(this, "followers", update, {
445
+ preferSharedInbox: true,
446
+ excludeBaseUris: [new URL(ctx.origin)]
447
+ });
448
+ }
449
+ return;
450
+ }
373
451
  if (this.onReply != null && replyTarget?.type === "object" && messageClasses.includes(replyTarget.class)) {
374
452
  const message = await getMessage();
375
453
  if (message.visibility === "public" || message.visibility === "unlisted") await ctx.forwardActivity(this, "followers", {
@@ -1 +1 @@
1
- {"version":3,"file":"bot-impl.js","names":["options: BotImplOptions<TContextData>","#summary","#properties","metadata","APEmoji","RawLike","session: Session<TContextData>","tags: (Link | Object)[]","pairs: PropertyValue[]","ctx: Context<TContextData>","identifier: string","Object","_ctx: Context<TContextData>","username: string","cursor: string | null","followers: AsyncIterable<Actor>","nextCursor: string | null","items: Recipient[]","ctx: RequestContext<TContextData>","owner: Actor | null","object: Object","items: Activity[]","nextPublished: Temporal.Instant | null","_ctx: RequestContext<TContextData>","values: { id: string }","_signedKey: CryptographicKey | null","signedKeyOwner: Actor | null","cls: new (values: any) => T","ctx: Context<TContextData> | RequestContext<TContextData>","id: string","values: { name: string }","ctx: InboxContext<TContextData>","follow: Follow","undo: Undo","accept: Accept","reject: Reject","create: Create","messageCache: Message<MessageClass, TContextData> | null","quoteUrl: URL | null","announce: Announce","object: Object | null","sharedMessage: SharedMessage<MessageClass, TContextData>","#parseLike","like: RawLike","#parseReaction","react: EmojiReact | RawLike","emoji: Emoji | APEmoji | undefined","origin: string | URL | Context<TContextData>","contextData?: TContextData","request: Request","contextData: TContextData","file: fs.FileHandle","name: string","data: CustomEmoji","url: URL","name: TEmojiName","emojis: Readonly<Record<TEmojiName, CustomEmoji>>"],"sources":["../src/bot-impl.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport {\n type Context,\n createFederation,\n type Federation,\n generateCryptoKeyPair,\n type InboxContext,\n type NodeInfo,\n Object,\n type PageItems,\n type Recipient,\n type RequestContext,\n type Software,\n} from \"@fedify/fedify\";\nimport {\n Accept,\n type Activity,\n type Actor,\n Announce,\n type Application,\n Article,\n ChatMessage,\n Create,\n type CryptographicKey,\n Emoji as APEmoji,\n EmojiReact,\n Endpoints,\n Follow,\n Image,\n isActor,\n Like as RawLike,\n Link,\n Mention,\n Note,\n PropertyValue,\n PUBLIC_COLLECTION,\n Question,\n Reject,\n Service,\n Undo,\n} from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport mimeDb from \"mime-db\";\nimport fs from \"node:fs/promises\";\nimport { getXForwardedRequest } from \"x-forwarded-fetch\";\nimport metadata from \"../deno.json\" with { type: \"json\" };\nimport type { Bot, CreateBotOptions, PagesOptions } from \"./bot.ts\";\nimport {\n type CustomEmoji,\n type DeferredCustomEmoji,\n type Emoji,\n isEmoji,\n} from \"./emoji.ts\";\nimport type {\n AcceptEventHandler,\n FollowEventHandler,\n LikeEventHandler,\n MentionEventHandler,\n MessageEventHandler,\n QuoteEventHandler,\n ReactionEventHandler,\n RejectEventHandler,\n ReplyEventHandler,\n SharedMessageEventHandler,\n UndoneReactionEventHandler,\n UnfollowEventHandler,\n UnlikeEventHandler,\n} from \"./events.ts\";\nimport { FollowRequestImpl } from \"./follow-impl.ts\";\nimport {\n createMessage,\n getMessageVisibility,\n isMessageObject,\n isQuoteLink,\n messageClasses,\n} from \"./message-impl.ts\";\nimport type { Message, MessageClass, SharedMessage } from \"./message.ts\";\nimport { app } from \"./pages.tsx\";\nimport type { Like, Reaction } from \"./reaction.ts\";\nimport { KvRepository, type Repository, type Uuid } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport type { Session } from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nexport interface BotImplOptions<TContextData>\n extends CreateBotOptions<TContextData> {\n collectionWindow?: number;\n}\n\nexport class BotImpl<TContextData> implements Bot<TContextData> {\n readonly identifier: string;\n readonly class: typeof Service | typeof Application;\n readonly username: string;\n readonly name?: string;\n readonly summary?: Text<\"block\", TContextData>;\n #summary: { text: string; tags: (Link | Object)[] } | null;\n readonly icon?: URL | Image;\n readonly image?: URL | Image;\n readonly properties: Record<string, Text<\"block\" | \"inline\", TContextData>>;\n #properties: { pairs: PropertyValue[]; tags: (Link | Object)[] } | null;\n readonly followerPolicy: \"accept\" | \"reject\" | \"manual\";\n readonly customEmojis: Record<string, CustomEmoji>;\n readonly repository: Repository;\n readonly software?: Software;\n readonly behindProxy: boolean;\n readonly pages: Required<PagesOptions>;\n readonly collectionWindow: number;\n readonly federation: Federation<TContextData>;\n\n onFollow?: FollowEventHandler<TContextData>;\n onUnfollow?: UnfollowEventHandler<TContextData>;\n onAcceptFollow?: AcceptEventHandler<TContextData>;\n onRejectFollow?: RejectEventHandler<TContextData>;\n onMention?: MentionEventHandler<TContextData>;\n onReply?: ReplyEventHandler<TContextData>;\n onQuote?: QuoteEventHandler<TContextData>;\n onMessage?: MessageEventHandler<TContextData>;\n onSharedMessage?: SharedMessageEventHandler<TContextData>;\n onLike?: LikeEventHandler<TContextData>;\n onUnlike?: UnlikeEventHandler<TContextData>;\n onReact?: ReactionEventHandler<TContextData>;\n onUnreact?: UndoneReactionEventHandler<TContextData>;\n\n constructor(options: BotImplOptions<TContextData>) {\n this.identifier = options.identifier ?? \"bot\";\n this.class = options.class ?? Service;\n this.username = options.username;\n this.name = options.name;\n this.summary = options.summary;\n this.#summary = null;\n this.icon = options.icon;\n this.image = options.image;\n this.properties = options.properties ?? {};\n this.#properties = null;\n this.followerPolicy = options.followerPolicy ?? \"accept\";\n this.customEmojis = {};\n this.repository = options.repository ?? new KvRepository(options.kv);\n this.software = options.software;\n this.pages = {\n color: \"green\",\n css: \"\",\n ...(options.pages ?? {}),\n };\n this.federation = createFederation<TContextData>({\n kv: options.kv,\n queue: options.queue,\n userAgent: {\n software: `BotKit/${metadata.version}`,\n },\n });\n this.behindProxy = options.behindProxy ?? false;\n this.collectionWindow = options.collectionWindow ?? 50;\n this.initialize();\n }\n\n initialize(): void {\n this.federation\n .setActorDispatcher(\n \"/ap/actor/{identifier}\",\n this.dispatchActor.bind(this),\n )\n .mapHandle(this.mapHandle.bind(this))\n .setKeyPairsDispatcher(this.dispatchActorKeyPairs.bind(this));\n this.federation\n .setFollowersDispatcher(\n \"/ap/actor/{identifier}/followers\",\n this.dispatchFollowers.bind(this),\n )\n .setFirstCursor(this.getFollowersFirstCursor.bind(this))\n .setCounter(this.countFollowers.bind(this));\n this.federation\n .setOutboxDispatcher(\n \"/ap/actor/{identifier}/outbox\",\n this.dispatchOutbox.bind(this),\n )\n .setFirstCursor(this.getOutboxFirstCursor.bind(this))\n .setCounter(this.countOutbox.bind(this));\n this.federation\n .setObjectDispatcher(\n Follow,\n \"/ap/follow/{id}\",\n this.dispatchFollow.bind(this),\n )\n .authorize(this.authorizeFollow.bind(this));\n this.federation.setObjectDispatcher(\n Create,\n \"/ap/create/{id}\",\n this.dispatchCreate.bind(this),\n );\n this.federation.setObjectDispatcher(\n Article,\n \"/ap/article/{id}\",\n (ctx, values) => this.dispatchMessage(Article, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n ChatMessage,\n \"/ap/chat-message/{id}\",\n (ctx, values) => this.dispatchMessage(ChatMessage, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Note,\n \"/ap/note/{id}\",\n (ctx, values) => this.dispatchMessage(Note, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Question,\n \"/ap/question/{id}\",\n (ctx, values) => this.dispatchMessage(Question, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Announce,\n \"/ap/announce/{id}\",\n this.dispatchAnnounce.bind(this),\n );\n this.federation.setObjectDispatcher(\n APEmoji,\n \"/ap/emoji/{name}\",\n this.dispatchEmoji.bind(this),\n );\n this.federation\n .setInboxListeners(\"/ap/actor/{identifier}/inbox\", \"/ap/inbox\")\n .on(Follow, this.onFollowed.bind(this))\n .on(Undo, async (ctx, undo) => {\n const object = await undo.getObject(ctx);\n if (object instanceof Follow) await this.onUnfollowed(ctx, undo);\n else if (object instanceof RawLike) await this.onUnliked(ctx, undo);\n else {\n const logger = getLogger([\"botkit\", \"bot\", \"inbox\"]);\n logger.warn(\n \"The Undo object {undoId} is not about Follow or Like: {object}.\",\n { undoId: undo.id?.href, object },\n );\n }\n })\n .on(Accept, this.onFollowAccepted.bind(this))\n .on(Reject, this.onFollowRejected.bind(this))\n .on(Create, this.onCreated.bind(this))\n .on(Announce, this.onAnnounced.bind(this))\n .on(RawLike, this.onLiked.bind(this))\n .setSharedKeyDispatcher(this.dispatchSharedKey.bind(this));\n if (this.software != null) {\n this.federation.setNodeInfoDispatcher(\n \"/nodeinfo/2.1\",\n this.dispatchNodeInfo.bind(this),\n );\n }\n }\n\n async getActorSummary(\n session: Session<TContextData>,\n ): Promise<{ text: string; tags: (Link | Object)[] } | null> {\n if (this.summary == null) return null;\n if (this.#summary == null) {\n let summary = \"\";\n const tags: (Link | Object)[] = [];\n for await (const chunk of this.summary.getHtml(session)) {\n summary += chunk;\n }\n for await (const tag of this.summary.getTags(session)) {\n tags.push(tag);\n }\n return this.#summary = { text: summary, tags };\n }\n return this.#summary;\n }\n\n async getActorProperties(\n session: Session<TContextData>,\n ): Promise<{ pairs: PropertyValue[]; tags: (Link | Object)[] }> {\n if (this.#properties != null) return this.#properties;\n const pairs: PropertyValue[] = [];\n const tags: (Link | Object)[] = [];\n for (const name in this.properties) {\n const value = this.properties[name];\n const pair = new PropertyValue({\n name,\n value: (await Array.fromAsync(value.getHtml(session))).join(\"\"),\n });\n pairs.push(pair);\n for await (const tag of value.getTags(session)) {\n tags.push(tag);\n }\n }\n return this.#properties = { pairs, tags };\n }\n\n async dispatchActor(\n ctx: Context<TContextData>,\n identifier: string,\n ): Promise<Actor | null> {\n if (this.identifier !== identifier) return null;\n const session = this.getSession(ctx);\n const summary = await this.getActorSummary(session);\n const { pairs, tags } = await this.getActorProperties(session);\n const allTags = summary == null ? tags : [...tags, ...summary.tags];\n const keyPairs = await ctx.getActorKeyPairs(identifier);\n return new this.class({\n id: ctx.getActorUri(identifier),\n preferredUsername: this.username,\n name: this.name,\n summary: summary == null ? null : summary.text,\n attachments: pairs,\n tags: allTags.filter((tag, i) =>\n allTags.findIndex((t) =>\n t.name?.toString() === tag.name?.toString() &&\n (t instanceof Link\n ? tag instanceof Link && t.href?.href === tag.href?.href\n : tag instanceof Object && t.id?.href === tag.id?.href)\n ) === i\n ),\n icon: this.icon == null\n ? null\n : this.icon instanceof Image\n ? this.icon\n : new Image({ url: this.icon }),\n image: this.image == null\n ? null\n : this.image instanceof Image\n ? this.image\n : new Image({ url: this.image }),\n inbox: ctx.getInboxUri(identifier),\n endpoints: new Endpoints({\n sharedInbox: ctx.getInboxUri(),\n }),\n followers: ctx.getFollowersUri(identifier),\n outbox: ctx.getOutboxUri(identifier),\n publicKey: keyPairs[0].cryptographicKey,\n assertionMethods: keyPairs.map((pair) => pair.multikey),\n url: new URL(\"/\", ctx.origin),\n });\n }\n\n mapHandle(_ctx: Context<TContextData>, username: string): string | null {\n return username === this.username ? this.identifier : null;\n }\n\n async dispatchActorKeyPairs(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<CryptoKeyPair[]> {\n if (identifier !== this.identifier) return [];\n let keyPairs = await this.repository.getKeyPairs();\n if (keyPairs == null) {\n const rsa = await generateCryptoKeyPair(\"RSASSA-PKCS1-v1_5\");\n const ed25519 = await generateCryptoKeyPair(\"Ed25519\");\n keyPairs = [rsa, ed25519];\n await this.repository.setKeyPairs(keyPairs);\n }\n return keyPairs;\n }\n\n async dispatchFollowers(\n _ctx: Context<TContextData>,\n identifier: string,\n cursor: string | null,\n ): Promise<PageItems<Recipient> | null> {\n if (identifier !== this.identifier) return null;\n let followers: AsyncIterable<Actor>;\n let nextCursor: string | null;\n if (cursor == null) {\n followers = this.repository.getFollowers();\n nextCursor = null;\n } else {\n const offset = cursor.match(/^\\d+$/) ? parseInt(cursor) : 0;\n followers = this.repository.getFollowers({\n offset,\n limit: this.collectionWindow,\n });\n nextCursor = (offset + this.collectionWindow).toString();\n }\n const items: Recipient[] = [];\n let i = 0;\n for await (const follower of followers) {\n items.push(follower);\n i++;\n }\n if (i < this.collectionWindow) nextCursor = null;\n return { items, nextCursor };\n }\n\n getFollowersFirstCursor(\n _ctx: Context<TContextData>,\n identifier: string,\n ): string | null {\n if (identifier !== this.identifier) return null;\n return \"0\";\n }\n\n async countFollowers(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<number | null> {\n if (identifier !== this.identifier) return null;\n return await this.repository.countFollowers();\n }\n\n async getPermissionChecker(\n ctx: RequestContext<TContextData>,\n ): Promise<(object: Object) => boolean> {\n let owner: Actor | null;\n try {\n owner = await ctx.getSignedKeyOwner();\n } catch {\n owner = null;\n }\n let follower = false;\n const ownerUri = owner?.id;\n if (ownerUri != null) {\n follower = await this.repository.hasFollower(ownerUri);\n }\n const followersUri = ctx.getFollowersUri(this.identifier);\n return (object: Object): boolean => {\n const recipients = [...object.toIds, ...object.ccIds].map((u) => u.href);\n if (recipients.includes(PUBLIC_COLLECTION.href)) return true;\n if (recipients.includes(followersUri.href) && follower) return true;\n return ownerUri == null ? false : recipients.includes(ownerUri.href);\n };\n }\n\n async dispatchOutbox(\n ctx: RequestContext<TContextData>,\n identifier: string,\n cursor: string | null,\n ): Promise<PageItems<Activity> | null> {\n if (identifier !== this.identifier) return null;\n const activities = this.repository.getMessages({\n order: \"newest\",\n until: cursor == null || cursor === \"\"\n ? undefined\n : Temporal.Instant.from(cursor),\n limit: cursor == null ? undefined : this.collectionWindow + 1,\n });\n const items: Activity[] = [];\n const isVisible = await this.getPermissionChecker(ctx);\n let i = 0;\n let nextPublished: Temporal.Instant | null = null;\n for await (const activity of activities) {\n if (cursor != null && i >= this.collectionWindow) {\n nextPublished = activity.published ??\n (await activity.getObject())?.published ?? null;\n break;\n }\n if (isVisible(activity)) items.push(activity);\n i++;\n }\n return { items, nextCursor: nextPublished?.toString() ?? null };\n }\n\n getOutboxFirstCursor(\n _ctx: Context<TContextData>,\n identifier: string,\n ): string | null {\n if (identifier !== this.identifier) return null;\n return \"\";\n }\n\n async countOutbox(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<number | null> {\n if (identifier !== this.identifier) return null;\n return await this.repository.countMessages();\n }\n\n async dispatchFollow(\n _ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Follow | null> {\n const id = values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n return follow ?? null;\n }\n\n async authorizeFollow(\n _ctx: RequestContext<TContextData>,\n values: { id: string },\n _signedKey: CryptographicKey | null,\n signedKeyOwner: Actor | null,\n ): Promise<boolean> {\n if (signedKeyOwner == null || signedKeyOwner.id == null) return false;\n const id = values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n if (follow == null) return false;\n return signedKeyOwner.id.href === follow.objectId?.href ||\n signedKeyOwner.id.href === follow.actorId?.href;\n }\n\n async dispatchCreate(\n ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Create | null> {\n const activity = await this.repository.getMessage(values.id as Uuid);\n if (!(activity instanceof Create)) return null;\n const isVisible = await this.getPermissionChecker(ctx);\n return isVisible(activity) ? activity : null;\n }\n\n async dispatchMessage<T extends MessageClass>(\n // deno-lint-ignore no-explicit-any\n cls: new (values: any) => T,\n ctx: Context<TContextData> | RequestContext<TContextData>,\n id: string,\n ): Promise<T | null> {\n const activity = await this.repository.getMessage(id as Uuid);\n if (!(activity instanceof Create)) return null;\n if (\"request\" in ctx) {\n // TODO: Split this method into two\n const isVisible = await this.getPermissionChecker(ctx);\n if (!isVisible(activity)) return null;\n }\n const object = await activity.getObject(ctx);\n if (object == null || !(object instanceof cls)) return null;\n return object;\n }\n\n async dispatchAnnounce(\n ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Announce | null> {\n const activity = await this.repository.getMessage(values.id as Uuid);\n if (!(activity instanceof Announce)) return null;\n const isVisible = await this.getPermissionChecker(ctx);\n return isVisible(activity) ? activity : null;\n }\n\n dispatchEmoji(\n ctx: Context<TContextData>,\n values: { name: string },\n ): APEmoji | null {\n const customEmoji = this.customEmojis[values.name];\n if (customEmoji == null) return null;\n return this.getEmoji(ctx, values.name, customEmoji);\n }\n\n dispatchSharedKey(_ctx: Context<TContextData>): { identifier: string } {\n return { identifier: this.identifier };\n }\n\n async onFollowed(\n ctx: InboxContext<TContextData>,\n follow: Follow,\n ): Promise<void> {\n const botUri = ctx.getActorUri(this.identifier);\n if (\n follow.actorId?.href === botUri.href ||\n follow.objectId?.href !== botUri.href\n ) {\n return;\n }\n const follower = await follow.getActor({\n contextLoader: ctx.contextLoader,\n documentLoader: ctx.documentLoader,\n suppressError: true,\n });\n if (follower == null || follower.id == null) return;\n const session = this.getSession(ctx);\n const followRequest = new FollowRequestImpl<TContextData>(\n session,\n follow,\n follower,\n );\n await this.onFollow?.(session, followRequest);\n if (followRequest.state === \"pending\") {\n if (this.followerPolicy === \"accept\") await followRequest.accept();\n else if (this.followerPolicy === \"reject\") await followRequest.reject();\n }\n }\n\n async onUnfollowed(\n ctx: InboxContext<TContextData>,\n undo: Undo,\n ): Promise<void> {\n const followId = undo.objectId;\n if (followId == null || undo.actorId == null) return;\n const follower = await this.repository.removeFollower(\n followId,\n undo.actorId,\n );\n if (this.onUnfollow != null && follower != null) {\n const session = this.getSession(ctx);\n await this.onUnfollow(session, follower);\n }\n }\n\n async onFollowAccepted(\n ctx: InboxContext<TContextData>,\n accept: Accept,\n ): Promise<void> {\n const parsedObj = ctx.parseUri(accept.objectId);\n if (parsedObj?.type !== \"object\" || parsedObj.class !== Follow) return;\n const follow = await this.repository.getSentFollow(\n parsedObj.values.id as Uuid,\n );\n if (follow == null) return;\n const followee = await follow.getObject(ctx);\n if (\n !isActor(followee) || followee.id == null ||\n followee.id.href !== accept.actorId?.href\n ) {\n return;\n }\n await this.repository.addFollowee(followee.id, follow);\n if (this.onAcceptFollow != null) {\n const session = this.getSession(ctx);\n await this.onAcceptFollow(session, followee);\n }\n }\n\n async onFollowRejected(\n ctx: InboxContext<TContextData>,\n reject: Reject,\n ): Promise<void> {\n const parsedObj = ctx.parseUri(reject.objectId);\n if (parsedObj?.type !== \"object\" || parsedObj.class !== Follow) return;\n const id = parsedObj.values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n if (follow == null) return;\n const followee = await follow.getObject(ctx);\n if (\n !isActor(followee) || followee.id == null ||\n followee.id.href !== reject.actorId?.href\n ) {\n return;\n }\n await this.repository.removeSentFollow(id);\n if (this.onRejectFollow != null) {\n const session = this.getSession(ctx);\n await this.onRejectFollow(session, followee);\n }\n }\n\n async onCreated(\n ctx: InboxContext<TContextData>,\n create: Create,\n ): Promise<void> {\n const object = await create.getObject(ctx);\n if (\n !(object instanceof Article || object instanceof ChatMessage ||\n object instanceof Note || object instanceof Question)\n ) {\n return;\n }\n const session = this.getSession(ctx);\n let messageCache: Message<MessageClass, TContextData> | null = null;\n const getMessage = async () => {\n if (messageCache != null) return messageCache;\n return messageCache = await createMessage(object, session, {});\n };\n const replyTarget = ctx.parseUri(object.replyTargetId);\n if (\n this.onReply != null &&\n replyTarget?.type === \"object\" &&\n // @ts-ignore: replyTarget.class satisfies (typeof messageClasses)[number]\n messageClasses.includes(replyTarget.class)\n ) {\n const message = await getMessage();\n if (\n message.visibility === \"public\" || message.visibility === \"unlisted\"\n ) {\n await ctx.forwardActivity(this, \"followers\", {\n skipIfUnsigned: true,\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n }\n await this.onReply(session, message);\n }\n let quoteUrl: URL | null = null;\n // FIXME: eliminate this duplication\n for await (const tag of object.getTags(ctx)) {\n if (tag instanceof Link && isQuoteLink(tag)) {\n quoteUrl = tag.href;\n break;\n }\n }\n if (quoteUrl == null) quoteUrl = object.quoteUrl;\n const quoteTarget = ctx.parseUri(quoteUrl);\n if (\n this.onQuote != null &&\n quoteTarget?.type === \"object\" &&\n // @ts-ignore: quoteTarget.class satisfies (typeof messageClasses)[number]\n messageClasses.includes(quoteTarget.class)\n ) {\n const message = await getMessage();\n if (\n message.visibility === \"public\" || message.visibility === \"unlisted\"\n ) {\n await ctx.forwardActivity(this, \"followers\", {\n skipIfUnsigned: true,\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n }\n await this.onQuote(session, message);\n }\n for await (const tag of object.getTags(ctx)) {\n if (\n tag instanceof Mention && tag.href != null && this.onMention != null\n ) {\n const parsed = ctx.parseUri(tag.href);\n if (\n parsed?.type === \"actor\" && parsed.identifier === this.identifier\n ) {\n await this.onMention(session, await getMessage());\n break;\n }\n }\n }\n if (this.onMessage != null) {\n await this.onMessage(session, await getMessage());\n }\n }\n\n async onAnnounced(\n ctx: InboxContext<TContextData>,\n announce: Announce,\n ): Promise<void> {\n if (\n this.onSharedMessage == null || announce.id == null ||\n announce.actorId == null\n ) return;\n const objectUri = ctx.parseUri(announce.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await announce.getObject(ctx);\n }\n if (!isMessageObject(object)) return;\n const session = this.getSession(ctx);\n const actor = announce.actorId.href == session.actorId.href\n ? await session.getActor()\n : await announce.getActor(ctx);\n if (actor == null) return;\n const original = await createMessage(object, session, {});\n const sharedMessage: SharedMessage<MessageClass, TContextData> = {\n raw: announce,\n id: announce.id,\n actor,\n visibility: getMessageVisibility(announce.toIds, announce.ccIds, actor),\n original,\n };\n await this.onSharedMessage(session, sharedMessage);\n }\n\n async #parseLike(\n ctx: InboxContext<TContextData>,\n like: RawLike,\n ): Promise<\n { session: Session<TContextData>; like: Like<TContextData> } | undefined\n > {\n if (like.id == null || like.actorId == null) return undefined;\n const objectUri = ctx.parseUri(like.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await like.getObject(ctx);\n }\n if (!isMessageObject(object)) return undefined;\n const session = this.getSession(ctx);\n const actor = like.actorId.href == session.actorId.href\n ? await session.getActor()\n : await like.getActor(ctx);\n if (actor == null) return;\n const message = await createMessage(object, session, {});\n return {\n session,\n like: {\n raw: like,\n id: like.id,\n actor,\n message,\n },\n };\n }\n\n async onLiked(ctx: InboxContext<TContextData>, like: RawLike): Promise<void> {\n if (like.name != null) return this.onReacted(ctx, like);\n if (this.onLike == null) return;\n const sessionAndLike = await this.#parseLike(ctx, like);\n if (sessionAndLike == null) return;\n const { session, like: likeObject } = sessionAndLike;\n await this.onLike(session, likeObject);\n }\n\n async onUnliked(ctx: InboxContext<TContextData>, undo: Undo): Promise<void> {\n const like = await undo.getObject(ctx);\n if (!(like instanceof RawLike)) return;\n if (like.name != null) return this.onUnreacted(ctx, undo);\n if (this.onUnlike == null) return;\n if (undo.actorId?.href !== like.actorId?.href) return;\n const sessionAndLike = await this.#parseLike(ctx, like);\n if (sessionAndLike == null) return;\n const { session, like: likeObject } = sessionAndLike;\n await this.onUnlike(session, likeObject);\n }\n\n async #parseReaction(\n ctx: InboxContext<TContextData>,\n react: EmojiReact | RawLike,\n ): Promise<\n | { session: Session<TContextData>; reaction: Reaction<TContextData> }\n | undefined\n > {\n if (react.id == null || react.actorId == null || react.name == null) {\n return undefined;\n }\n let emoji: Emoji | APEmoji | undefined;\n if (isEmoji(react.name)) {\n emoji = react.name;\n } else if (\n typeof react.name === \"string\" && react.name.startsWith(\":\") &&\n react.name.endsWith(\":\")\n ) {\n for await (const tag of react.getTags(ctx)) {\n if (tag instanceof APEmoji && tag.name === react.name) {\n emoji = tag;\n break;\n }\n }\n }\n if (emoji == null) return undefined;\n const objectUri = ctx.parseUri(react.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await react.getObject(ctx);\n }\n if (!isMessageObject(object)) return undefined;\n const session = this.getSession(ctx);\n const actor = react.actorId.href == session.actorId.href\n ? await session.getActor()\n : await react.getActor(ctx);\n if (actor == null) return;\n const message = await createMessage(object, session, {});\n return {\n session,\n reaction: {\n raw: react,\n id: react.id,\n actor,\n message,\n emoji,\n },\n };\n }\n\n async onReacted(\n ctx: InboxContext<TContextData>,\n react: EmojiReact | RawLike,\n ): Promise<void> {\n if (this.onReact == null) return;\n const sessionAndReaction = await this.#parseReaction(ctx, react);\n if (sessionAndReaction == null) return;\n const { session, reaction } = sessionAndReaction;\n await this.onReact(session, reaction);\n }\n\n async onUnreacted(\n ctx: InboxContext<TContextData>,\n undo: Undo,\n ): Promise<void> {\n if (this.onUnreact == null) return;\n const react = await undo.getObject(ctx);\n if (!(react instanceof EmojiReact || react instanceof RawLike)) return;\n if (undo.actorId?.href !== react.actorId?.href) return;\n const sessionAndReaction = await this.#parseReaction(ctx, react);\n if (sessionAndReaction == null) return;\n const { session, reaction } = sessionAndReaction;\n await this.onUnreact(session, reaction);\n }\n\n dispatchNodeInfo(_ctx: Context<TContextData>): NodeInfo {\n return {\n software: this.software!,\n protocols: [\"activitypub\"],\n services: {\n outbound: [\"atom1.0\"], // TODO\n },\n usage: {\n users: {\n total: 1,\n activeMonth: 1, // FIXME\n activeHalfyear: 1, // FIXME\n },\n localPosts: 0, // FIXME\n localComments: 0,\n },\n };\n }\n\n getSession(\n origin: string | URL,\n contextData: TContextData,\n ): SessionImpl<TContextData>;\n getSession(origin: string | URL): SessionImpl<TContextData>;\n getSession(context: Context<TContextData>): SessionImpl<TContextData>;\n\n getSession(\n origin: string | URL | Context<TContextData>,\n contextData?: TContextData,\n ): SessionImpl<TContextData> {\n const ctx = typeof origin === \"string\" || origin instanceof URL\n ? this.federation.createContext(new URL(origin), contextData!)\n : origin;\n return new SessionImpl(this, ctx);\n }\n\n async fetch(request: Request, contextData: TContextData): Promise<Response> {\n if (this.behindProxy) {\n request = await getXForwardedRequest(request);\n }\n const url = new URL(request.url);\n if (\n url.pathname.startsWith(\"/.well-known/\") ||\n url.pathname.startsWith(\"/ap/\") ||\n url.pathname.startsWith(\"/nodeinfo/\")\n ) {\n return await this.federation.fetch(request, { contextData });\n }\n const match = /^\\/emojis\\/([a-z0-9-_]+)(?:$|\\.)/.exec(url.pathname);\n if (match != null) {\n const customEmoji = this.customEmojis[match[1]];\n if (customEmoji == null || !(\"file\" in customEmoji)) {\n return new Response(\"Not Found\", { status: 404 });\n }\n let file: fs.FileHandle;\n try {\n file = await fs.open(customEmoji.file, \"r\");\n } catch (error) {\n if (\n typeof error === \"object\" && error != null && \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return new Response(\"Not Found\", { status: 404 });\n }\n throw error;\n }\n const fileInfo = await file.stat();\n return new Response(file.readableWebStream(), {\n headers: {\n \"Content-Type\": customEmoji.type,\n \"Content-Length\": fileInfo.size.toString(),\n \"Cache-Control\": \"public, max-age=31536000, immutable\",\n \"Last-Modified\": (fileInfo.mtime ?? new Date()).toUTCString(),\n \"ETag\": `\"${fileInfo.mtime?.getTime().toString(36)}${\n fileInfo.size.toString(36)\n }\"`,\n },\n });\n }\n return await app.fetch(request, { bot: this, contextData });\n }\n\n getEmoji(\n ctx: Context<TContextData>,\n name: string,\n data: CustomEmoji,\n ): APEmoji {\n let url: URL;\n if (\"url\" in data) {\n url = new URL(data.url);\n } else {\n // @ts-ignore: data.type satisfies keyof typeof mimeDb\n const t = mimeDb[data.type];\n url = new URL(\n `/emojis/${name}${\n t == null || t.extensions == null || t.extensions.length < 1\n ? \"\"\n : `.${t.extensions[0]}`\n }`,\n ctx.origin,\n );\n }\n return new APEmoji({\n id: ctx.getObjectUri(APEmoji, { name }),\n name: `:${name}:`,\n icon: new Image({\n mediaType: data.type,\n url,\n }),\n });\n }\n\n addCustomEmoji<TEmojiName extends string>(\n name: TEmojiName,\n data: CustomEmoji,\n ): DeferredCustomEmoji<TContextData> {\n if (!name.match(/^[a-z0-9-_]+$/i)) {\n throw new TypeError(\n `Invalid custom emoji name: ${name}. It must match /^[a-z0-9-_]+$/i.`,\n );\n } else if (name in this.customEmojis) {\n throw new TypeError(`Duplicate custom emoji name: ${name}`);\n } else if (!data.type.startsWith(\"image/\")) {\n throw new TypeError(`Unsupported media type: ${data.type}`);\n }\n this.customEmojis[name] = data;\n return (session: Session<TContextData>) =>\n this.getEmoji(\n session.context,\n name,\n data,\n );\n }\n\n addCustomEmojis<TEmojiName extends string>(\n emojis: Readonly<Record<TEmojiName, CustomEmoji>>,\n ): Readonly<Record<TEmojiName, DeferredCustomEmoji<TContextData>>> {\n const emojiMap = {} as Record<\n TEmojiName,\n DeferredCustomEmoji<TContextData>\n >;\n for (const name in emojis) {\n emojiMap[name] = this.addCustomEmoji(name, emojis[name]);\n }\n return emojiMap;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"bot-impl.js","names":["options: BotImplOptions<TContextData>","#summary","#properties","metadata","APEmoji","RawLike","session: Session<TContextData>","tags: (Link | Object)[]","pairs: PropertyValue[]","ctx: Context<TContextData>","identifier: string","Object","_ctx: Context<TContextData>","username: string","cursor: string | null","followers: AsyncIterable<Actor>","nextCursor: string | null","items: Recipient[]","ctx: RequestContext<TContextData>","owner: Actor | null","object: Object","items: Activity[]","nextPublished: Temporal.Instant | null","_ctx: RequestContext<TContextData>","values: { id: string }","_signedKey: CryptographicKey | null","signedKeyOwner: Actor | null","cls: new (values: any) => T","ctx: Context<TContextData> | RequestContext<TContextData>","id: string","values: { name: string }","ctx: InboxContext<TContextData>","follow: Follow","undo: Undo","accept: Accept","reject: Reject","create: Create","messageCache: Message<MessageClass, TContextData> | null","optionNotes: Note[]","options: string[]","updatedOptionNotes: Note[]","vote: Vote<TContextData>","Update","quoteUrl: URL | null","announce: Announce","object: Object | null","sharedMessage: SharedMessage<MessageClass, TContextData>","#parseLike","like: RawLike","#parseReaction","react: EmojiReact | RawLike","emoji: Emoji | APEmoji | undefined","origin: string | URL | Context<TContextData>","contextData?: TContextData","request: Request","contextData: TContextData","file: fs.FileHandle","name: string","data: CustomEmoji","url: URL","name: TEmojiName","emojis: Readonly<Record<TEmojiName, CustomEmoji>>"],"sources":["../src/bot-impl.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport {\n type Context,\n createFederation,\n type Federation,\n generateCryptoKeyPair,\n type InboxContext,\n type NodeInfo,\n Object,\n type PageItems,\n type Recipient,\n type RequestContext,\n type Software,\n Update,\n} from \"@fedify/fedify\";\nimport {\n Accept,\n type Activity,\n type Actor,\n Announce,\n type Application,\n Article,\n ChatMessage,\n Create,\n type CryptographicKey,\n Emoji as APEmoji,\n EmojiReact,\n Endpoints,\n Follow,\n Image,\n isActor,\n Like as RawLike,\n Link,\n Mention,\n Note,\n PropertyValue,\n PUBLIC_COLLECTION,\n Question,\n Reject,\n Service,\n Undo,\n} from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport mimeDb from \"mime-db\";\nimport fs from \"node:fs/promises\";\nimport { getXForwardedRequest } from \"x-forwarded-fetch\";\nimport metadata from \"../deno.json\" with { type: \"json\" };\nimport type { Bot, CreateBotOptions, PagesOptions } from \"./bot.ts\";\nimport {\n type CustomEmoji,\n type DeferredCustomEmoji,\n type Emoji,\n isEmoji,\n} from \"./emoji.ts\";\nimport type {\n AcceptEventHandler,\n FollowEventHandler,\n LikeEventHandler,\n MentionEventHandler,\n MessageEventHandler,\n QuoteEventHandler,\n ReactionEventHandler,\n RejectEventHandler,\n ReplyEventHandler,\n SharedMessageEventHandler,\n UndoneReactionEventHandler,\n UnfollowEventHandler,\n UnlikeEventHandler,\n VoteEventHandler,\n} from \"./events.ts\";\nimport { FollowRequestImpl } from \"./follow-impl.ts\";\nimport {\n createMessage,\n getMessageVisibility,\n isMessageObject,\n isQuoteLink,\n messageClasses,\n} from \"./message-impl.ts\";\nimport type { Message, MessageClass, SharedMessage } from \"./message.ts\";\nimport { app } from \"./pages.tsx\";\nimport type { Vote } from \"./poll.ts\";\nimport type { Like, Reaction } from \"./reaction.ts\";\nimport { KvRepository, type Repository, type Uuid } from \"./repository.ts\";\nimport { SessionImpl } from \"./session-impl.ts\";\nimport type { Session } from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nexport interface BotImplOptions<TContextData>\n extends CreateBotOptions<TContextData> {\n collectionWindow?: number;\n}\n\nexport class BotImpl<TContextData> implements Bot<TContextData> {\n readonly identifier: string;\n readonly class: typeof Service | typeof Application;\n readonly username: string;\n readonly name?: string;\n readonly summary?: Text<\"block\", TContextData>;\n #summary: { text: string; tags: (Link | Object)[] } | null;\n readonly icon?: URL | Image;\n readonly image?: URL | Image;\n readonly properties: Record<string, Text<\"block\" | \"inline\", TContextData>>;\n #properties: { pairs: PropertyValue[]; tags: (Link | Object)[] } | null;\n readonly followerPolicy: \"accept\" | \"reject\" | \"manual\";\n readonly customEmojis: Record<string, CustomEmoji>;\n readonly repository: Repository;\n readonly software?: Software;\n readonly behindProxy: boolean;\n readonly pages: Required<PagesOptions>;\n readonly collectionWindow: number;\n readonly federation: Federation<TContextData>;\n\n onFollow?: FollowEventHandler<TContextData>;\n onUnfollow?: UnfollowEventHandler<TContextData>;\n onAcceptFollow?: AcceptEventHandler<TContextData>;\n onRejectFollow?: RejectEventHandler<TContextData>;\n onMention?: MentionEventHandler<TContextData>;\n onReply?: ReplyEventHandler<TContextData>;\n onQuote?: QuoteEventHandler<TContextData>;\n onMessage?: MessageEventHandler<TContextData>;\n onSharedMessage?: SharedMessageEventHandler<TContextData>;\n onLike?: LikeEventHandler<TContextData>;\n onUnlike?: UnlikeEventHandler<TContextData>;\n onReact?: ReactionEventHandler<TContextData>;\n onUnreact?: UndoneReactionEventHandler<TContextData>;\n onVote?: VoteEventHandler<TContextData>;\n\n constructor(options: BotImplOptions<TContextData>) {\n this.identifier = options.identifier ?? \"bot\";\n this.class = options.class ?? Service;\n this.username = options.username;\n this.name = options.name;\n this.summary = options.summary;\n this.#summary = null;\n this.icon = options.icon;\n this.image = options.image;\n this.properties = options.properties ?? {};\n this.#properties = null;\n this.followerPolicy = options.followerPolicy ?? \"accept\";\n this.customEmojis = {};\n this.repository = options.repository ?? new KvRepository(options.kv);\n this.software = options.software;\n this.pages = {\n color: \"green\",\n css: \"\",\n ...(options.pages ?? {}),\n };\n this.federation = createFederation<TContextData>({\n kv: options.kv,\n queue: options.queue,\n userAgent: {\n software: `BotKit/${metadata.version}`,\n },\n });\n this.behindProxy = options.behindProxy ?? false;\n this.collectionWindow = options.collectionWindow ?? 50;\n this.initialize();\n }\n\n initialize(): void {\n this.federation\n .setActorDispatcher(\n \"/ap/actor/{identifier}\",\n this.dispatchActor.bind(this),\n )\n .mapHandle(this.mapHandle.bind(this))\n .setKeyPairsDispatcher(this.dispatchActorKeyPairs.bind(this));\n this.federation\n .setFollowersDispatcher(\n \"/ap/actor/{identifier}/followers\",\n this.dispatchFollowers.bind(this),\n )\n .setFirstCursor(this.getFollowersFirstCursor.bind(this))\n .setCounter(this.countFollowers.bind(this));\n this.federation\n .setOutboxDispatcher(\n \"/ap/actor/{identifier}/outbox\",\n this.dispatchOutbox.bind(this),\n )\n .setFirstCursor(this.getOutboxFirstCursor.bind(this))\n .setCounter(this.countOutbox.bind(this));\n this.federation\n .setObjectDispatcher(\n Follow,\n \"/ap/follow/{id}\",\n this.dispatchFollow.bind(this),\n )\n .authorize(this.authorizeFollow.bind(this));\n this.federation.setObjectDispatcher(\n Create,\n \"/ap/create/{id}\",\n this.dispatchCreate.bind(this),\n );\n this.federation.setObjectDispatcher(\n Article,\n \"/ap/article/{id}\",\n (ctx, values) => this.dispatchMessage(Article, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n ChatMessage,\n \"/ap/chat-message/{id}\",\n (ctx, values) => this.dispatchMessage(ChatMessage, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Note,\n \"/ap/note/{id}\",\n (ctx, values) => this.dispatchMessage(Note, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Question,\n \"/ap/question/{id}\",\n (ctx, values) => this.dispatchMessage(Question, ctx, values.id),\n );\n this.federation.setObjectDispatcher(\n Announce,\n \"/ap/announce/{id}\",\n this.dispatchAnnounce.bind(this),\n );\n this.federation.setObjectDispatcher(\n APEmoji,\n \"/ap/emoji/{name}\",\n this.dispatchEmoji.bind(this),\n );\n this.federation\n .setInboxListeners(\"/ap/actor/{identifier}/inbox\", \"/ap/inbox\")\n .on(Follow, this.onFollowed.bind(this))\n .on(Undo, async (ctx, undo) => {\n const object = await undo.getObject(ctx);\n if (object instanceof Follow) await this.onUnfollowed(ctx, undo);\n else if (object instanceof RawLike) await this.onUnliked(ctx, undo);\n else {\n const logger = getLogger([\"botkit\", \"bot\", \"inbox\"]);\n logger.warn(\n \"The Undo object {undoId} is not about Follow or Like: {object}.\",\n { undoId: undo.id?.href, object },\n );\n }\n })\n .on(Accept, this.onFollowAccepted.bind(this))\n .on(Reject, this.onFollowRejected.bind(this))\n .on(Create, this.onCreated.bind(this))\n .on(Announce, this.onAnnounced.bind(this))\n .on(RawLike, this.onLiked.bind(this))\n .setSharedKeyDispatcher(this.dispatchSharedKey.bind(this));\n if (this.software != null) {\n this.federation.setNodeInfoDispatcher(\n \"/nodeinfo/2.1\",\n this.dispatchNodeInfo.bind(this),\n );\n }\n }\n\n async getActorSummary(\n session: Session<TContextData>,\n ): Promise<{ text: string; tags: (Link | Object)[] } | null> {\n if (this.summary == null) return null;\n if (this.#summary == null) {\n let summary = \"\";\n const tags: (Link | Object)[] = [];\n for await (const chunk of this.summary.getHtml(session)) {\n summary += chunk;\n }\n for await (const tag of this.summary.getTags(session)) {\n tags.push(tag);\n }\n return this.#summary = { text: summary, tags };\n }\n return this.#summary;\n }\n\n async getActorProperties(\n session: Session<TContextData>,\n ): Promise<{ pairs: PropertyValue[]; tags: (Link | Object)[] }> {\n if (this.#properties != null) return this.#properties;\n const pairs: PropertyValue[] = [];\n const tags: (Link | Object)[] = [];\n for (const name in this.properties) {\n const value = this.properties[name];\n const pair = new PropertyValue({\n name,\n value: (await Array.fromAsync(value.getHtml(session))).join(\"\"),\n });\n pairs.push(pair);\n for await (const tag of value.getTags(session)) {\n tags.push(tag);\n }\n }\n return this.#properties = { pairs, tags };\n }\n\n async dispatchActor(\n ctx: Context<TContextData>,\n identifier: string,\n ): Promise<Actor | null> {\n if (this.identifier !== identifier) return null;\n const session = this.getSession(ctx);\n const summary = await this.getActorSummary(session);\n const { pairs, tags } = await this.getActorProperties(session);\n const allTags = summary == null ? tags : [...tags, ...summary.tags];\n const keyPairs = await ctx.getActorKeyPairs(identifier);\n return new this.class({\n id: ctx.getActorUri(identifier),\n preferredUsername: this.username,\n name: this.name,\n summary: summary == null ? null : summary.text,\n attachments: pairs,\n tags: allTags.filter((tag, i) =>\n allTags.findIndex((t) =>\n t.name?.toString() === tag.name?.toString() &&\n (t instanceof Link\n ? tag instanceof Link && t.href?.href === tag.href?.href\n : tag instanceof Object && t.id?.href === tag.id?.href)\n ) === i\n ),\n icon: this.icon == null\n ? null\n : this.icon instanceof Image\n ? this.icon\n : new Image({ url: this.icon }),\n image: this.image == null\n ? null\n : this.image instanceof Image\n ? this.image\n : new Image({ url: this.image }),\n inbox: ctx.getInboxUri(identifier),\n endpoints: new Endpoints({\n sharedInbox: ctx.getInboxUri(),\n }),\n followers: ctx.getFollowersUri(identifier),\n outbox: ctx.getOutboxUri(identifier),\n publicKey: keyPairs[0].cryptographicKey,\n assertionMethods: keyPairs.map((pair) => pair.multikey),\n url: new URL(\"/\", ctx.origin),\n });\n }\n\n mapHandle(_ctx: Context<TContextData>, username: string): string | null {\n return username === this.username ? this.identifier : null;\n }\n\n async dispatchActorKeyPairs(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<CryptoKeyPair[]> {\n if (identifier !== this.identifier) return [];\n let keyPairs = await this.repository.getKeyPairs();\n if (keyPairs == null) {\n const rsa = await generateCryptoKeyPair(\"RSASSA-PKCS1-v1_5\");\n const ed25519 = await generateCryptoKeyPair(\"Ed25519\");\n keyPairs = [rsa, ed25519];\n await this.repository.setKeyPairs(keyPairs);\n }\n return keyPairs;\n }\n\n async dispatchFollowers(\n _ctx: Context<TContextData>,\n identifier: string,\n cursor: string | null,\n ): Promise<PageItems<Recipient> | null> {\n if (identifier !== this.identifier) return null;\n let followers: AsyncIterable<Actor>;\n let nextCursor: string | null;\n if (cursor == null) {\n followers = this.repository.getFollowers();\n nextCursor = null;\n } else {\n const offset = cursor.match(/^\\d+$/) ? parseInt(cursor) : 0;\n followers = this.repository.getFollowers({\n offset,\n limit: this.collectionWindow,\n });\n nextCursor = (offset + this.collectionWindow).toString();\n }\n const items: Recipient[] = [];\n let i = 0;\n for await (const follower of followers) {\n items.push(follower);\n i++;\n }\n if (i < this.collectionWindow) nextCursor = null;\n return { items, nextCursor };\n }\n\n getFollowersFirstCursor(\n _ctx: Context<TContextData>,\n identifier: string,\n ): string | null {\n if (identifier !== this.identifier) return null;\n return \"0\";\n }\n\n async countFollowers(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<number | null> {\n if (identifier !== this.identifier) return null;\n return await this.repository.countFollowers();\n }\n\n async getPermissionChecker(\n ctx: RequestContext<TContextData>,\n ): Promise<(object: Object) => boolean> {\n let owner: Actor | null;\n try {\n owner = await ctx.getSignedKeyOwner();\n } catch {\n owner = null;\n }\n let follower = false;\n const ownerUri = owner?.id;\n if (ownerUri != null) {\n follower = await this.repository.hasFollower(ownerUri);\n }\n const followersUri = ctx.getFollowersUri(this.identifier);\n return (object: Object): boolean => {\n const recipients = [...object.toIds, ...object.ccIds].map((u) => u.href);\n if (recipients.includes(PUBLIC_COLLECTION.href)) return true;\n if (recipients.includes(followersUri.href) && follower) return true;\n return ownerUri == null ? false : recipients.includes(ownerUri.href);\n };\n }\n\n async dispatchOutbox(\n ctx: RequestContext<TContextData>,\n identifier: string,\n cursor: string | null,\n ): Promise<PageItems<Activity> | null> {\n if (identifier !== this.identifier) return null;\n const activities = this.repository.getMessages({\n order: \"newest\",\n until: cursor == null || cursor === \"\"\n ? undefined\n : Temporal.Instant.from(cursor),\n limit: cursor == null ? undefined : this.collectionWindow + 1,\n });\n const items: Activity[] = [];\n const isVisible = await this.getPermissionChecker(ctx);\n let i = 0;\n let nextPublished: Temporal.Instant | null = null;\n for await (const activity of activities) {\n if (cursor != null && i >= this.collectionWindow) {\n nextPublished = activity.published ??\n (await activity.getObject())?.published ?? null;\n break;\n }\n if (isVisible(activity)) items.push(activity);\n i++;\n }\n return { items, nextCursor: nextPublished?.toString() ?? null };\n }\n\n getOutboxFirstCursor(\n _ctx: Context<TContextData>,\n identifier: string,\n ): string | null {\n if (identifier !== this.identifier) return null;\n return \"\";\n }\n\n async countOutbox(\n _ctx: Context<TContextData>,\n identifier: string,\n ): Promise<number | null> {\n if (identifier !== this.identifier) return null;\n return await this.repository.countMessages();\n }\n\n async dispatchFollow(\n _ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Follow | null> {\n const id = values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n return follow ?? null;\n }\n\n async authorizeFollow(\n _ctx: RequestContext<TContextData>,\n values: { id: string },\n _signedKey: CryptographicKey | null,\n signedKeyOwner: Actor | null,\n ): Promise<boolean> {\n if (signedKeyOwner == null || signedKeyOwner.id == null) return false;\n const id = values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n if (follow == null) return false;\n return signedKeyOwner.id.href === follow.objectId?.href ||\n signedKeyOwner.id.href === follow.actorId?.href;\n }\n\n async dispatchCreate(\n ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Create | null> {\n const activity = await this.repository.getMessage(values.id as Uuid);\n if (!(activity instanceof Create)) return null;\n const isVisible = await this.getPermissionChecker(ctx);\n return isVisible(activity) ? activity : null;\n }\n\n async dispatchMessage<T extends MessageClass>(\n // deno-lint-ignore no-explicit-any\n cls: new (values: any) => T,\n ctx: Context<TContextData> | RequestContext<TContextData>,\n id: string,\n ): Promise<T | null> {\n const activity = await this.repository.getMessage(id as Uuid);\n if (!(activity instanceof Create)) return null;\n if (\"request\" in ctx) {\n // TODO: Split this method into two\n const isVisible = await this.getPermissionChecker(ctx);\n if (!isVisible(activity)) return null;\n }\n const object = await activity.getObject(ctx);\n if (object == null || !(object instanceof cls)) return null;\n return object;\n }\n\n async dispatchAnnounce(\n ctx: RequestContext<TContextData>,\n values: { id: string },\n ): Promise<Announce | null> {\n const activity = await this.repository.getMessage(values.id as Uuid);\n if (!(activity instanceof Announce)) return null;\n const isVisible = await this.getPermissionChecker(ctx);\n return isVisible(activity) ? activity : null;\n }\n\n dispatchEmoji(\n ctx: Context<TContextData>,\n values: { name: string },\n ): APEmoji | null {\n const customEmoji = this.customEmojis[values.name];\n if (customEmoji == null) return null;\n return this.getEmoji(ctx, values.name, customEmoji);\n }\n\n dispatchSharedKey(_ctx: Context<TContextData>): { identifier: string } {\n return { identifier: this.identifier };\n }\n\n async onFollowed(\n ctx: InboxContext<TContextData>,\n follow: Follow,\n ): Promise<void> {\n const botUri = ctx.getActorUri(this.identifier);\n if (\n follow.actorId?.href === botUri.href ||\n follow.objectId?.href !== botUri.href\n ) {\n return;\n }\n const follower = await follow.getActor({\n contextLoader: ctx.contextLoader,\n documentLoader: ctx.documentLoader,\n suppressError: true,\n });\n if (follower == null || follower.id == null) return;\n const session = this.getSession(ctx);\n const followRequest = new FollowRequestImpl<TContextData>(\n session,\n follow,\n follower,\n );\n await this.onFollow?.(session, followRequest);\n if (followRequest.state === \"pending\") {\n if (this.followerPolicy === \"accept\") await followRequest.accept();\n else if (this.followerPolicy === \"reject\") await followRequest.reject();\n }\n }\n\n async onUnfollowed(\n ctx: InboxContext<TContextData>,\n undo: Undo,\n ): Promise<void> {\n const followId = undo.objectId;\n if (followId == null || undo.actorId == null) return;\n const follower = await this.repository.removeFollower(\n followId,\n undo.actorId,\n );\n if (this.onUnfollow != null && follower != null) {\n const session = this.getSession(ctx);\n await this.onUnfollow(session, follower);\n }\n }\n\n async onFollowAccepted(\n ctx: InboxContext<TContextData>,\n accept: Accept,\n ): Promise<void> {\n const parsedObj = ctx.parseUri(accept.objectId);\n if (parsedObj?.type !== \"object\" || parsedObj.class !== Follow) return;\n const follow = await this.repository.getSentFollow(\n parsedObj.values.id as Uuid,\n );\n if (follow == null) return;\n const followee = await follow.getObject(ctx);\n if (\n !isActor(followee) || followee.id == null ||\n followee.id.href !== accept.actorId?.href\n ) {\n return;\n }\n await this.repository.addFollowee(followee.id, follow);\n if (this.onAcceptFollow != null) {\n const session = this.getSession(ctx);\n await this.onAcceptFollow(session, followee);\n }\n }\n\n async onFollowRejected(\n ctx: InboxContext<TContextData>,\n reject: Reject,\n ): Promise<void> {\n const parsedObj = ctx.parseUri(reject.objectId);\n if (parsedObj?.type !== \"object\" || parsedObj.class !== Follow) return;\n const id = parsedObj.values.id as Uuid;\n const follow = await this.repository.getSentFollow(id);\n if (follow == null) return;\n const followee = await follow.getObject(ctx);\n if (\n !isActor(followee) || followee.id == null ||\n followee.id.href !== reject.actorId?.href\n ) {\n return;\n }\n await this.repository.removeSentFollow(id);\n if (this.onRejectFollow != null) {\n const session = this.getSession(ctx);\n await this.onRejectFollow(session, followee);\n }\n }\n\n async onCreated(\n ctx: InboxContext<TContextData>,\n create: Create,\n ): Promise<void> {\n const object = await create.getObject(ctx);\n if (\n !(object instanceof Article || object instanceof ChatMessage ||\n object instanceof Note || object instanceof Question) ||\n object.attributionId?.href !== create.actorId?.href\n ) {\n return;\n }\n const session = this.getSession(ctx);\n let messageCache: Message<MessageClass, TContextData> | null = null;\n const getMessage = async () => {\n if (messageCache != null) return messageCache;\n return messageCache = await createMessage(object, session, {});\n };\n const replyTarget = ctx.parseUri(object.replyTargetId);\n if (\n this.onVote != null &&\n object instanceof Note && replyTarget?.type === \"object\" &&\n // @ts-ignore: replyTarget.class satisfies (typeof messageClasses)[number]\n messageClasses.includes(replyTarget.class) &&\n object.name != null\n ) {\n if (create.actorId?.href === session.actorId.href) return;\n const actor = await create.getActor(ctx);\n if (actor == null) return;\n const pollMessage = await this.repository.getMessage(\n replyTarget.values.id as Uuid,\n );\n if (!(pollMessage instanceof Create)) return;\n const question = await pollMessage.getObject(ctx);\n if (\n !(question instanceof Question) || question.endTime == null ||\n Temporal.Instant.compare(question.endTime, Temporal.Now.instant()) < 0\n ) {\n return;\n }\n const optionNotes: Note[] = [];\n const options: string[] = [];\n for await (const note of question.getInclusiveOptions(ctx)) {\n if (!(note instanceof Note)) continue;\n optionNotes.push(note);\n if (note.name != null) options.push(note.name.toString());\n }\n const multiple = options.length > 0;\n for await (const note of question.getExclusiveOptions(ctx)) {\n if (!(note instanceof Note)) continue;\n optionNotes.push(note);\n if (note.name != null) options.push(note.name.toString());\n }\n const option = object.name.toString();\n if (!options.includes(option)) return;\n const updatedOptionNotes: Note[] = [...optionNotes];\n let i = 0;\n for (const note of updatedOptionNotes) {\n if (note.name === option) {\n const replies = await note.getReplies(ctx);\n if (replies != null && replies.totalItems != null) {\n updatedOptionNotes[i] = note.clone({\n replies: replies.clone({\n // FIXME: This way of updating vote count is not only inefficient,\n // but also can lead to incorrect counts if multiple votes are\n // cast at the same time.\n totalItems: replies.totalItems + 1,\n }),\n });\n }\n }\n i++;\n }\n const updatedQuestion = question.clone({\n inclusiveOptions: multiple ? updatedOptionNotes : [],\n exclusiveOptions: !multiple ? updatedOptionNotes : [],\n });\n const updatedPollMessage = pollMessage.clone({\n object: updatedQuestion,\n });\n await this.repository.updateMessage(\n replyTarget.values.id as Uuid,\n () => updatedPollMessage,\n );\n const message = await createMessage(updatedQuestion, session, {});\n const vote: Vote<TContextData> = {\n raw: object,\n actor,\n message,\n poll: {\n multiple,\n options,\n endTime: question.endTime,\n },\n option,\n };\n await this.onVote(session, vote);\n const update = new Update({\n id: new URL(\n `#update-votes/${Date.now()}`,\n updatedQuestion.id ?? ctx.origin,\n ),\n actor: ctx.getActorUri(this.identifier),\n object: updatedPollMessage.id,\n tos: updatedPollMessage.toIds,\n ccs: updatedPollMessage.ccIds,\n });\n if (message.visibility === \"direct\") {\n await ctx.forwardActivity(this, [...message.mentions], {\n skipIfUnsigned: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n await ctx.sendActivity(\n this,\n [...message.mentions],\n update,\n { excludeBaseUris: [new URL(ctx.origin)] },\n );\n } else {\n await ctx.forwardActivity(this, \"followers\", {\n skipIfUnsigned: true,\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n await ctx.sendActivity(\n this,\n \"followers\",\n update,\n {\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n },\n );\n }\n return;\n }\n if (\n this.onReply != null &&\n replyTarget?.type === \"object\" &&\n // @ts-ignore: replyTarget.class satisfies (typeof messageClasses)[number]\n messageClasses.includes(replyTarget.class)\n ) {\n const message = await getMessage();\n if (\n message.visibility === \"public\" || message.visibility === \"unlisted\"\n ) {\n await ctx.forwardActivity(this, \"followers\", {\n skipIfUnsigned: true,\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n }\n await this.onReply(session, message);\n }\n let quoteUrl: URL | null = null;\n // FIXME: eliminate this duplication\n for await (const tag of object.getTags(ctx)) {\n if (tag instanceof Link && isQuoteLink(tag)) {\n quoteUrl = tag.href;\n break;\n }\n }\n if (quoteUrl == null) quoteUrl = object.quoteUrl;\n const quoteTarget = ctx.parseUri(quoteUrl);\n if (\n this.onQuote != null &&\n quoteTarget?.type === \"object\" &&\n // @ts-ignore: quoteTarget.class satisfies (typeof messageClasses)[number]\n messageClasses.includes(quoteTarget.class)\n ) {\n const message = await getMessage();\n if (\n message.visibility === \"public\" || message.visibility === \"unlisted\"\n ) {\n await ctx.forwardActivity(this, \"followers\", {\n skipIfUnsigned: true,\n preferSharedInbox: true,\n excludeBaseUris: [new URL(ctx.origin)],\n });\n }\n await this.onQuote(session, message);\n }\n for await (const tag of object.getTags(ctx)) {\n if (\n tag instanceof Mention && tag.href != null && this.onMention != null\n ) {\n const parsed = ctx.parseUri(tag.href);\n if (\n parsed?.type === \"actor\" && parsed.identifier === this.identifier\n ) {\n await this.onMention(session, await getMessage());\n break;\n }\n }\n }\n if (this.onMessage != null) {\n await this.onMessage(session, await getMessage());\n }\n }\n\n async onAnnounced(\n ctx: InboxContext<TContextData>,\n announce: Announce,\n ): Promise<void> {\n if (\n this.onSharedMessage == null || announce.id == null ||\n announce.actorId == null\n ) return;\n const objectUri = ctx.parseUri(announce.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await announce.getObject(ctx);\n }\n if (!isMessageObject(object)) return;\n const session = this.getSession(ctx);\n const actor = announce.actorId.href == session.actorId.href\n ? await session.getActor()\n : await announce.getActor(ctx);\n if (actor == null) return;\n const original = await createMessage(object, session, {});\n const sharedMessage: SharedMessage<MessageClass, TContextData> = {\n raw: announce,\n id: announce.id,\n actor,\n visibility: getMessageVisibility(announce.toIds, announce.ccIds, actor),\n original,\n };\n await this.onSharedMessage(session, sharedMessage);\n }\n\n async #parseLike(\n ctx: InboxContext<TContextData>,\n like: RawLike,\n ): Promise<\n { session: Session<TContextData>; like: Like<TContextData> } | undefined\n > {\n if (like.id == null || like.actorId == null) return undefined;\n const objectUri = ctx.parseUri(like.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await like.getObject(ctx);\n }\n if (!isMessageObject(object)) return undefined;\n const session = this.getSession(ctx);\n const actor = like.actorId.href == session.actorId.href\n ? await session.getActor()\n : await like.getActor(ctx);\n if (actor == null) return;\n const message = await createMessage(object, session, {});\n return {\n session,\n like: {\n raw: like,\n id: like.id,\n actor,\n message,\n },\n };\n }\n\n async onLiked(ctx: InboxContext<TContextData>, like: RawLike): Promise<void> {\n if (like.name != null) return this.onReacted(ctx, like);\n if (this.onLike == null) return;\n const sessionAndLike = await this.#parseLike(ctx, like);\n if (sessionAndLike == null) return;\n const { session, like: likeObject } = sessionAndLike;\n await this.onLike(session, likeObject);\n }\n\n async onUnliked(ctx: InboxContext<TContextData>, undo: Undo): Promise<void> {\n const like = await undo.getObject(ctx);\n if (!(like instanceof RawLike)) return;\n if (like.name != null) return this.onUnreacted(ctx, undo);\n if (this.onUnlike == null) return;\n if (undo.actorId?.href !== like.actorId?.href) return;\n const sessionAndLike = await this.#parseLike(ctx, like);\n if (sessionAndLike == null) return;\n const { session, like: likeObject } = sessionAndLike;\n await this.onUnlike(session, likeObject);\n }\n\n async #parseReaction(\n ctx: InboxContext<TContextData>,\n react: EmojiReact | RawLike,\n ): Promise<\n | { session: Session<TContextData>; reaction: Reaction<TContextData> }\n | undefined\n > {\n if (react.id == null || react.actorId == null || react.name == null) {\n return undefined;\n }\n let emoji: Emoji | APEmoji | undefined;\n if (isEmoji(react.name)) {\n emoji = react.name;\n } else if (\n typeof react.name === \"string\" && react.name.startsWith(\":\") &&\n react.name.endsWith(\":\")\n ) {\n for await (const tag of react.getTags(ctx)) {\n if (tag instanceof APEmoji && tag.name === react.name) {\n emoji = tag;\n break;\n }\n }\n }\n if (emoji == null) return undefined;\n const objectUri = ctx.parseUri(react.objectId);\n let object: Object | null = null;\n if (\n objectUri?.type === \"object\" &&\n // deno-lint-ignore no-explicit-any\n messageClasses.includes(objectUri.class as any)\n ) {\n const msg = await this.repository.getMessage(objectUri.values.id as Uuid);\n if (msg instanceof Create) object = await msg.getObject(ctx);\n } else {\n object = await react.getObject(ctx);\n }\n if (!isMessageObject(object)) return undefined;\n const session = this.getSession(ctx);\n const actor = react.actorId.href == session.actorId.href\n ? await session.getActor()\n : await react.getActor(ctx);\n if (actor == null) return;\n const message = await createMessage(object, session, {});\n return {\n session,\n reaction: {\n raw: react,\n id: react.id,\n actor,\n message,\n emoji,\n },\n };\n }\n\n async onReacted(\n ctx: InboxContext<TContextData>,\n react: EmojiReact | RawLike,\n ): Promise<void> {\n if (this.onReact == null) return;\n const sessionAndReaction = await this.#parseReaction(ctx, react);\n if (sessionAndReaction == null) return;\n const { session, reaction } = sessionAndReaction;\n await this.onReact(session, reaction);\n }\n\n async onUnreacted(\n ctx: InboxContext<TContextData>,\n undo: Undo,\n ): Promise<void> {\n if (this.onUnreact == null) return;\n const react = await undo.getObject(ctx);\n if (!(react instanceof EmojiReact || react instanceof RawLike)) return;\n if (undo.actorId?.href !== react.actorId?.href) return;\n const sessionAndReaction = await this.#parseReaction(ctx, react);\n if (sessionAndReaction == null) return;\n const { session, reaction } = sessionAndReaction;\n await this.onUnreact(session, reaction);\n }\n\n dispatchNodeInfo(_ctx: Context<TContextData>): NodeInfo {\n return {\n software: this.software!,\n protocols: [\"activitypub\"],\n services: {\n outbound: [\"atom1.0\"], // TODO\n },\n usage: {\n users: {\n total: 1,\n activeMonth: 1, // FIXME\n activeHalfyear: 1, // FIXME\n },\n localPosts: 0, // FIXME\n localComments: 0,\n },\n };\n }\n\n getSession(\n origin: string | URL,\n contextData: TContextData,\n ): SessionImpl<TContextData>;\n getSession(origin: string | URL): SessionImpl<TContextData>;\n getSession(context: Context<TContextData>): SessionImpl<TContextData>;\n\n getSession(\n origin: string | URL | Context<TContextData>,\n contextData?: TContextData,\n ): SessionImpl<TContextData> {\n const ctx = typeof origin === \"string\" || origin instanceof URL\n ? this.federation.createContext(new URL(origin), contextData!)\n : origin;\n return new SessionImpl(this, ctx);\n }\n\n async fetch(request: Request, contextData: TContextData): Promise<Response> {\n if (this.behindProxy) {\n request = await getXForwardedRequest(request);\n }\n const url = new URL(request.url);\n if (\n url.pathname.startsWith(\"/.well-known/\") ||\n url.pathname.startsWith(\"/ap/\") ||\n url.pathname.startsWith(\"/nodeinfo/\")\n ) {\n return await this.federation.fetch(request, { contextData });\n }\n const match = /^\\/emojis\\/([a-z0-9-_]+)(?:$|\\.)/.exec(url.pathname);\n if (match != null) {\n const customEmoji = this.customEmojis[match[1]];\n if (customEmoji == null || !(\"file\" in customEmoji)) {\n return new Response(\"Not Found\", { status: 404 });\n }\n let file: fs.FileHandle;\n try {\n file = await fs.open(customEmoji.file, \"r\");\n } catch (error) {\n if (\n typeof error === \"object\" && error != null && \"code\" in error &&\n error.code === \"ENOENT\"\n ) {\n return new Response(\"Not Found\", { status: 404 });\n }\n throw error;\n }\n const fileInfo = await file.stat();\n return new Response(file.readableWebStream(), {\n headers: {\n \"Content-Type\": customEmoji.type,\n \"Content-Length\": fileInfo.size.toString(),\n \"Cache-Control\": \"public, max-age=31536000, immutable\",\n \"Last-Modified\": (fileInfo.mtime ?? new Date()).toUTCString(),\n \"ETag\": `\"${fileInfo.mtime?.getTime().toString(36)}${\n fileInfo.size.toString(36)\n }\"`,\n },\n });\n }\n return await app.fetch(request, { bot: this, contextData });\n }\n\n getEmoji(\n ctx: Context<TContextData>,\n name: string,\n data: CustomEmoji,\n ): APEmoji {\n let url: URL;\n if (\"url\" in data) {\n url = new URL(data.url);\n } else {\n // @ts-ignore: data.type satisfies keyof typeof mimeDb\n const t = mimeDb[data.type];\n url = new URL(\n `/emojis/${name}${\n t == null || t.extensions == null || t.extensions.length < 1\n ? \"\"\n : `.${t.extensions[0]}`\n }`,\n ctx.origin,\n );\n }\n return new APEmoji({\n id: ctx.getObjectUri(APEmoji, { name }),\n name: `:${name}:`,\n icon: new Image({\n mediaType: data.type,\n url,\n }),\n });\n }\n\n addCustomEmoji<TEmojiName extends string>(\n name: TEmojiName,\n data: CustomEmoji,\n ): DeferredCustomEmoji<TContextData> {\n if (!name.match(/^[a-z0-9-_]+$/i)) {\n throw new TypeError(\n `Invalid custom emoji name: ${name}. It must match /^[a-z0-9-_]+$/i.`,\n );\n } else if (name in this.customEmojis) {\n throw new TypeError(`Duplicate custom emoji name: ${name}`);\n } else if (!data.type.startsWith(\"image/\")) {\n throw new TypeError(`Unsupported media type: ${data.type}`);\n }\n this.customEmojis[name] = data;\n return (session: Session<TContextData>) =>\n this.getEmoji(\n session.context,\n name,\n data,\n );\n }\n\n addCustomEmojis<TEmojiName extends string>(\n emojis: Readonly<Record<TEmojiName, CustomEmoji>>,\n ): Readonly<Record<TEmojiName, DeferredCustomEmoji<TContextData>>> {\n const emojiMap = {} as Record<\n TEmojiName,\n DeferredCustomEmoji<TContextData>\n >;\n for (const name in emojis) {\n emojiMap[name] = this.addCustomEmoji(name, emojis[name]);\n }\n return emojiMap;\n }\n}\n"],"mappings":"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"}