参照资料学习并且手写一个微信机器人聊天等等

主要使用 Wechaty 库来进行


const { Wechaty } = require('wechaty');
const bot = new Wechaty({ name: 'xxx' })  // 记录一个签名用于免扫码登陆
const Qrcode = require('qrcode-terminal');  //可以在终端显示二维码
const autoBot = require('./utils/getReply'); //引入自动回复
const config = require('./config')  
const initTask = require('./utils/timeTask')  //定时任务
bot.start().then(() => console.log('开始登陆微信'))
    .catch(e => console.error(e));
bot.on('scan', (qrcode, status) => {
    let qrcodeSrc = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(qrcode)}`
    Qrcode.generate(qrcode, { small: true });
})

bot.on('login', handleLogin) 

bot.on('message', handleMessage)  //处理消息

async function handleLogin(user) {
    console.log(`用户${user}登陆成功`);
    initTask(_=>{
        console.log('执行定时任务=====>')
        init();
    })
}

async function handleMessage(messge) {
    let contact = messge.from();   //发送人
    const room = messge.room();    //群消息
    const alias = await contact.alias();   //发送人的备注  name()发送人昵称
    const name = await contact.name();
    const content = messge.text().trim();  //发送的消息
    if (messge.self()) {
        console.log(`跳过自己的回复,${contact.name()}`)
        return
    }
    if (room) {
        console.log(`群名:${await room.topic()} 发消息人:${contact.name()} 内容:${content}`)
        //可以回复群里消息  
         if(await room.topic() === '好好学习天天向上'){
             let reply = await autoBot.getBotReply(content)
             room.say(reply);
         }
    } else {
    //这里的逻辑可以自己写 都可以调用getReply.js里的接口来进行回复
        if (content.includes('天气')) {
            let reply = await autoBot.getWetherInfo()
            contact.say(reply);
        }
        console.log(`类型: ${contact}`)
        console.log(`发消息人备注: ${await contact.alias()} 消息内容: ${content}`)

    }
}


//初始化任务 发送天气预报
async function init() {
    const friend = await bot.Contact.find({ name: config.NICK_NAME }) || await bot.Contact.find({ alias: config.ALISA })
    let reply = await autoBot.getWetherInfo()
    //还可以发送 新闻 每日一说 自己调用就行了
    await friend.say(reply);
}

在当前目录下可以新建一个config.js来自定义设置

//建议大家自己注册  
module.exports = {
    TULING_KEY:'d6cdb25d7e1145f5877bf8d3dc915cb6',  //图灵机器人api
    TIANXING_KEY:'cba50d45aca1560837508d06932b88cf',   //天行api
    TIME_TASK:['12:01','23:59'],   //定时任务时间
    NICK_NAME:''",  //昵称
    ALISA:'xxx' ,   //备注名
    LOCATION:'贵阳' ,  //别加  市
    GROUPNAME:['好好学习天天向上'],
}

因为要使用定时任务 所以用到了node-schedule模块
新建一个utils文件夹

//timeTask.js
const schedule = require('node-schedule');
const config = require('../config')
    /**
     * @param{function}  执行回调函数
     * 
     * scheduleJob arguments :
     *  ┬ ┬ ┬ ┬ ┬ ┬
        │ │ │ │ │ |
        │ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
        │ │ │ │ └───── month (1 - 12)
        │ │ │ └────────── day of month (1 - 31)
        │ │ └─────────────── hour (0 - 23)
        │ └──────────────────── minute (0 - 59)
        └───────────────────────── second (0 - 59, OPTIONAL)
     */

module.exports = function task(callback) {
    if(typeof callback !== 'function' && !callback){
        console.log('参数错误');
        return
    }
    for(let t of config.TIME_TASK){
        let c = t.split(':');
        schedule.scheduleJob(`0 ${c[1]} ${c[0]} * * *`, _=>callback());
    }
}

定时执行有了现在需要获取自动回复的机器人接口

//在utils文件夹下新建getReply.js
const cry = require("crypto");
const { machineIdSync } = require('node-machine-id');
const config = require('../config')
const http = require('./http')   
const cheerio = require('cheerio');
let md5 = cry.createHash('md5');
let userId = md5.update(machineIdSync()).digest('hex');
//这里我用了几个接口来获取
//新闻,天气,机器人,每日一句

const touTiaoApi = 'http://api.tianapi.com/topnews/index';
//获取机器人回复
//因为这api需要每次访问提供一个唯一的id 所以使用 node-machine-id' 和 md5 模块来生成唯一id
async function getBotReply(word) {
    let data = {
        "reqType": 0,
        "perception": {
            "inputText": {
                "text": word || '你叫什么名字',
            },
            "selfInfo": {
                "location": {
                    "city": config.LOCATION,
                }
            },
        },
        "userInfo": {
            "apiKey": config.TULING_KEY,
            "userId": userId
        }
    };
    let response = await http('http://openapi.tuling123.com/openapi/api/v2', 'post', data);
    let content = response.data;
    return content.results[0].values.text  || '机器人api获取出错'
}

//获取今日天气
async function getWetherInfo(){
    const res = await http(`http://api.tianapi.com/txapi/tianqi/index?key=${config.TIANXING_KEY}&city=${encodeURI(config.LOCATION)}`,'get')
    if(res.data.code == 200){
        let result = res.data.newslist[0];
        let str = `今日天气早知道:\n${result.date} ${result.week} \n天气:${result.weather} 最高温:${result.lowest}  最低温:${result.highest} \n风力:${result.windspeed} 风向:${result.wind} 空气质量等级:${result.air_level} 空气质量指数:${result.air} \ntip:${result.tips}`
        return str || '天气获取出错'
    }
}
//用node版的jq cheerio模块来爬去数据
async function getOneText(){
    const response = await http('http://wufazhuce.com/','get')
    const $ = cheerio.load(response.data);
    const parent = $('#carousel-one .carousel-inner .item');
    const text = $(parent[0]).find('.fp-one-cita').text().trim()
    return text || '每日一句获取出错'
}
//获取新闻热点
let count = '5' //新闻条数
async function getTopNews(){
    let url = `${touTiaoApi}?key=${config.TIANXING_KEY}&num=${count}`
    const response = await http(url,'get');
    if(response.data.code == 200){
        const list = response.data.newslist;
        let text = `今日新闻: \n${list.map(item=>{
            return `${item.ctime} \n${item.title}\n${item.description}\n<a src=${item.url} >查看详情</a>`
        })}`

        return text
    }
    return '获取新闻出错'
}

module.exports = {
    getBotReply,
    getWetherInfo,
    getOneText,
    getTopNews
}

因为简单封装了一下http请求,所以在utls下新建http.js

//http.js
const axios = require('axios');
function http(url,method,param){
    return new Promise((resove,reject)=>{
        const options = {
            method,
            headers: { "Content-Type": "application/x-www-form-urlencoded" },
            url,
            data: param
        }
        axios(options).then(res=>{
            try {
                resove(res)
            } catch (error) {
                reject(error)
            }
        })
    })
}
module.exports = http
在微信小程序中实现上传文件和手写签名的功能,需要分成几个步骤来完成: 1. **文件上传**:使用微信小程序的 `wx.uploadFile` API 来实现文件上传的功能。这个API能够将本地资源上传到开发者服务器。 2. **签名功能**:利用canvas组件来实现手写签名。用户可以在canvas上进行签名,然后通过 `wx.canvasToTempFilePath` 将签名转换为图片路径。 3. **后端接口**:需要一个后端服务来接收上传的文件和签名图片,可以使用Node.js、PHP、Java等语言来搭建。 下面是一个简单的实现示例: **前端代码(微信小程序)**: 1. WXML文件: ```xml <view class="container"> <canvas canvas-id="signature" disable-scroll="true" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"></canvas> <button bindtap="uploadFile">上传文件</button> <button bindtap="uploadSignature">上传签名</button> </view> ``` 2. WXSS文件(设置样式): ```css .container { display: flex; flex-direction: column; align-items: center; padding: 20px; } canvas { border: 1px solid #ccc; margin-bottom: 10px; } ``` 3. JS文件: ```javascript Page({ data: { // 签名的base64数据 signatureData: '' }, touchStart: function(e) { // 开始触摸事件 }, touchMove: function(e) { // 移动触摸事件 }, touchEnd: function(e) { // 结束触摸事件 this.setData({ signatureData: this.data.canvasData }); }, uploadFile: function() { var that = this; wx.chooseMessageFile({ count: 1, type: 'file', success(res) { const filePath = res.tempFiles[0].path; wx.uploadFile({ url: '你的上传文件的服务器地址', // 开发者服务器的地址 filePath: filePath, name: 'file', success(uploadRes) { console.log(uploadRes.data); // 这里可以处理服务器返回的数据,如上传成功后的提示等 } }) } }) }, uploadSignature: function() { var that = this; wx.canvasToTempFilePath({ canvasId: 'signature', success(res) { that.setData({ signatureData: res.tempFilePath }); wx.uploadFile({ url: '你的上传签名的服务器地址', // 开发者服务器的地址 filePath: res.tempFilePath, name: 'signature', success(uploadRes) { console.log(uploadRes.data); // 这里可以处理服务器返回的数据,如上传成功后的提示等 } }) } }) } }) ``` **后端代码示例(使用Node.js)**: ```javascript const express = require('express'); const multer = require('multer'); const app = express(); // 配置multer用于处理文件上传 const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, 'uploads/') // 上传文件存储的位置 }, filename: function (req, file, cb) { cb(null, file.fieldname + '-' + Date.now()) } }); const upload = multer({ storage: storage }); // 文件上传接口 app.post('/upload', upload.single('file'), function(req, res){ // 文件信息可以通过req.file获取 // 文件保存的路径是 req.file.path // 返回成功结果给前端 res.send('上传成功'); }); // 签名图片上传接口 app.post('/upload-signature', upload.single('signature'), function(req, res){ // 处理逻辑同上 res.send('签名图片上传成功'); }); app.listen(3000, function() { console.log('服务器启动在3000端口'); }); ``` 需要注意的是,上述代码仅为示例,实际使用中需要根据具体需求进行调整。另外,在使用multer上传文件时,你需要确保服务器有足够的权限来保存上传的文件,并且要处理好安全性问题,如验证上传文件的类型等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值