dsh-qq-tools 0.9.4 → 0.9.5

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.
Files changed (2) hide show
  1. package/lib/shared.js +30 -59
  2. package/package.json +2 -1
package/lib/shared.js CHANGED
@@ -451,14 +451,13 @@ export function formatIncomingLine(name, userId, text, messageId) {
451
451
  }
452
452
 
453
453
  // 回复风格:群聊要像随手打字,短、分条、不刷屏地 @ 和引用。
454
- export const CHAT_STYLE = '回复像群友随手打字:想连发几条就传 messages,每条一句短话(十几二十个字),最多三条;'
454
+ export const CHAT_STYLE = '回复像群友随手打字:想连发几条就**多次调用同一个工具**(一次调用只发一条),每条一句短话(十几二十个字),最多三次调用;'
455
455
  + '不要句号收尾,不要写长段落,不要 Markdown,不要把昵称或 QQ 号写进正文,不要每句都 @ 或引用——'
456
456
  + '只有确实要指代某条消息时才传 reply_to,只有必须提醒某个人时才传 at_user_ids。'
457
457
 
458
458
  const CHAT_BUBBLE_CHARS = 80
459
- const CHAT_BUBBLE_MAX = 5
460
459
 
461
- // 一条气泡的清理:压掉复制来的对齐空格和多行,去掉正文开头重复的 @昵称。
460
+ // 一条消息的清理:压掉复制来的对齐空格和多行,去掉正文开头重复的 @昵称。
462
461
  function cleanBubble(value) {
463
462
  return String(value || '')
464
463
  .replace(/\r/g, '')
@@ -469,12 +468,9 @@ function cleanBubble(value) {
469
468
  .slice(0, CHAT_BUBBLE_CHARS)
470
469
  }
471
470
 
472
- // 模型自己决定发几条:messages 数组每条一个气泡;只给 message 就是一条,不做机械切分。
473
- export function chatMessages(args) {
474
- const list = Array.isArray(args && args.messages) ? args.messages : []
475
- const single = args && args.message
476
- const source = list.length ? list : (single ? [single] : [])
477
- return source.map(cleanBubble).filter(Boolean).slice(0, CHAT_BUBBLE_MAX)
471
+ // 一次工具调用只发一条:想分几条说就让模型多次调用工具。
472
+ export function chatText(args) {
473
+ return cleanBubble(args && args.message)
478
474
  }
479
475
 
480
476
 
@@ -951,7 +947,7 @@ export function makeSendTool(onSent) {
951
947
  return {
952
948
  name: 'qq_send_group_message',
953
949
  description:
954
- '在指定群里发消息。发之前先确认群号;只发到允许的群。' +
950
+ '在指定群里发一条消息。发之前先确认群号;只发到允许的群。想分几条说就**多次调用本工具**,一次一条。' +
955
951
  'reply_to 传消息前面的 #编号 可以引用那条消息;at_user_ids 传 QQ 号可以 @ 人,at_all=true 是 @全体成员。' +
956
952
  CHAT_STYLE +
957
953
  '不想说话就不要调用这个工具;调用后不要再重复说自己发了什么。',
@@ -959,11 +955,7 @@ export function makeSendTool(onSent) {
959
955
  type: 'object',
960
956
  properties: {
961
957
  group_id: { type: 'number', description: '群号' },
962
- messages: {
963
- type: 'array', items: { type: 'string' },
964
- description: '想连发几条就放这里,每条一个气泡、一句短话;最多 5 条',
965
- },
966
- message: { type: 'string', description: '只发一条时的文字;要发多条用 messages;只 @ 不说话时可以留空' },
958
+ message: { type: 'string', description: '这一条的文字,一句短话;只 @ 不说话时可以留空' },
967
959
  reply_to: { type: 'string', description: '要引用的消息 ID(消息前面的 #编号),可选', },
968
960
  at_user_ids: { type: 'array', items: { type: 'number' }, description: '要 @ 的 QQ 号列表,可选', },
969
961
  at_all: { type: 'boolean', description: 'true = @全体成员,可选' },
@@ -975,37 +967,28 @@ export function makeSendTool(onSent) {
975
967
  async execute(args) {
976
968
  const cfg = loadCfg()
977
969
  const groupId = Number(args && args.group_id)
978
- const bubbles = chatMessages(args)
970
+ const text = chatText(args)
979
971
  const atIds = [...new Set(
980
972
  (Array.isArray(args && args.at_user_ids) ? args.at_user_ids : [])
981
973
  .map((x) => Number(x)).filter((x) => Number.isInteger(x) && x > 0),
982
974
  )].slice(0, 20)
983
975
  const atAll = args && args.at_all === true
984
976
  if (!Number.isFinite(groupId)) return { ok: false, error: 'group_id 不是有效群号' }
985
- if (!bubbles.length && !atIds.length && !atAll) return { ok: false, error: '消息是空的' }
977
+ if (!text && !atIds.length && !atAll) return { ok: false, error: '消息是空的' }
986
978
  if (!allowedGroup(groupId, cfg)) return { ok: false, error: '这个群不在允许列表里' }
987
979
  try {
988
980
  const replyTo = args && args.reply_to
989
- const messageIds = []
990
- for (const [index, segment] of (bubbles.length ? bubbles : ['']).entries()) {
991
- const message = []
992
- // 引用和 @ 只挂在第一条上,避免每条都刷一遍。
993
- if (index === 0 && replyTo != null && replyTo !== '') message.push({ type: 'reply', data: { id: String(replyTo) } })
994
- if (index === 0) {
995
- if (atAll) message.push({ type: 'at', data: { qq: 'all' } })
996
- else for (const qq of atIds) message.push({ type: 'at', data: { qq: String(qq) } })
997
- }
998
- if (segment) message.push({ type: 'text', data: { text: segment } })
999
- const data = await onebot('send_group_msg', { group_id: groupId, message }, cfg)
1000
- messageIds.push(data && data.message_id)
1001
- }
981
+ const message = []
982
+ if (replyTo != null && replyTo !== '') message.push({ type: 'reply', data: { id: String(replyTo) } })
983
+ if (atAll) message.push({ type: 'at', data: { qq: 'all' } })
984
+ else for (const qq of atIds) message.push({ type: 'at', data: { qq: String(qq) } })
985
+ if (text) message.push({ type: 'text', data: { text } })
986
+ const data = await onebot('send_group_msg', { group_id: groupId, message }, cfg)
1002
987
  try { if (typeof onSent === 'function') onSent(groupId, '发群消息') } catch (error) {}
1003
988
  return {
1004
989
  ok: true,
1005
990
  group_id: groupId,
1006
- message_id: messageIds[0],
1007
- message_ids: messageIds,
1008
- segments: bubbles.length,
991
+ message_id: data && data.message_id,
1009
992
  reply_to: replyTo != null && replyTo !== '' ? String(replyTo) : '',
1010
993
  at_user_ids: atAll ? [] : atIds,
1011
994
  at_all: atAll,
@@ -1020,8 +1003,7 @@ export function makeSendTool(onSent) {
1020
1003
  if (v.reply_to) extra.push('引用了 #' + v.reply_to)
1021
1004
  if (v.at_all) extra.push('@全体成员')
1022
1005
  else if (Array.isArray(v.at_user_ids) && v.at_user_ids.length) extra.push('@了 ' + v.at_user_ids.join('、'))
1023
- const count = Array.isArray(v.message_ids) && v.message_ids.length > 1 ? `,分 ${v.message_ids.length} 条` : ''
1024
- return [{ type: 'text', text: `已发到群 ${v.group_id}(消息 ${v.message_id || '?'}${count}${extra.length ? ',' + extra.join(',') : ''})。` }]
1006
+ return [{ type: 'text', text: `已发到群 ${v.group_id}(消息 ${v.message_id || '?'}${extra.length ? ',' + extra.join(',') : ''})。` }]
1025
1007
  },
1026
1008
  }
1027
1009
  }
@@ -1166,7 +1148,7 @@ export function makeSendPrivateTool() {
1166
1148
  return {
1167
1149
  name: 'qq_send_private_message',
1168
1150
  description:
1169
- '给某个 QQ 好友发私聊消息。user_id 从 qq_list_friends 或私聊唤醒提示里拿。' +
1151
+ '给某个 QQ 好友发一条私聊消息。user_id 从 qq_list_friends 或私聊唤醒提示里拿。想分几条说就多次调用本工具,一次一条。' +
1170
1152
  'reply_to 传消息前面的 #编号 可以引用那条消息。' +
1171
1153
  CHAT_STYLE +
1172
1154
  '不想说话就不要调用;调用后不要再重复说自己发了什么。',
@@ -1174,44 +1156,34 @@ export function makeSendPrivateTool() {
1174
1156
  type: 'object',
1175
1157
  properties: {
1176
1158
  user_id: { type: 'number', description: '对方的 QQ 号' },
1177
- messages: {
1178
- type: 'array', items: { type: 'string' },
1179
- description: '想连发几条就放这里,每条一个气泡、一句短话;最多 5 条',
1180
- },
1181
- message: { type: 'string', description: '只发一条时的文字;要发多条用 messages' },
1159
+ message: { type: 'string', description: '这一条的文字,一句短话' },
1182
1160
  reply_to: { type: 'string', description: '要引用的消息 ID(消息前面的 #编号),可选' },
1183
1161
  group_id: { type: 'number', description: '临时会话的来源群号,可选;普通好友私聊不用传' },
1184
1162
  },
1185
- required: ['user_id'],
1163
+ required: ['user_id', 'message'],
1186
1164
  additionalProperties: false,
1187
1165
  },
1188
1166
  output: { schema: { type: 'object', additionalProperties: true }, render: renderTool },
1189
1167
  async execute(args) {
1190
1168
  const cfg = loadCfg()
1191
1169
  const userId = Number(args && args.user_id)
1192
- const bubbles = chatMessages(args)
1170
+ const text = chatText(args)
1193
1171
  const groupId = args && args.group_id != null ? Number(args.group_id) : 0
1194
1172
  if (!Number.isFinite(userId)) return { ok: false, error: 'user_id 不是有效 QQ 号' }
1195
- if (!bubbles.length) return { ok: false, error: '消息是空的' }
1173
+ if (!text) return { ok: false, error: '消息是空的' }
1196
1174
  if (!allowedPrivate(userId, cfg)) return { ok: false, error: '这个 QQ 不在允许列表里' }
1197
1175
  try {
1198
1176
  const replyTo = args && args.reply_to
1199
- const messageIds = []
1200
- for (const [index, segment] of bubbles.entries()) {
1201
- const message = []
1202
- if (index === 0 && replyTo != null && replyTo !== '') message.push({ type: 'reply', data: { id: String(replyTo) } })
1203
- message.push({ type: 'text', data: { text: segment } })
1204
- const body = { user_id: userId, message }
1205
- if (groupId) body.group_id = groupId
1206
- const data = await onebot('send_private_msg', body, cfg)
1207
- messageIds.push(data && data.message_id)
1208
- }
1177
+ const message = []
1178
+ if (replyTo != null && replyTo !== '') message.push({ type: 'reply', data: { id: String(replyTo) } })
1179
+ message.push({ type: 'text', data: { text } })
1180
+ const body = { user_id: userId, message }
1181
+ if (groupId) body.group_id = groupId
1182
+ const data = await onebot('send_private_msg', body, cfg)
1209
1183
  return {
1210
1184
  ok: true,
1211
1185
  user_id: userId,
1212
- message_id: messageIds[0],
1213
- message_ids: messageIds,
1214
- segments: bubbles.length,
1186
+ message_id: data && data.message_id,
1215
1187
  reply_to: replyTo != null && replyTo !== '' ? String(replyTo) : '',
1216
1188
  }
1217
1189
  } catch (error) {
@@ -1221,8 +1193,7 @@ export function makeSendPrivateTool() {
1221
1193
  render(_args, v) {
1222
1194
  if (!v || !v.ok) return [{ type: 'text', text: '发私聊消息失败:' + String((v && v.error) || '未知错误') }]
1223
1195
  const quote = v.reply_to ? ',引用了 #' + v.reply_to : ''
1224
- const count = Array.isArray(v.message_ids) && v.message_ids.length > 1 ? `,分 ${v.message_ids.length} 条` : ''
1225
- return [{ type: 'text', text: `已发给 QQ ${v.user_id}(消息 ${v.message_id || '?'}${count}${quote})。` }]
1196
+ return [{ type: 'text', text: `已发给 QQ ${v.user_id}(消息 ${v.message_id || '?'}${quote})。` }]
1226
1197
  },
1227
1198
  }
1228
1199
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-qq-tools",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "给大肥鱼会话用的 QQ 群/私聊工具:列群、看群记录、发群消息(可引用/@)、发表情、收藏表情(SnowLuma 收藏夹)、好友/私聊记录、发私聊消息、私聊唤醒、群成员、戳一戳感知/戳回去、更改头像、好友管理(资料/备注/分组/删好友/名片赞/好友申请)、QQ 空间说说(列表/详情/发表/评论/点赞/权限)、挂载会话选择。11 个工具组加 1 个设置组件,可在插件页逐个开关。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -100,3 +100,4 @@
100
100
  }
101
101
 
102
102
 
103
+