node.js wechaty实现微信机器人聊天,定时发送消息

目录

  • 1.介绍
  • 2.插件安装运行
  • 3.快速上手

1.介绍

本项目主要是node wechaty的一个小应用,其核心原理主要通过wechaty插件登录网页版微信接受消息进行通信以及其他功能等。这里只做了聊天接收展示,图灵机器人接入指定人聊天,通过爬虫每日一说,墨迹天气定时给指定人发送消息等

1.主要功能
登录后可在微信发送以下内容
‘开启:’ 开启图灵机器人聊天(可指定微信好友)

‘关闭:’ 关闭灵机器人聊天

定时给女友发送暖心问候 1.墨迹天气 2.每日一句

2.插件安装运行

本项目主要需要安装一下插件

"dependencies": {
    "cheerio": "^1.0.0-rc.3", // 网络抓取要识别Web页面,并将其转换成结构化数据
    "node-schedule": "^1.3.2", // Nodejs定时任务
    "qrcode-terminal": "^0.12.0",// 在终端输出二维码
    "request": "^2.88.2", // node request请求
    "request-promise": "^4.2.5", // request请求promise形式回调返回
    "wechaty": "^0.38.4" // 开源的微信SDK
  }

没装yarn 的可以使用npm

安装依赖 yarn install

运行yarn start

3.快速上手

1.所有配置项均在 config/index.js文件中

// 配置文件
  module.exports = {
    NAME: 'xxx', //女朋友备注姓名
    NICKNAME: 'xxx', //女朋友昵称
    MEMORIAL_DAY: '2017/05/11', //你和女朋友的纪念日
    SENDDATE: '00 00 08 * * *', //定时发送时间 每天8点0分0秒发送,规则见 npm schedule
    MOJI_HOST: 'https://tianqi.moji.com/weather/china/',
    CITY:'shaanxi',//收信者所在城市
    LOCATION:'yanta-district',//收信者所在区
    ONE: 'http://wufazhuce.com/',
    //图灵机器人功能配置项
    AUTOREPLY: false, //自动聊天功能 默认关闭 开启设置为: true
    TULINGURL: 'http://openapi.tuling123.com/openapi/api/v2',
    TULINGKEY: '',//图灵机器人apikey,需要自己到图灵机器人官网申请,并且需要认证http://www.turingapi.com/

  }

2.代码实现

const { Wechaty } = require('wechaty')
const QrcodeTerminal = require('qrcode-terminal')
const cheerio = require('cheerio')
const schedule = require('node-schedule')
const { post, get } = require('./utils/request')
const tools = require('./utils/timeTools')
const config = require('./config/index')

/**
 *
 * 获取图灵机器人消息
 * @param {*} text 传入聊天内容
 * @returns
 */
const getNews = (text) => {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res
    reject = rej
  })
  post(config.TULINGURL, {
    reqType:0,
      perception: {
          inputText: {
            text
          },
      },
      userInfo: {
        apiKey: config.TULINGKEY,
        userId: "485b3f76446f8b99"
      }
  })
  .then((res) => {
    if (res.intent.code !=0 && res.intent.code > 10000) {
      resolve(res)
    } else {
      reject(res)
    }
  })
  .catch(res => {
    reject(res)
  })
  return promise
}
// 获取每日一句
const getOne = async() =>{
  // 获取每日一句
  try {
    let res = await get(config.ONE);
    let $ = cheerio.load(res);
    let todayOneList = $('#carousel-one .carousel-inner .item');
    let todayOne = $(todayOneList[0])
      .find('.fp-one-cita')
      .text()
      .replace(/(^\s*)|(\s*$)/g, '');
    return todayOne;
  } catch (err) {
    console.log('错误', err);
    return err;
  }
}
// 获取墨迹天气
const getWeather = async() => {
  let url = config.MOJI_HOST + config.CITY+'/'+config.LOCATION
  let res = await get(url)
  let $ = cheerio.load(res)
  let weatherTips = $('.wea_tips em').text()
  const today = $('.forecast .days').first().find('li');
  let todayInfo = {
      Day:$(today[0]).text().replace(/(^\s*)|(\s*$)/g, ""),
      WeatherText:$(today[1]).text().replace(/(^\s*)|(\s*$)/g, ""),
      Temp:$(today[2]).text().replace(/(^\s*)|(\s*$)/g, ""),
      Wind:$(today[3]).find('em').text().replace(/(^\s*)|(\s*$)/g, ""),
      WindLevel:$(today[3]).find('b').text().replace(/(^\s*)|(\s*$)/g, ""),
      PollutionLevel:$(today[4]).find('strong').text().replace(/(^\s*)|(\s*$)/g, "")
  }
  let obj = {
    weatherTips:weatherTips,
    todayWeather:todayInfo.Day + ':' + todayInfo.WeatherText + '
'
+ '温度:' + todayInfo.Temp + '
'
+ todayInfo.Wind + todayInfo.WindLevel + '
'
+ '空气:' + todayInfo.PollutionLevel + '
'
} return obj } // 定时任务 const main = async() => { let contact = await bot.Contact.find({name:config.NICKNAME}) || await bot.Contact.find({alias:config.NAME}) // 获取你要发送的联系人 let one = await getOne() //获取每日一句 let weather = await getWeather() //获取天气信息 let today = await tools.formatDate(new Date())//获取今天的日期 let memorialDay = tools.getDay(config.MEMORIAL_DAY)//获取纪念日天数 let str = today + '
'
+ '今天是我们在一起的第' + memorialDay + '天' + '

今日天气早知道

'
+ weather.weatherTips +'

'
+weather.todayWeather+ '每日一句:

'
+one+'

'
+'------来自最爱你的我' await contact.say(str)//发送消息 } // 二维码生成 const onScan = (qrcode, code) => { QrcodeTerminal.generate(qrcode) // 在console端显示二维码 const qrcodeImageUrl = [ 'https://api.qrserver.com/v1/create-qr-code/?data=', encodeURIComponent(qrcode), ].join('') console.log(qrcodeImageUrl) } // 登录 const onLogin = (user) => { console.log(`User ${user} logined`) schedule.scheduleJob(config.SENDDATE, () => { console.log('小助理开始工作啦!') main() }) } // 登出 const onLogout = (user) => { console.log(`User ${user} 登出`) } // 监听消息 /** * * * @param {*} message 消息 */ const onMessage = async(message) => { const contact = message.from() // 发消息人 const content = message.text().trim() // 消息内容 const room = message.room() // 是否是群消息 const alias = await contact.alias(); // 发消息人备注 const isText = message.type() === bot.Message.Type.Text; // 是否是文字 if (content === '开启:') { // 通过输入内容开启关闭图灵机器人 config.AUTOREPLY = true } else if (content === '关闭:'){ config.AUTOREPLY = false } if (message.self()) { return } if (room && isText) { // 如果是群消息 目前只处理文字消息 const topic = await room.topic(); console.log(`群名: ${topic} 发消息人: ${contact.name()} 内容: ${content}`); } else if (isText) { // 如果非群消息 目前只处理文字消息 console.log(`发消息人: ${alias} 消息内容: ${content}`); if(alias == config.NAME) { if (config.AUTOREPLY) { const news = await getNews(content).catch(err => console.log(err,'机器人接口出错啦')) await message.say(news.results[0].values.text) } } } } const bot = new Wechaty({ name: 'yeshen' }); bot.on('scan', onScan) .on('login', onLogin) .on('logout', onLogout) .on('message', onMessage) bot.start() .then(() => console.log('开始登录微信')) .catch(err => console.error(err))

项目github

你可能感兴趣的:(Node.js,nodejs,javascript)