feat:表情上传功能

This commit is contained in:
Jerry 2025-10-12 00:09:46 +08:00
parent 0992d0d809
commit 5d8fe40860
6 changed files with 225 additions and 1 deletions

View File

@ -1,7 +1,23 @@
import plugin from '../../../lib/plugins/plugin.js';
import ConfigControl from '../lib/config/configControl.js';
import configControl from '../lib/config/configControl.js';
import Meme from '../lib/core/meme.js';
imporexport default class UpMeme extends plugin {
constructor() {
super({
name: '上传表情包',
dsc: 'yeye',
event: 'message',
priority: '-114',
rule: [
{
reg: '^#上传(\\d+)?$',
fnc: 'up',
},
],
});
}
}
t Meme from '../lib/core/meme.js';
import NapcatService from '../lib/login/napcat.js';
import LgrService from '../lib/login/lgr.js';
const loginSessions = new Map(); //正在进行的登录会话

84
apps/upMeme.js Normal file
View File

@ -0,0 +1,84 @@
import plugin from '../../../lib/plugins/plugin.js';
import axios from 'axios';
import YunzaiUtils from '../lib/yunzai/utils.js';
import ConfigControl from '../lib/config/configControl.js';
const uploadSessions = new Map(); // 正在进行的上传会话
export default class MemeUploadService extends plugin {
constructor() {
super({
name: '表情包上传服务',
dsc: '通过引用消息或发送图片上传表情包',
event: 'message',
priority: 50,
rule: [
{
reg: '^#上传表情$',
fnc: 'startUpload',
},
],
});
}
/**
* 上传入口
* @param e
*/
async startUpload(e) {
if (!e.isMaster) return e.reply('不许你上传哦', true);
const key = e.user_id;
if (uploadSessions.has(key)) return e.reply('你已经在上传流程中了..', true);
const imgs = await YunzaiUtils.getImages(e, 1);
if (!imgs.length) return e.reply('你图片搁哪呢?', true);
uploadSessions.set(key, { step: 'askCharacter', img: imgs[0] });
return e.reply('这表情叫什么?', true);
}
async accept(e) {
const key = e.user_id;
const session = uploadSessions.get(key);
if (!session) return;
const text = (e.message || [])
.filter((m) => m.type === 'text')
.map((m) => m.text)
.join('')
.trim();
if (session.step === 'askCharacter') {
session.character = text;
session.step = 'askStatus';
return e.reply('表情处于什么状态?', true);
}
if (session.step === 'askStatus') {
session.status = text;
uploadSessions.delete(key);
try {
const formData = new FormData();
const res = await fetch(session.img);
const blob = await res.blob();
formData.append('file', blob, 'meme.jpg');
formData.append('character', session.character);
formData.append('status', session.status);
const token = await ConfigControl.get('config')?.coreConfig?.token;
const coreUrl = await ConfigControl.get('config')?.coreConfig?.coreUrl;
await axios.post(`${coreUrl}/api/meme/upload`, formData, {
headers: {
'x-token': token,
...formData.getHeaders?.(),
},
});
return e.reply('上传成功~', true);
} catch (err) {
console.error(err);
return e.reply('上传失败..', true);
}
}
}
}

32
lib/yunzai/group.js Normal file
View File

@ -0,0 +1,32 @@
const Group = {
/**
* 群戳一戳
* @param e
* @param user_id 被戳的用户
* @param group_id 群号
* @returns {Promise<*>}
*/
async groupPoke(e, user_id, group_id) {
return await e.bot.sendApi('group_poke', {
group_id: group_id,
user_id: user_id,
});
},
/**
* 群踢人
* @param e
* @param user_id 要踢的人
* @param group_id 群号
* @param ban 是否允许再次加群
* @returns {Promise<*>}
*/
async groupKick(e, user_id, group_id, ban) {
return await e.bot.sendApi('set_group_kick', {
user_id: user_id,
group_id: group_id,
reject_add_request: ban,
});
},
};
export default Group;

40
lib/yunzai/message.js Normal file
View File

@ -0,0 +1,40 @@
const Message = {
/**
* 群撤回消息
* @param e
* @param message_id 消息id
* @returns {Promise<*>}
*/
async deleteMsg(e, message_id) {
return await e.bot.sendApi('delete_msg', {
message_id: message_id,
});
},
/**
* 群表情回应
* @param e
* @param message_id 消息id
* @param emoji_id 表情id
* @param group_id 群号
* @param adapter nc/lgr
* @returns {Promise<*>}
*/
async emojiLike(e, message_id, emoji_id, group_id, adapter) {
if (adapter === 'nc') {
return await e.bot.sendApi('set_msg_emoji_like', {
message_id: message_id,
emoji_id: emoji_id,
set: true,
});
} else if (adapter === 'lgr') {
return await e.bot.sendApi('set_group_reaction', {
group_id: group_id,
message_id: message_id,
code: emoji_id,
is_add: true,
});
}
},
};
export default Message;

3
lib/yunzai/self.js Normal file
View File

@ -0,0 +1,3 @@
const Self = {};
export default Self;

49
lib/yunzai/utils.js Normal file
View File

@ -0,0 +1,49 @@
export default class YunzaiUtils {
/**
* 获取消息中的图片
* @param e
* @param limit 限制
* @returns {Promise<string[]>}
*/
static async getImages(e, limit = 1) {
let imgUrls = [];
const me = `https://q1.qlogo.cn/g?b=qq&s=640&nk=${e.user_id}`;
// 获取引用消息
if (e.source || e.reply_id) {
let reply;
if (e.getReply) reply = await e.getReply();
else {
const history = await (e.isGroup ? e.group : e.friend).getChatHistory(
e.isGroup ? e.source.seq : e.source.time,
1
);
reply = history?.pop();
}
if (reply) {
const msgArr = Array.isArray(reply) ? reply : reply.message || [];
imgUrls = msgArr.filter((m) => m.type === 'image').map((m) => m.url);
}
}
if (!imgUrls.length && e.message) {
imgUrls = e.message.filter((m) => m.type === 'image').map((m) => m.url);
}
if (!imgUrls.length) imgUrls = [me];
return imgUrls.slice(0, limit);
}
/**
* 看看使用的是哪个适配器
* @param e
* @returns {Promise<*>}
*/
static async getAdapter(e) {
const adapter = e.bot.version?.app_name;
if (adapter === 'NapCat.Onebot') {
return 'nc';
} else if (adapter === 'Lagrange.OneBot') {
return 'lgr';
} else return 'nc';
}
}