飞书接入机器人NODE开发自动回复

一、创建飞书应用

1.登录飞书开放平台 进入开发者后台 创建自建应用

2.添加应用能力 选择机器人添加

3.添加事件订阅并根据权限开通权限  此处只添加获取消息事件

4.配置应用服务端地址(当事件触发 会触发设置的地址 并发送事件数据)开启Encrypt Key 实现回调数据加密 接收到数据后 通过开发文档 - 飞书开放平台 文档介绍 解密

 5.创建测试企业 测试人员 测试应用无压力不要审核

 二、搭建服务 接入 https 证书 创建api

const express = require('express')

const app = express()

const https = require('https');

// node接入证书
const options = {
	cert: fs.readFileSync('./ssl/xyz.pem'),
	key: fs.readFileSync('./ssl/xyz.key')
}
let server = https.createServer(options, app)

const bodyParser = require('body-parser')

app.use(bodyParser.urlencoded({
	extended: false
}))
app.use(bodyParser.json())

server.listen(8443, (err) => {
	if (!err) {
		console.log('服务器已启动 端口号8443:::')
		console.log('http://127.0.0.1:8443')
	}
})
app.all('*', function(req, res, next) {
	res.header('Access-Control-Allow-Origin', '*')
	res.header('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type')
	res.header('Access-Control-Allow-Methods', 'GET,POST,OPTIONS')
	next()
})

1.引入axios 调用飞书api接口做准备  npm i axios 并封装

// 封装axios
let tenantToken = ''
let tokenTimes = ''
const httpsAxios = async (url, data) => {
    if(!tenantToken || ((new Date().getTime() - tokenTimes ) / 1000) > 5400) {
        tokenTimes = new Date().getTime()
        tenantToken = await getTenantToken()
     }
    return new Promise((resolve, reject) => {
        axios({
            url,
            method: 'post',
            headers: { Authorization: `Bearer ${tenantToken}`, 'Content-Type': 'application/json; charset=utf-8' },
            data: data
        }).then(res=>{
            resolve(res)
        }).catch(err=>{
            reject(err)
        })
    })
}

2. 获取飞书的access_token 在调用api中 身份象征 

// 获取飞书 tenant_access_token 的方法
const getTenantToken = async () => {
    const Bool = await addFile()
    console.log(Bool)
    if(!Bool) {
        const url =
        'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal';
        const res = await axios.post(url, {
            app_id: obj.appID,
            app_secret: obj.EncryptKey
        });
        addFile(res.data)
        return res.data.tenant_access_token;
    } else {
        return Bool;
    }
}

2.1. addFile 存储 access_token 有效期为2小时 则设置为5400秒重新获取 , 没有用数据库 则使用文件json保存到本地目录下

const fs = require('fs');
const path = require('path');
// 存储数据access_token 到本地文件
const addFile = (data) => {
    const configFile = path.resolve(__dirname, './json/Info.json')
	let Obj = JSON.parse(fs.readFileSync(configFile, 'UTF-8').toString())
    return new Promise(re => {
        if(data) {
            Obj.tenant_access_token = data.tenant_access_token
            Obj.tenant_access_token_time = new Date().getTime()
            fs.writeFileSync(configFile, JSON.stringify(Obj))
            re(Obj.tenant_access_token)
        } else
        if (!Obj.tenant_access_token) {
            re(false)
        } else {
            let time = new Date().getTime()
            console.log((time - Obj.tenant_access_token_time ))
            // 一个小时三十分钟就重新获取
            if(((time - Obj.tenant_access_token_time ) / 1000) > 5400) {
                re(false)
            } else {
                re(Obj.tenant_access_token)
            }
        }
    })
}

3.事件订阅接收数据 接收数据 由于加密过的 需要AESCipher 解密 监听 im.message.receive_v1 获取用户发送的数据  如果你有gpt的话 可以接上webGpt

app.post('/gptTest', async (req, res) => {
    cipher = new AESCipher(obj.encrypt)
    let data = JSON.parse(cipher.decrypt(req.body.encrypt))
    console.log(data)
    //接收到的数据过期 10秒就不做处理
    if(new Date().getTime() - Number(data.header.create_time) > 10000) {
        res.send({
			data: {},
			message: 'err',
			code: 400
		})
        return
    }
	if (data.header.event_type == 'im.message.receive_v1') {
        let contents = JSON.parse(data.event.message.content)
        console.log(contents)
        console.log(data.event.sender.sender_id.open_id)
        let result = '测试'
        //GPT识别码
        if(contents.text.indexOf('GPT') != -1) {
            setMessages(data.event.sender.sender_id.open_id)
            result = await webGpt(contents.text.substring((contents.text.indexOf('GPT')+ 3)))
            console.log(result)
            if(!result) {
                result = '网络不稳定,请重试'
            }
        }
       
        const url = `https://open.feishu.cn/open-apis/im/v1/messages/${data.event.message.message_id}/reply`;
        // at功能
        // if (data.event.sender.sender_id.open_id) content = `<at user_id="${data.event.sender.sender_id.open_id}"></at> ${content}`;
        const getData = await httpsAxios(url, { content: JSON.stringify({ text: result }),"msg_type": "text"})
        res.send({
			data: {},
			message: 'success',
			code: 200
		})
    } else {
        res.send({
			data: {},
			message: 'err',
			code: 400
		})
    }
	// 	res.send({
	// 		challenge: req.body.challenge,
	// 		data: {},
	// 		message: 'err',
	// 		code: 500
	// 	})
})

 3.1  AESCipher 解密

// 解密接收事件数据
const crypto = require("crypto");
class AESCipher {
    constructor(key) {
        const hash = crypto.createHash('sha256');
        hash.update(key);
        this.key = hash.digest();
    }
    decrypt(encrypt) {
        const encryptBuffer = Buffer.from(encrypt, 'base64');
        const decipher = crypto.createDecipheriv('aes-256-cbc', this.key, encryptBuffer.slice(0, 16));
        let decrypted = decipher.update(encryptBuffer.slice(16).toString('hex'), 'hex', 'utf8');
        decrypted += decipher.final('utf8');
        return decrypted;
    }
}

3.2 回复用户信息 调取api 开发文档 - 飞书开放平台https://open.feishu.cn/open-apis/im/v1/messages/${data.event.message.message_id}/reply

let url = `https://open.feishu.cn/open-apis/im/v1/messages/${data.event.message.message_id}/reply`
let result = ''
const getData = await httpsAxios(url, { content: JSON.stringify({ text: result }),"msg_type": "text"})

3.3 发送信息给用户 调用 api 开发文档 - 飞书开放平台

https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id

//receive_id 用户open_id
const setMessages = (receive_id) =>{
    httpsAxios('https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=open_id', {
        "receive_id": receive_id,
        "msg_type": "text",
        "content": "{\"text\":\"等我C一下...\"}"
    }).then(res=>{
    }).catch(err=>{
    })
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,需要安装相应的 Python 包 `requests`,可以使用以下命令进行安装: ```python pip install requests ``` 接下来,可以编写一个 Python 脚本来将 ChatGPT4 接入飞书机器人。以下是一个简单的示例代码: ```python import requests import json # 将聊天内容作为输入,获取 ChatGPT4 的回复 def get_chatgpt4_response(input_text): url = 'https://api.openai.com/v1/engine/davinci-codex/completions' headers = { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_API_KEY' # 替换为你的 OpenAI API Key } data = json.dumps({ 'prompt': input_text, 'max_tokens': 60, 'temperature': 0.7 }) response = requests.post(url, headers=headers, data=data) response_dict = json.loads(response.text) return response_dict['choices'][0]['text'] # 发送机器人消息 def send_bot_message(message): url = 'https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_BOT_WEBHOOK' # 替换为你的机器人 Webhook headers = {'Content-Type': 'application/json'} data = { 'msg_type': 'text', 'content': { 'text': message } } response = requests.post(url, headers=headers, json=data) return response # 监听机器人消息 def listen_bot_message(): url = 'https://open.feishu.cn/open-apis/bot/v2/hook/YOUR_BOT_WEBHOOK' # 替换为你的机器人 Webhook headers = {'Content-Type': 'application/json'} response = requests.get(url, headers=headers) response_dict = json.loads(response.text) if response_dict['msg_type'] == 'text': input_text = response_dict['text']['content'] output_text = get_chatgpt4_response(input_text) send_bot_message(output_text) # 启动机器人 while True: listen_bot_message() ``` 以上代码中,`get_chatgpt4_response` 函数用于将聊天内容作为输入,获取 ChatGPT4 的回复;`send_bot_message` 函数用于发送机器人消息;`listen_bot_message` 函数用于监听机器人消息,并在收到消息后调用 `get_chatgpt4_response` 函数获取回复,并调用 `send_bot_message` 函数发送回复。最后,通过一个无限循环启动机器人,不断监听和回复消息。 注意,在代码中需要替换 `YOUR_API_KEY` 和 `YOUR_BOT_WEBHOOK` 为自己的 OpenAI API Key 和飞书机器人 Webhook。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值