11import { Context , Schema , Logger } from 'koishi'
22
33export const usage = `
4- ## koishi-plugin-api-handler v1.0.6
4+ ## koishi-plugin-api-handler v1.1.0
55
661. 配置API地址。
77
@@ -13,6 +13,9 @@ export const usage = `
1313
1414注意:只有群内@机器人的消息才会处理。
1515
16+
17+ 微信配合adapter-wechat4u使用。
18+
1619`
1720
1821export const name = 'koishi-plugin-api-handler'
@@ -26,16 +29,37 @@ export interface Config {
2629 prefix_2 : string ,
2730 prefix_3 ?: string ,
2831 prefix_4 ?: string ,
32+ wx_api ?: string ,
33+ wx_token ?: string ,
34+ bot_name ?: string ,
35+ wx_group_all_message ?: boolean ,
2936}
30-
31- export const Config : Schema < Config > = Schema . object ( {
32- api : Schema . string ( ) . required ( true ) . description ( 'API地址' ) ,
33- token : Schema . string ( ) . required ( true ) . description ( 'API接收的token,以POST传递,参数名为token' ) ,
34- prefix_1 : Schema . string ( ) . required ( true ) . description ( '消息开头匹配字符串,不区分大小写,完全包含则将用户消息发送到API,由API返回回复内容字符串' ) ,
35- prefix_2 : Schema . string ( ) . description ( '匹配消息前缀2' ) ,
36- prefix_3 : Schema . string ( ) . description ( '匹配消息前缀3' ) ,
37- prefix_4 : Schema . string ( ) . description ( '匹配消息前缀4' ) ,
38- } )
37+ export const Config : Schema < Config > = Schema . intersect ( [
38+ Schema . object ( {
39+ api : Schema . string ( ) . required ( true ) . description ( 'API地址' ) ,
40+ token : Schema . string ( ) . required ( true ) . description ( 'API接收的token,以POST传递,参数名为token' ) ,
41+ prefix_1 : Schema . string ( ) . required ( true ) . description ( '消息开头匹配字符串,不区分大小写,完全包含则将用户消息发送到API,由API返回回复内容字符串' ) ,
42+ prefix_2 : Schema . string ( ) . description ( '匹配消息前缀2' ) ,
43+ prefix_3 : Schema . string ( ) . description ( '匹配消息前缀3' ) ,
44+ prefix_4 : Schema . string ( ) . description ( '匹配消息前缀4' ) ,
45+ } ) . description ( '基础设置' ) ,
46+ Schema . object ( {
47+ wx_api : Schema . string ( ) . description ( 'API地址' ) ,
48+ wx_token : Schema . string ( ) . description ( 'API接收的token,以POST传递,参数名为token' ) ,
49+ bot_name : Schema . string ( ) . description ( 'wx机器人昵称,用于判定是否@' ) ,
50+ wx_group_all_message : Schema . boolean ( ) . description ( 'wx群组所有消息都处理' ) ,
51+ } ) . description ( '微信设置(结合wechat4u使用)' ) ,
52+ ] ) ;
53+ // export const Config: Schema<Config> = Schema.object({
54+ // api: Schema.string().required(true).description('API地址'),
55+ // token: Schema.string().required(true).description('API接收的token,以POST传递,参数名为token'),
56+ // prefix_1: Schema.string().required(true).description('消息开头匹配字符串,不区分大小写,完全包含则将用户消息发送到API,由API返回回复内容字符串'),
57+ // prefix_2: Schema.string().description('匹配消息前缀2'),
58+ // prefix_3: Schema.string().description('匹配消息前缀3'),
59+ // prefix_4: Schema.string().description('匹配消息前缀4'),
60+ // bot_name: Schema.string().description('wx机器人昵称,用于判定是否@'),
61+ // wx_group_all_message: Schema.boolean().description('wx群组所有消息都处理'),
62+ // })
3963
4064export function startsWithPrefix ( str : string , prefix : string ) {
4165 // 首先去掉字符串前后的空格
@@ -63,40 +87,97 @@ export function handlePrefixes(sessionContent: string, config: Config) {
6387export function apply ( ctx : Context , config : Config ) {
6488 ctx . middleware ( async ( session , next ) => {
6589
66- const content = session . content ;
90+ let content = session . content ;
6791 const botId = session . selfId ;
6892
93+ // logger.info(session);
94+ logger . info ( '群组:' + session . channelId )
6995 logger . info ( '原始消息:' + content ) ;
70- logger . info ( '机器人QQ:' + botId ) ;
96+ logger . info ( '机器人ID:' + botId ) ;
97+
98+ const mentionRegex2 = new RegExp ( `private:` ) ;
99+ const isPrivateChat = session . channelId && mentionRegex2 . test ( session . channelId ) ;
100+
101+ if ( session . platform == 'wechaty' ) {
102+ const mentionRegex = new RegExp ( `@${ config . bot_name } ` ) ;
103+ const isMentioned = content && mentionRegex . test ( content ) ;
104+ let regex = new RegExp ( `@${ config . bot_name } \\s*` , "g" ) ;
105+ content = content . replace ( regex , "" ) . trim ( ) ;
106+
107+ logger . info ( '是否私聊:' + isPrivateChat ) ;
108+ logger . info ( '是否@:' + isMentioned ) ;
109+ logger . info ( '过滤@后的内容:' + content ) ;
110+
111+ // 非私聊、非群组@,群组内其他消息
112+ // 若关闭了回复所有群组消息,则直接返回空
113+ if ( ! isPrivateChat && ! isMentioned && ! config . wx_group_all_message ) {
114+ return '' ;
115+ // return next()
116+ }
71117
72- // 使用正则表达式确保准确匹配特定的提到格式
73- const mentionRegex = new RegExp ( `<at id="${ botId } "/>` ) ;
74- const isMentioned = content && mentionRegex . test ( content ) ;
75- if ( ! isMentioned ) {
118+ // 私聊/群组@
119+ let wx_match_prefix = handlePrefixes ( content , config )
120+ if ( wx_match_prefix ) {
121+ logger . info ( wx_match_prefix )
122+ const res = await ctx . http . post ( config . wx_api , {
123+ token : config . wx_token ,
124+ message : content ,
125+ channelId : session . channelId ,
126+ } )
127+ . catch ( ( err ) => {
128+ return { error : err . message }
129+ } )
130+ if ( res !== undefined ) {
131+ return res ;
132+ }
133+
134+ return 'Error' ;
135+ }
76136 return next ( )
77137 }
78138
79- const cleanContent = content . replace ( / < a t i d = " \d + " \/ > / g, '' ) . trim ( ) ;
80- logger . info ( '文本消息:' + cleanContent ) ;
81- logger . info ( '群组:' + session . channelId )
139+ if ( session . platform == 'onebot' ) {
140+ // 使用正则表达式确保准确匹配特定的提到格式
141+ const mentionRegex = new RegExp ( `<at id="${ botId } "/>` ) ;
142+ const isMentioned = content && mentionRegex . test ( content ) ;
82143
83- let match_prefix = handlePrefixes ( cleanContent , config )
84- if ( match_prefix ) {
85- logger . info ( match_prefix )
86- const res = await ctx . http . post ( config . api , {
87- token : config . token ,
88- message : cleanContent ,
89- channelId : session . channelId ,
90- } )
91- . catch ( ( err ) => {
92- return { error : err . message }
93- } )
94- if ( res !== undefined ) {
95- return res ;
144+ const cleanContent = content . replace ( / < a t i d = " \d + " \/ > / g, '' ) . trim ( ) ;
145+
146+ logger . info ( '是否私聊:' + isPrivateChat ) ;
147+ logger . info ( '是否@:' + isMentioned ) ;
148+ logger . info ( '过滤@后的内容:' + cleanContent ) ;
149+
150+ // 非私聊、非群组@
151+ // 群组内其他消息,则直接返回空
152+ if ( ! isPrivateChat && ! isMentioned ) {
153+ return '' ;
154+ }
155+
156+ // 私聊直接返回AI内容
157+ if ( isPrivateChat ) {
158+ return next ( )
96159 }
97160
98- return 'Error' ;
161+ // 群内@,如果匹配到前缀,请求API结果
162+ // 如未匹配到,返回AI内容
163+ let match_prefix = handlePrefixes ( cleanContent , config )
164+ if ( match_prefix ) {
165+ logger . info ( match_prefix )
166+ const res = await ctx . http . post ( config . api , {
167+ token : config . token ,
168+ message : cleanContent ,
169+ channelId : session . channelId ,
170+ } )
171+ . catch ( ( err ) => {
172+ return { error : err . message }
173+ } )
174+ if ( res !== undefined ) {
175+ return res ;
176+ }
177+
178+ return 'Error' ;
179+ }
180+ return next ( )
99181 }
100- return next ( )
101182 } , true )
102183}
0 commit comments