• wechaty消息防撤回功能


     

    1. let historyMsgList = []
    2. const handleAddHistoryMsg = ({ msg }) => {
    3. if (historyMsgList.length < 10) {
    4. historyMsgList.push(msg)
    5. } else {
    6. historyMsgList.push(msg)
    7. historyMsgList.shift()
    8. }
    9. }
    10. const handleGetDeleteMsg = ({ msg, alias }) => {
    11. historyMsgList.forEach(async (item) => {
    12. if (msg.payload.text.includes(item.id)) {
    13. console.log(item.text())
    14. const room = msg.room()
    15. if (room) {
    16. if (global.isLocal) {
    17. const roomName = await room?.topic()
    18. if (roomWhiteList.includes(roomName)) {
    19. room.say(`我是机器人,我知道你撤回了什么消息:
    20. ${item.text()}`)
    21. }
    22. } else {
    23. if (alias.includes('徐同保') === false) {
    24. room.say(`我是机器人,我知道你撤回了什么消息:
    25. ${item.text()}`)
    26. }
    27. }
    28. }
    29. }
    30. })
    31. }

    1. const handleMessage = async ({ msg, bot }) => {
    2. const contact = msg.talker() // 发消息人
    3. //const receiver = msg.to() // 消息接收人
    4. let content = msg.text() // 消息内容
    5. const room = msg.room() // 是否是群消息
    6. const roomName = (await room?.topic()) || null // 群名称
    7. let alias = (await contact.alias()) || (await contact.name()) // 发消息人昵称
    8. // const remarkName = await contact.alias() // 备注名称
    9. // const name = await contact.name() // 微信名称
    10. const msgType = msg.type()
    11. let isRoom = true // roomWhiteList.includes(roomName) || roomName?.includes('gpt')
    12. // const isAlias =
    13. // aliasWhiteList.includes(remarkName) ||
    14. // aliasWhiteList.includes(name) ||
    15. // remarkName.includes('gpt')
    16. const isAlias = true
    17. if (global.isLocal) {
    18. //alias = '徐同保88'
    19. isRoom = roomWhiteList.includes(roomName)
    20. }
    21. if (msg.mentionSelf && (await msg.mentionSelf())) {
    22. console.log(
    23. 'this message were mentioned me! [You were mentioned] tip ([有人@我]的提示)'
    24. )
    25. await room.say(`不要@微信机器人
    26. 免费向微信机器人提问的格式:
    27. gpt,xxx
    28. 晓丽,xxx
    29. speech,xxx(文本转语音)
    30. 付费后向微信机器人提问的格式:
    31. gpt4,xxx
    32. claude3,xxx
    33. 大明,xxx
    34. mistral,xxx
    35. mj,xxx(AI绘画)
    36. gemini,xxx
    37. 文心一言v4,xxx
    38. upload
    39. uploadForMJ
    40. whisper,xxx(xxx为音频或视频链接,语音转文本)
    41. 可以加微信机器人私聊
    42. 网站:
    43. https://chat.xutongbao.top`)
    44. } else if (msgType === 13) {
    45. console.log(msg.payload.text)
    46. handleGetDeleteMsg({ msg, alias })
    47. } else if (msgType === bot.Message.Type.Text) {
    48. handleAddHistoryMsg({ msg })
    49. let message = ''
    50. let gptVersion = ''
    51. content = content.trim()
    52. let wxMsgType = ''
    53. let contentObj = {}
    54. //#region mj帮助
    55. if (content.length >= 3) {
    56. let startContent = content.slice(0, 3)
    57. startContent = startContent.toLowerCase()
    58. if (startContent === 'mj?' || startContent === 'mj?') {
    59. let mjHelp = `### midjourney提问格式文档
    60. #### 一次画四个图
    61. mj,xxx
    62. #### 备注
    63. - 提示词支持中文
    64. - 如果需要使用【--v】之类的指令请使用英文提示词
    65. `
    66. /*
    67. let mjHelp = `### midjourney提问格式文档
    68. #### 一次画四个图
    69. mj,xxx
    70. #### 一次画一个图
    71. mj1,xxx
    72. #### 一次画四个图
    73. {
    74. "type": "mj",
    75. "prompt": "xxx",
    76. "drawType": "grid"
    77. }
    78. #### 选择四个图中的某一个放大
    79. U1代表第一个,还有U2、U3、U4
    80. parent_id的值为一次画四个图时返回的ID
    81. {
    82. "type": "mj",
    83. "pick": "U1",
    84. "parent_id": 123
    85. }
    86. #### 选择四个图中的某一个再次生成四个相似的图
    87. V1代表第一个,还有V2、V3、V4
    88. parent_id的值为一次画四个图时返回的ID
    89. {
    90. "type": "mj",
    91. "pick": "V1",
    92. "parent_id": 123
    93. }
    94. `
    95. */
    96. if (room) {
    97. room.say(mjHelp)
    98. } else if (contact) {
    99. contact.say(mjHelp)
    100. }
    101. return
    102. }
    103. }
    104. //#endregion
    105. let assistantName = ''
    106. //#region json格式的提示词
    107. try {
    108. contentObj = JSON.parse(content) ? JSON.parse(content) : {}
    109. if (contentObj.type === 'sd') {
    110. console.log('sd绘画', contentObj)
    111. wxMsgType = 'sd'
    112. } else if (contentObj.type === 'textToAudioByMicrosoft') {
    113. console.log('文本转语音', contentObj)
    114. wxMsgType = 'textToAudioByMicrosoft'
    115. } else if (contentObj.type === 'mj') {
    116. console.log('mj绘画', contentObj)
    117. contentObj.message = contentObj.prompt
    118. ? contentObj.prompt
    119. : contentObj.message
    120. wxMsgType = 'mj'
    121. } else {
    122. console.log('contentObj', contentObj)
    123. }
    124. } catch (error) {
    125. if (content.includes('"type":')) {
    126. if (room) {
    127. room.say(`JSON格式错误,${error}`)
    128. } else if (contact) {
    129. contact.say(`JSON格式错误,${error}`)
    130. }
    131. }
    132. //todo
    133. }
    134. //#endregion
    135. //#region 智能问答
    136. if (content.length > 4) {
    137. let startContent = content.slice(0, 4)
    138. startContent = startContent.toLowerCase()
    139. if (
    140. startContent === 'gpt,' ||
    141. startContent === 'gpt,' ||
    142. startContent === 'gpt '
    143. ) {
    144. message = content.slice(4)
    145. gptVersion = '3.5'
    146. }
    147. }
    148. if (content.length > 5) {
    149. let startContent = content.slice(0, 5)
    150. startContent = startContent.toLowerCase()
    151. if (
    152. startContent === 'gpt4,' ||
    153. startContent === 'gpt4,' ||
    154. startContent === 'gpt4 '
    155. ) {
    156. message = content.slice(5)
    157. gptVersion = '4'
    158. }
    159. }
    160. if (content.length > 3) {
    161. let startContent = content.slice(0, 3)
    162. if (
    163. startContent === '晓丽,' ||
    164. startContent === '晓丽,' ||
    165. startContent === '晓丽 '
    166. ) {
    167. message = content.slice(3)
    168. gptVersion = '3.5'
    169. assistantName = 'xiaoli'
    170. }
    171. }
    172. if (content.length > 3) {
    173. let startContent = content.slice(0, 3)
    174. if (
    175. startContent === '大明,' ||
    176. startContent === '大明,' ||
    177. startContent === '大明 '
    178. ) {
    179. message = content.slice(3)
    180. gptVersion = '4'
    181. assistantName = 'daming'
    182. }
    183. }
    184. if (content.length > 7) {
    185. let startContent3 = content.slice(0, 7)
    186. startContent3 = startContent3.toLowerCase()
    187. if (
    188. startContent3 === 'gemini,' ||
    189. startContent3 === 'gemini,' ||
    190. startContent3 === 'gemini '
    191. ) {
    192. message = content.slice(7)
    193. gptVersion = 'gemini'
    194. }
    195. }
    196. if (content.length > 7) {
    197. let startContent = content.slice(0, 7)
    198. startContent = startContent.toLowerCase()
    199. if (
    200. startContent === '文心一言v4,' ||
    201. startContent === '文心一言v4,' ||
    202. startContent === '文心一言v4 '
    203. ) {
    204. message = content.slice(7)
    205. gptVersion = 'ERNIE-Bot-4'
    206. }
    207. }
    208. if (content.length > 8) {
    209. let startContent = content.slice(0, 8)
    210. startContent = startContent.toLowerCase()
    211. if (
    212. startContent === 'claude3,' ||
    213. startContent === 'claude3,' ||
    214. startContent === 'claude3 '
    215. ) {
    216. message = content.slice(8)
    217. gptVersion = 'claude3'
    218. }
    219. }
    220. if (content.length > 8) {
    221. let startContent = content.slice(0, 8)
    222. startContent = startContent.toLowerCase()
    223. if (
    224. startContent === 'mistral,' ||
    225. startContent === 'mistral,' ||
    226. startContent === 'mistral '
    227. ) {
    228. message = content.slice(8)
    229. gptVersion = 'mistral-large-latest'
    230. }
    231. }
    232. if (gptVersion) {
    233. wxMsgType = 'gpt'
    234. }
    235. //#endregion
    236. //#region midjourney
    237. if (content.length > 3) {
    238. let startContent = content.slice(0, 3)
    239. startContent = startContent.toLowerCase()
    240. if (
    241. startContent === 'mj,' ||
    242. startContent === 'mj,' ||
    243. startContent === 'mj '
    244. ) {
    245. message = content.slice(3)
    246. contentObj = {
    247. type: 'mj',
    248. message,
    249. prompt: message,
    250. drawType: 'grid',
    251. msgFrom: 'wx_mj',
    252. }
    253. wxMsgType = 'mj'
    254. }
    255. }
    256. if (content.length > 4) {
    257. let startContent = content.slice(0, 4)
    258. startContent = startContent.toLowerCase()
    259. if (
    260. startContent === 'mj1,' ||
    261. startContent === 'mj1,' ||
    262. startContent === 'mj1 '
    263. ) {
    264. message = content.slice(4)
    265. contentObj = {
    266. type: 'mj',
    267. message,
    268. prompt: message,
    269. }
    270. wxMsgType = 'mj'
    271. }
    272. }
    273. if (content.length > 6) {
    274. if (
    275. (content.charAt(0) === 'U' || content.charAt(0) === 'V') &&
    276. content.includes(':')
    277. ) {
    278. contentObj = {
    279. type: 'mj',
    280. pick: content.slice(0, 2),
    281. parent_id: content.split(':')[1] - 0,
    282. }
    283. wxMsgType = 'mj'
    284. }
    285. }
    286. if (content.length > 6) {
    287. let startContent = content.slice(0, 4)
    288. startContent = startContent.toLowerCase()
    289. if (startContent === 'mjs,') {
    290. message = content.slice(4)
    291. contentObj = {
    292. type: 'mj',
    293. message,
    294. prompt: message,
    295. msgFrom: 'wx_mjs',
    296. }
    297. wxMsgType = 'mj'
    298. }
    299. }
    300. //#endregion
    301. //#region 文本转语音
    302. if (content.length > 7) {
    303. let startContent = content.slice(0, 7)
    304. startContent = startContent.toLowerCase()
    305. if (
    306. startContent === 'speech,' ||
    307. startContent === 'speech,' ||
    308. startContent === 'speech '
    309. ) {
    310. message = content.slice(7)
    311. let voiceName = ['zh-CN', 'zh-CN-YunxiNeural']
    312. let style = 'chat'
    313. let role = 'YoungAdultMale'
    314. if (message.includes('--type=')) {
    315. const options = {
    316. string: ['name', 'age', 'type'], // 字符串类型的选项
    317. boolean: ['verbose'], // 布尔类型的选项
    318. }
    319. const cmdArr = parseCommandLine(message)
    320. let cmdResult = parseArgs(cmdArr, options)
    321. let resultStr = cmdResult['_'].join(' ')
    322. if (resultStr) {
    323. message = resultStr
    324. }
    325. if (cmdResult.type) {
    326. let resultIndexVoiceList = voiceList.findIndex(
    327. (item) => item.id === cmdResult.type
    328. )
    329. if (resultIndexVoiceList >= 0) {
    330. voiceName = voiceList[resultIndexVoiceList].voiceName
    331. style = voiceList[resultIndexVoiceList].style
    332. role = voiceList[resultIndexVoiceList].role
    333. }
    334. }
    335. }
    336. contentObj = {
    337. type: 'textToAudioByMicrosoft',
    338. dataList: [
    339. {
    340. componentType: 'msttsExpressAs',
    341. message: message,
    342. voiceName,
    343. style,
    344. role,
    345. styledegree: 1,
    346. delayTime: 500,
    347. },
    348. ],
    349. }
    350. wxMsgType = 'textToAudioByMicrosoft'
    351. }
    352. }
    353. //#endregion
    354. //#region 上传
    355. if (content.length === 6) {
    356. let startContent = content.slice(0, 6)
    357. startContent = startContent.toLowerCase()
    358. if (startContent === 'upload') {
    359. waitingUploadType = 'upload'
    360. waitingUploadAlias = alias
    361. return await handleUploadFileBefore({
    362. isAlias,
    363. alias,
    364. isRoom,
    365. room,
    366. contact,
    367. })
    368. }
    369. }
    370. if (content.length === 11) {
    371. let startContent = content.slice(0, 11)
    372. startContent = startContent.toLowerCase()
    373. if (startContent === 'uploadformj') {
    374. waitingUploadType = 'uploadformj'
    375. waitingUploadAlias = alias
    376. return await handleUploadFileBefore({
    377. isAlias,
    378. alias,
    379. isRoom,
    380. room,
    381. contact,
    382. })
    383. }
    384. }
    385. //#endregion
    386. //#region 语音转文本
    387. if (content.length > 8) {
    388. let startContent = content.slice(0, 8)
    389. startContent = startContent.toLowerCase()
    390. if (
    391. startContent === 'whisper,' ||
    392. startContent === 'whisper,' ||
    393. startContent === 'whisper '
    394. ) {
    395. message = content.slice(8)
    396. return await handleWhisper({
    397. isAlias,
    398. alias,
    399. isRoom,
    400. room,
    401. contact,
    402. message,
    403. })
    404. }
    405. }
    406. //#endregion
    407. //#region google搜索
    408. if (content.length > 7) {
    409. let startContent = content.slice(0, 7)
    410. startContent = startContent.toLowerCase()
    411. if (
    412. startContent === 'google,' ||
    413. startContent === 'google,' ||
    414. startContent === 'google '
    415. ) {
    416. message = content.slice(7)
    417. return await handleGoogleSearch({
    418. isAlias,
    419. alias,
    420. isRoom,
    421. room,
    422. contact,
    423. message,
    424. })
    425. }
    426. }
    427. //#endregion
    428. //#region 图片转文字
    429. if (content.length > 10) {
    430. let startContent = content.slice(0, 10)
    431. startContent = startContent.toLowerCase()
    432. if (
    433. startContent === 'imgtotext,' ||
    434. startContent === 'imgtotext,' ||
    435. startContent === 'imgtotext '
    436. ) {
    437. message = content.slice(10)
    438. return await handleImgToText({
    439. isAlias,
    440. alias,
    441. isRoom,
    442. room,
    443. contact,
    444. message,
    445. })
    446. }
    447. }
    448. //#endregion
    449. if (wxMsgType === 'gpt') {
    450. console.log('gpt,alias', alias)
    451. console.log(JSON.stringify(msg))
    452. return await handleGPT({
    453. isAlias,
    454. alias,
    455. isRoom,
    456. room,
    457. message,
    458. gptVersion,
    459. contact,
    460. assistantName,
    461. })
    462. } else if (wxMsgType === 'sd') {
    463. console.log('sd,alias', alias)
    464. console.log(JSON.stringify(msg))
    465. await handleSD({ isAlias, alias, isRoom, room, contentObj, contact })
    466. } else if (wxMsgType === 'textToAudioByMicrosoft') {
    467. console.log(JSON.stringify(msg))
    468. await handleTextToAudio({
    469. isAlias,
    470. alias,
    471. isRoom,
    472. room,
    473. contentObj,
    474. contact,
    475. })
    476. } else if (wxMsgType === 'mj') {
    477. if (global.isLocal) {
    478. if (alias === '徐同保') {
    479. console.log(JSON.stringify(msg))
    480. await handleMj({
    481. isAlias,
    482. alias,
    483. isRoom,
    484. room,
    485. message,
    486. contentObj,
    487. contact,
    488. })
    489. } else {
    490. console.log('本地调试mj,其他人不能用')
    491. }
    492. } else {
    493. console.log(JSON.stringify(msg))
    494. await handleMj({
    495. isAlias,
    496. alias,
    497. isRoom,
    498. room,
    499. message,
    500. contentObj,
    501. contact,
    502. })
    503. }
    504. }
    505. } else if (waitingUploadType && waitingUploadAlias === alias) {
    506. const fileTypeList = [
    507. bot.Message.Type.Attachment,
    508. bot.Message.Type.Audio,
    509. bot.Message.Type.Image,
    510. bot.Message.Type.Video,
    511. ]
    512. if (fileTypeList.includes(msg.type())) {
    513. const fileBox = await msg.toFileBox()
    514. console.info(`Saving file ${fileBox.name}...`)
    515. let filePath = `/temp/ai/wx/${fileBox.name}`
    516. await fileBox.toFile(filePath, true)
    517. console.log('保存成功')
    518. await handleUploadFile({
    519. isAlias,
    520. alias,
    521. isRoom,
    522. room,
    523. message: '',
    524. contentObj: {},
    525. contact,
    526. fileBox,
    527. filePath,
    528. waitingUploadType,
    529. })
    530. } else {
    531. console.log('文件类型错误')
    532. }
    533. } else {
    534. //console.log('不是文本也不是上传文件')
    535. }
    536. }

    人工智能学习网站

    https://chat.xutongbao.top

  • 相关阅读:
    _c++11( lambda)
    批量控制教程-Ansible管理windows
    零信任产生的历史背景
    webpack构建工具面试题
    Linux系统编程系列之互斥锁和读写锁
    博客的评论与回复功能的实现
    开发者福利!李彦宏将在百度世界大会手把手教你做AI原生应用
    金蝶云苍穹-插件开发(四)GPT开发相关插件
    C语言,洛谷题,压缩技术2.0
    Twitter图片数据优化的细节
  • 原文地址:https://blog.csdn.net/xutongbao/article/details/138160809