import type { MessagePageOptions } from "./discord-client.js"; import type { ScopePolicy } from "./policy.js"; import type { DiscordChannel, DiscordMessage, RequestOptions } from "./types.js"; export interface CommunityActivityChannelSelection { beforeMessageId?: string; channelId: string; } export interface CommunityActivityRequest { channels: readonly CommunityActivityChannelSelection[]; guildId: string; maxMessagesPerChannel?: number; } export interface NormalizedCommunityActivityRequest { channels: CommunityActivityChannelSelection[]; guildId: string; maxMessagesPerChannel: number; } export interface CommunityActivityServiceClient { getChannel(channelId: string, options?: RequestOptions): Promise; listMessages(channelId: string, options?: MessagePageOptions): Promise; } export interface CommunityActivityServiceOptions { client: CommunityActivityServiceClient; policy: Pick; } type PaginationStop = "empty-page" | "request-limit" | "short-page"; export declare function normalizeCommunityActivityRequest(request: CommunityActivityRequest): NormalizedCommunityActivityRequest; export declare class CommunityActivityService { #private; constructor(options: CommunityActivityServiceOptions); analyze(request: CommunityActivityRequest, options?: RequestOptions): Promise<{ activity: { botMessages: number; conversationMessages: number; humanMessages: number; humanParticipants: number; nonConversationMessages: number; otherConversationMessages: number; webhookMessages: number; activeUtcDays: number; messagesFetched: number; }; participation: { multiDayParticipantRate: number | null; multiDayParticipants: number; topFiveParticipantMessageShare: number | null; topParticipantMessageShare: number | null; }; reciprocity: { directedRelationships: number; participantPairs: number; reciprocalPairRate: number | null; reciprocalPairs: number; }; responsiveness: { humanAuthoredExplicitReplies: number; humanToDifferentHumanReplies: number; latencyPairs: number; medianSeconds: number | null; nonHumanTargetReplies: number; p75Seconds: number | null; p90Seconds: number | null; sampledHumanMessagesReceivingReply: number; sampledHumanMessagesWithoutObservedReply: number; selfReplies: number; unresolvedTargetReplies: number; }; timing: { hoursUtc: { hour: number; messageCount: number; }[]; weekdaysUtc: { messageCount: number; weekday: "Friday" | "Monday" | "Saturday" | "Sunday" | "Thursday" | "Tuesday" | "Wednesday"; }[]; }; coverage: { channels: { botMessages: number; conversationMessages: number; humanMessages: number; humanParticipants: number; nonConversationMessages: number; otherConversationMessages: number; webhookMessages: number; beforeMessageId: string | null; channelId: string; messagesFetched: number; newestObservedAt: string | null; nextBeforeMessageId: string | null; oldestObservedAt: string | null; pagesRequested: number; paginationStop: PaginationStop; }[]; channelsRequested: number; maximumMessages: number; maxMessagesPerChannel: number; messagesFetched: number; newestObservedAt: string | null; oldestObservedAt: string | null; }; definitions: Readonly<{ explicitHumanReply: "A Discord Reply authored by a human participant with a different resolved human target."; humanParticipant: "An ordinary Discord message author that is not a bot, system user, or webhook."; multiDayParticipant: "A human participant with sampled messages on at least two UTC dates."; participantMessageShare: "The selected participants' human-message count divided by all sampled human messages."; reciprocalPair: "An unordered human-participant pair with observed explicit replies in both directions."; replyLatency: "Elapsed seconds from a resolved target message to a later explicit human reply, summarized with nearest-rank percentiles."; }>; guildId: string; limitations: readonly ["A bounded message sample does not establish whole-community behavior or causality.", "Explicit replies undercount conversational responses that do not use Discord's Reply action.", "Reply latency covers only targets present in the sample or resolved by Discord.", "A short or empty page does not prove complete history because Discord can return no messages when Read Message History is unavailable.", "UTC activity distributions may not match participants' local time zones.", "Message content is not used, so themes, topics, sentiment, and intent are outside this analysis."]; privacy: Readonly<{ content: "not-used"; identities: "transient-aggregate-only"; names: "omitted"; persistence: "none"; profiles: "omitted"; rawPayloads: "omitted"; }>; schemaVersion: number; status: "ok"; }>; } export {}; //# sourceMappingURL=community-activity-service.d.ts.map