refactor(onebot): inline ctx.bridge.apis.friend/interaction/message direct calls

Remove 8 passthrough fields from ApiActionContext spanning three Api
areas:

  friend area:
    - handleFriendRequest  (set_friend_add_request)
    - handleDeleteFriend   (delete_friend)
    - setFriendRemark already kept the field name but now unused

  interaction area:
    - sendFriendPoke / sendGroupPoke  (friend_poke, group_poke, send_poke)
    - getEmojiLikes  (was already dead — extended.ts used the direct
      path; field removed)

  message area:
    - markGroupMsgAsRead / markPrivateMsgAsRead  (already dead —
      mark_msg_as_read sites use the module helper)

`handleGroupRequest` stays on ctx because `handleGroupAddRequest` is
a module helper that does the flag-parsing + group-request roster
lookup before routing to `bridge.apis.groupAdmin.setAddRequest` —
real composition, not a passthrough.

Behavior preserved: same flag parsing (`asString/asNumber/asBoolean`),
same `isGroup` flag flatten into `sendPoke(isGroup, peerUin, target?)`,
same default `block=false` for delete_friend.

Part 3 of the OneBot-side slim-down. 552/552 tests still green.
This commit is contained in:
DrSmoothl
2026-05-21 09:23:32 +08:00
parent 4c4ce60bf2
commit 8bf2ff3f36
5 changed files with 18 additions and 26 deletions
+4 -4
View File
@@ -96,7 +96,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const userId = asNumber(params.user_id);
const targetId = asNumber(params.target_id) || undefined;
if (!userId) return failedResponse(RETCODE.BAD_REQUEST, 'user_id is required');
await ctx.sendFriendPoke(userId, targetId);
await ctx.bridge.apis.interaction.sendPoke(false, userId, targetId);
return okResponse();
});
@@ -104,7 +104,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const groupId = asNumber(params.group_id);
const userId = asNumber(params.user_id);
if (!groupId || !userId) return failedResponse(RETCODE.BAD_REQUEST, 'group_id and user_id are required');
await ctx.sendGroupPoke(groupId, userId);
await ctx.bridge.apis.interaction.sendPoke(true, groupId, userId);
return okResponse();
});
@@ -113,9 +113,9 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const userId = asNumber(params.user_id);
if (!userId) return failedResponse(RETCODE.BAD_REQUEST, 'user_id is required');
if (groupId) {
await ctx.sendGroupPoke(groupId, userId);
await ctx.bridge.apis.interaction.sendPoke(true, groupId, userId);
} else {
await ctx.sendFriendPoke(userId);
await ctx.bridge.apis.interaction.sendPoke(false, userId);
}
return okResponse();
});
+1 -1
View File
@@ -24,7 +24,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const userId = asNumber(params.user_id);
const block = asBoolean(params.block, false);
if (!userId) return failedResponse(RETCODE.BAD_REQUEST, 'user_id is required');
await ctx.handleDeleteFriend(userId, block);
await ctx.bridge.apis.friend.delete(userId, block);
return okResponse();
});
}
+1 -1
View File
@@ -7,7 +7,7 @@ export function register(h: ApiHandler, ctx: ApiActionContext): void {
const flag = asString(params.flag);
const approve = asBoolean(params.approve, true);
if (!flag) return failedResponse(RETCODE.BAD_REQUEST, 'flag is required');
await ctx.handleFriendRequest(flag, approve);
await ctx.bridge.apis.friend.handleRequest(flag, approve);
return okResponse();
});
+9 -10
View File
@@ -71,20 +71,19 @@ export interface ApiActionContext {
// stays because it composes through the `getGroupFiles` module
// helper (identity-lookup enrichment of uploader names).
getGroupFiles: (groupId: number, folderId?: string) => Promise<JsonObject>;
// Requests (adapters: rename to OneBot vocabulary)
handleFriendRequest: (flag: string, approve: boolean) => Promise<void>;
// Friend requests: direct via `ctx.bridge.apis.friend.handleRequest`.
// Group requests: stay on ctx because `handleGroupAddRequest` is a
// module helper that does the flag-parsing + group-request lookup
// dance before routing to `bridge.apis.groupAdmin.setAddRequest`.
handleGroupRequest: (flag: string, subType: string, approve: boolean, reason: string) => Promise<void>;
// Pokes (adapters: flatten isGroup into bridge.sendPoke signature)
sendFriendPoke: (userId: number, targetId?: number) => Promise<void>;
sendGroupPoke: (groupId: number, userId: number) => Promise<void>;
// Pokes: direct via `ctx.bridge.apis.interaction.sendPoke(isGroup, …)`.
// Essence (adapter: bakes the set/unset boolean)
setEssenceMsg: (messageId: number) => Promise<void>;
deleteEssenceMsg: (messageId: number) => Promise<void>;
// Profile reads with OneBot-specific default args
getProfileLike: (userId?: number, start?: number, limit?: number) => Promise<any>;
getGroupEssence: (groupId: number, pageStart?: number, pageLimit?: number) => Promise<GroupEssenceMsgRet>;
// Friend deletion (adapter: rename + force-boolean)
handleDeleteFriend: (userId: number, block?: boolean) => Promise<void>;
// Friend deletion: direct via `ctx.bridge.apis.friend.delete(userId, block)`.
// Module wrappers / multi-dep compositions
getGroupMsgHistory: (groupId: number, messageId?: number, count?: number) => Promise<JsonObject[]>;
getFriendMsgHistory: (userId: number, messageId?: number, count?: number) => Promise<JsonObject[]>;
@@ -99,12 +98,12 @@ export interface ApiActionContext {
setFriendRemark: (userId: number, remark: string) => Promise<void>;
setGroupAvatar: (groupId: number, source: string) => Promise<void>;
setMsgEmojiLike: (messageId: number, emojiId: string, set: boolean) => Promise<void>;
markGroupMsgAsRead: (groupId: number, sequence: number) => Promise<void>;
markPrivateMsgAsRead: (userId: number, sequence: number) => Promise<void>;
// markGroupMsgAsRead / markPrivateMsgAsRead: direct via
// `ctx.bridge.apis.message.{markGroupRead,markPrivateRead}`.
setOnlineStatus: (status: number, extStatus?: number, batteryStatus?: number) => Promise<void>;
setProfile: (nickname?: string, personalNote?: string) => Promise<void>;
fetchCustomFace: (count?: number) => Promise<string[]>;
getEmojiLikes: (groupId: number, sequence: number, emojiId: string, emojiType?: number, count?: number, cookie?: string) => Promise<{ users: Array<{ uin: number }>, cookie: string, isLast: boolean }>;
// getEmojiLikes: direct via `ctx.bridge.apis.interaction.getEmojiLikes(...)`.
// Web
getGroupHonorInfo: (groupId: number, type: WebHonorType | string) => Promise<any>;
getGroupEssenceAll: (groupId: number) => Promise<GroupEssenceMsgRet[]>;
+3 -10
View File
@@ -119,14 +119,11 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
// rest of the area is called directly via `ctx.bridge.apis.groupFile.*`.
getGroupFiles: (groupId, folderId) => getGroupFiles(bridge, groupId, folderId),
// Requests — name translation.
handleFriendRequest: (flag, approve) => bridge.apis.friend.handleRequest(flag, approve),
// Group request handling stays here because `handleGroupAddRequest`
// is a module helper (flag parsing + group-request lookup). Friend
// request handling moved to direct `ctx.bridge.apis.friend.handleRequest`.
handleGroupRequest: (flag, _subType, approve, reason) => handleGroupAddRequest(bridge, flag, approve, reason),
// Pokes — flatten isGroup into the bridge signature.
sendFriendPoke: (userId, targetId) => bridge.apis.interaction.sendPoke(false, userId, targetId),
sendGroupPoke: (groupId, userId) => bridge.apis.interaction.sendPoke(true, groupId, userId),
// Essence — bake the set/unset boolean.
setEssenceMsg: (messageId) => setEssenceMessage(bridge, messageStore, messageId, true),
deleteEssenceMsg: (messageId) => setEssenceMessage(bridge, messageStore, messageId, false),
@@ -148,7 +145,6 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
sendForwardMsg: (messages, groupId) => uploadForwardMessage(ref, messages, groupId),
getForwardMsg: (resId) => getForwardMessage(ref, resId),
forwardSingleMsg: (messageId, target) => forwardSingleMessage(ref, messageId, target),
handleDeleteFriend: (userId, block) => bridge.apis.friend.delete(userId, !!block),
forceFetchClientKey: () => bridge.apis.web.forceFetchClientKey(),
setFriendRemark: (userId, remark) => bridge.apis.friend.setRemark(userId, remark),
setGroupAvatar: (groupId, source) => bridge.apis.profile.setGroupAvatar(groupId, source),
@@ -163,8 +159,6 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
if (!meta.isGroup) throw new Error('emoji reactions are not supported on private messages');
await bridge.apis.interaction.setReaction(meta.targetId, meta.sequence, emojiId, set);
},
markGroupMsgAsRead: (groupId, sequence) => bridge.apis.message.markGroupRead(groupId, sequence),
markPrivateMsgAsRead: (userId, sequence) => bridge.apis.message.markPrivateRead(userId, sequence),
setOnlineStatus: (status: number, extStatus?: number, batteryStatus?: number) => bridge.apis.profile.setOnlineStatus(status, extStatus, batteryStatus),
setProfile: (nickname?: string, personalNote?: string) => bridge.apis.profile.setProfile(nickname, personalNote),
@@ -186,7 +180,6 @@ export function buildApiContext(ref: OneBotInstanceContext): ApiActionContext {
// Extended
fetchCustomFace: (count) => bridge.apis.profile.fetchCustomFace(count),
getEmojiLikes: (groupId, sequence, emojiId, emojiType, count, cookie) => bridge.apis.interaction.getEmojiLikes(groupId, sequence, emojiId, emojiType, count, cookie),
// Media lookup.
getImageInfo: (file) => getCachedImageInfo(mediaStore, file),