main.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. const { WechatyBuilder } = require("wechaty")
  2. const { sendMessageToAPI } = require('./ChatGPT')
  3. const sqlite3 = require('sqlite3')
  4. //sqlite数据库路径
  5. let sqliteDbPath = "./db/data.db"
  6. //打开数据库
  7. let db = new sqlite3.Database(sqliteDbPath)
  8. const wechaty = WechatyBuilder.build()
  9. function getConfigValue(configName) {
  10. return new Promise((resolve, reject) => {
  11. const query = 'SELECT value FROM wxconfig WHERE config = ?'
  12. db.get(query, [configName], (err, row) => {
  13. if (err) {
  14. reject(err)
  15. } else {
  16. const configValue = row ? row.value : null
  17. // 处理字符串 'null',如果是 'null' 则返回 null
  18. resolve(configValue === 'null' ? null : configValue)
  19. }
  20. })
  21. })
  22. }
  23. // 读取配置信息并设置相应的变量
  24. async function loadConfigValues() {
  25. try {
  26. autoReplySingle = await getConfigValue('autoReplySingle') === 'true'
  27. prefix = await getConfigValue('prefix')
  28. suffix = await getConfigValue('suffix')
  29. whiteRoomString = await getConfigValue('whiteRoom')
  30. keyWordsString = await getConfigValue('keyWords')
  31. blackNameString = await getConfigValue('blackName')
  32. atReply = await getConfigValue('atReply') === 'true'
  33. // 处理转义符
  34. suffix = suffix !== null ? suffix.replace(/\\n/g, '\n') : ''
  35. prefix = prefix !== null ? prefix.replace(/\\n/g, '\n') : ''
  36. // 处理用逗号分隔的字符串形式的数组
  37. whiteRoom = whiteRoomString !== null ? whiteRoomString.split(",").map(item => item.trim()) : []
  38. keyWords = keyWordsString !== null ? keyWordsString.split(",").map(item => item.trim()) : []
  39. blackName = blackNameString !== null ? blackNameString.split(",").map(item => item.trim()) : []
  40. } catch (error) {
  41. console.error('Error loading config values:', error)
  42. }
  43. }
  44. // 调用函数加载配置信息
  45. loadConfigValues()
  46. //获取时间
  47. function getCurrentTime() {
  48. const options = {
  49. year: 'numeric',
  50. month: '2-digit',
  51. day: '2-digit',
  52. hour: '2-digit',
  53. minute: '2-digit',
  54. second: '2-digit',
  55. }
  56. const currentTime = new Date().toLocaleString('zh-CN', options)
  57. return currentTime
  58. }
  59. //停止函数运行
  60. let isRunning = false
  61. async function stopWx() {
  62. if (isRunning) {
  63. isRunning = false
  64. await wechaty.stop()
  65. Status.status = 0
  66. }
  67. }
  68. let Status = { status: null }
  69. let User = {name: null}
  70. async function wxlogin() {
  71. if (isRunning) {
  72. isRunning = false
  73. await wechaty.stop()
  74. Status.status = 0
  75. }
  76. isRunning = true
  77. return new Promise((resolve, reject) => {
  78. let qrcodeUrl
  79. // 解除之前绑定的所有事件处理程序
  80. wechaty.removeAllListeners()
  81. wechaty
  82. .on('scan', (qrcode, status) => {
  83. qrcodeUrl = `https://my.tv.sohu.com/user/a/wvideo/getQRCode.do?text=${encodeURIComponent(qrcode)}`
  84. Status.status = status
  85. // 将 qrcodeUrl 提前返回
  86. resolve(qrcodeUrl)
  87. })
  88. .on('login', async (user) => {
  89. Status.status = 200
  90. // 获取登录用户的信息
  91. const contact = await wechaty.Contact.find({ id: user.id })
  92. const name = await contact.name()
  93. const avatarFileBox = await contact.avatar()
  94. User.name = name
  95. // 将头像保存到本地
  96. const avatarFilePath = `./wechat/avatar/avatar.jpg`
  97. await avatarFileBox.toFile(avatarFilePath,true)
  98. // 有程序运行后配置未加载的问题,这里重新加载一遍
  99. loadConfigValues()
  100. })
  101. .on('logout', async () => {
  102. Status.status = null
  103. isRunning = false
  104. await wechaty.stop()
  105. })
  106. .on('message',async (message) => {
  107. if (message.self()) {
  108. return
  109. } else {
  110. if (message.type() === wechaty.Message.Type.Text) {
  111. const content = message.text()
  112. const room = message.room()
  113. const talker = message.talker()
  114. const talkername = message.talker().payload.name
  115. const foundWords = keyWords.filter(word => content.includes(word))
  116. if (room) {
  117. const roomname = message.room().payload.topic
  118. if (whiteRoom.length === 0 || whiteRoom.includes(roomname)) {
  119. //在群聊中被@
  120. if (await message.mentionSelf()) {
  121. console.log('机器人被@')
  122. if (atReply) {
  123. const apiMessage = await sendMessageToAPI(content)
  124. const senmsg = '@' + talkername + ' ' + prefix + apiMessage + suffix
  125. room.say(senmsg)
  126. //写入数据库
  127. writeToDatabase({
  128. time: getCurrentTime(),
  129. type: '群聊',
  130. recmsg: content,
  131. senmsg: senmsg,
  132. name: talkername,
  133. roomname: roomname,
  134. })
  135. return
  136. }
  137. } else if (foundWords.length > 0) {
  138. console.log('发现关键字')
  139. const apiMessage = await sendMessageToAPI(content)
  140. const senmsg = '@' + talkername + ' ' + prefix + apiMessage + suffix
  141. room.say(senmsg)
  142. //写入数据库
  143. writeToDatabase({
  144. time: getCurrentTime(),
  145. type: '群聊',
  146. recmsg: content,
  147. senmsg: senmsg,
  148. name: talkername,
  149. roomname: roomname,
  150. })
  151. return
  152. }
  153. } else {
  154. return
  155. }
  156. } else {
  157. if (autoReplySingle) {
  158. if (blackName.includes(talkername)) {
  159. return
  160. } else {
  161. const apiMessage = await sendMessageToAPI(content)
  162. const senmsg = prefix + apiMessage + suffix
  163. talker.say(senmsg)
  164. writeToDatabase({
  165. time: getCurrentTime(),
  166. type: '私聊',
  167. recmsg: content,
  168. senmsg: senmsg,
  169. name: message.talker().payload.name,
  170. roomname: null,
  171. })
  172. return
  173. }
  174. }
  175. }
  176. } else {
  177. return
  178. }
  179. }
  180. }
  181. )
  182. wechaty.start()
  183. wechaty.on('error', (error) => {
  184. reject(error)
  185. })
  186. })
  187. }
  188. //向数据库写入数据
  189. function writeToDatabase(data) {
  190. const { time, type, recmsg, senmsg, name, roomname } = data
  191. const insertQuery = `INSERT INTO message (time, type, recmsg, senmsg, name, roomname) VALUES (?, ?, ?, ?, ?, ?)`
  192. db.run(insertQuery, [time, type, recmsg, senmsg, name, roomname], (error) => {
  193. if (error) {
  194. console.error('数据库写入失败:', error)
  195. }
  196. })
  197. }
  198. // 更新设置到数据库
  199. function updateConfigValue(configName, configValue) {
  200. const query = 'INSERT OR REPLACE INTO wxconfig (config, value) VALUES (?, ?)'
  201. db.run(query, [configName, configValue], (err) => {
  202. if (err) {
  203. console.error('数据库写入失败:', err)
  204. }
  205. })
  206. }
  207. function setWx(key,value) {
  208. updateConfigValue(key,value)
  209. }
  210. module.exports = {
  211. wxlogin,
  212. Status,
  213. setWx,
  214. stopWx,
  215. loadConfigValues,
  216. User
  217. }