背景
顶岗实习期间学校要求用学习通每日打卡,打卡时候会获取经纬度和所在地名称,经纬度出现偏差就会导致打卡失败。
一方面不会每天都在这个范围内,另一方面就是怕某天忘记打卡。所以写个bot每天上QQ看到发条消息就算打卡啦。
效果图:
1.编写插件
在app抓包得到的Cookie很久都不会变,不用担心失效的问题,所以在bot保存配置文件时直接写入死的Cookie即可
import {Context} from 'koishi'
import axios from 'axios'
import qs from 'qs'
import * as fs from "fs";
export const name = 'xuexitong'
axios.defaults.withCredentials = true
function addAccount(userId, username, password, cookies) {
// 判断文件是否存在
const filePath = `${__dirname}/accounts.txt`
if (!fs.existsSync(filePath)) {
fs.writeFileSync(filePath, '')
}
// 追加写入内容
const data = `${userId}\t${username}\t${password}\t${cookies}\n`
fs.appendFileSync(filePath, data)
}
function readAccount(userId: string) {
// 判断文件是否存在
const filePath = `${__dirname}/accounts.txt`
if (!fs.existsSync(filePath)) {
return null
}
// 读取文件内容
const data = fs.readFileSync(filePath, 'utf-8')
const lines = data.split('\n')
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
const [id, username, password, cookies] = line.split('\t')
if (id === userId) {
return {username, password, cookies}
}
}
return null
}
export function apply(ctx: Context) {
// write your plugin here
ctx.middleware((session, next) => {
// 用户号码绑定
if (session.content.indexOf('账户绑定') === 0) {
// 将消息按空格分为3份
let arr = session.content.split(' ')
// 判断是否有账号密码
if (arr.length !== 3) {
return '请输入正确的格式:账户绑定 号码 密码'
}
let username = arr[1]
let password = arr[2]
const params = new URLSearchParams()
params.append("uname", username)
params.append("code", password);
params.append("loginType", '1');
params.append("roleSelect", 'true');
// 发送请求 判断是否可用
return axios.post('https://passport2-api.chaoxing.com/v11/loginregister?cx_xxt_passport=json', params)
.then(res => {
if (res.data.mes.indexOf('验证通过') !== -1) {
// 可用
let cookie = res.headers['set-cookie'];
let cookieStr = '';
// 循环cookie 截取每一个cookie;前的字符串
for (let i = 0; i < cookie.length; i++) {
cookieStr += cookie[i].split(';')[0] + ';';
}
addAccount(session.userId, username, password, cookieStr);
return '账户绑定成功'
} else {
return '账户绑定失败,原因:' + res.data.mes
}
}).catch(err => {
return '账户绑定失败,失败原因' + err.message
})
}
// 学习通签到
if (session.content === '学习通签到') {
// 判断是否绑定
let account = readAccount(session.userId)
if (!account) {
return '请先绑定账号'
}
// 获取yyyy-MM-dd格式的日期
let date = new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let dateStr = `${year}-${month}-${day}`
return axios.post('http://xingtai.dgsx.chaoxing.com/mobile/clockin/addclockin2', qs.stringify({
'pcid': 3680,
'pcmajorid': 2457050,
'address': 'xxxx夏万杰存',
'geolocation': '110.437392,30.479040',
'remark': '',
'workStart': dateStr + ' 08:00:00',
'workEnd': dateStr + ' 18:00:00',
'images': '',
'allowOffset': 2000,
'offset': 13,
'offduty': 0
}), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Cookie': account.cookies
}
}).then(res => {
return res.data.msg;
})
}
return next()
}
)
}
2.托管到服务器上
在官网没看到部署教程,就决定照着自己思路来吧
2.1 先下载相应的go-cqhttp,并在后台跑起来!
go-cqhttp Release: https://github.com/Mrs4s/go-cqhttp/releases
根据上图的命令查询对应linux版本,我对应下载的为 go-cqhttp_linux_amd64.tar.gz
接着解压然后运行go-cqhttp.
mkdir go-cqhttp
cd go-cqhttp
wget https://github.com/Mrs4s/go-cqhttp/releases/download/v1.0.0-rc1/go-cqhttp_linux_amd64.tar.gz
tar -zxvf go-cqhttp_linux_amd64.tar.gz
# 后台运行 会输出到运行目录下的nohup.out
nohup ./go-cqhttp
# 直接运行
./go-cqhttp
需要扫码登录,但是扫描出现了安全提示,无法登录..
于是先在本地环境登录了一下,复制go-cqhttp目录下的session.token到服务器同目录下,再次启动就正常登录用户啦!
2.2 go-cqhttp跑起来后再跑Koishi
Koishi携带了web端的控制台,直接搭建一个网站运行它!
直接使用宝塔 稍稍配置一下
其他的不用动,nginx我也没有配置!
直接根据绑定的域名访问,就到达了Koishi控制台
3.停止项目
3.1 停止go-cqhttp
由于运行的时候是通过后台运行的:
# 后台运行 会输出到运行目录下的nohup.out
nohup ./go-cqhttp
停止时先检索后台应用:
ps -aux | grep "go-cqhttp"
第一组数字:3149356
,就是go-cqhttp的pid 接着执行
kill 3149356
即可干掉后台进程!
3.2 停止koishi
这个好弄,由于Koishi有web的控制台
启动的时候是通过宝塔搭建网站的方式启动的,那么需要停止的直接去停止这个网站就行了。
参考文档/项目
1.API文档|Koishi: https://koishi.js.org/api/
2.go-cqhttp帮助中心: https://docs.go-cqhttp.org/
评论 (0)