mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2024-11-16 13:01:14 +00:00
refactor: send music card
feat: send mface
This commit is contained in:
parent
8ae0d07ec1
commit
2662e875ca
2
src/core
2
src/core
@ -1 +1 @@
|
||||
Subproject commit b8167109159bfda7057b95936e5470929462e4a0
|
||||
Subproject commit f22a4cee7dd1e41073b8e1ad7e99ada33c863992
|
Binary file not shown.
@ -1,4 +1,4 @@
|
||||
import { getGroup } from '@/core/data';
|
||||
import { getGroup, groupMembers } from '@/core/data';
|
||||
import { OB11GroupMember } from '../../types';
|
||||
import { OB11Constructor } from '../../constructor';
|
||||
import BaseAction from '../BaseAction';
|
||||
@ -8,7 +8,8 @@ import { WebApi } from '@/core/apis/webapi';
|
||||
import { logDebug } from '@/common/utils/log';
|
||||
|
||||
export interface PayloadType {
|
||||
group_id: number
|
||||
group_id: number,
|
||||
no_cache?: boolean | string
|
||||
}
|
||||
|
||||
|
||||
@ -23,10 +24,15 @@ class GetGroupMemberList extends BaseAction<PayloadType, OB11GroupMember[]> {
|
||||
if (!group) {
|
||||
throw (`群${payload.group_id}不存在`);
|
||||
}
|
||||
const GroupMember = OB11Constructor.groupMembers(group);
|
||||
if (payload.no_cache || payload.no_cache === 'true') {
|
||||
const _groupMembers = await NTQQGroupApi.getGroupMembers(payload.group_id.toString());
|
||||
groupMembers.set(group.groupCode, _groupMembers);
|
||||
}
|
||||
const _groupMembers = OB11Constructor.groupMembers(group);
|
||||
|
||||
// 方便索引处理
|
||||
for (let i = 0, len = GroupMember.length; i < len; i++) {
|
||||
MemberMap.set(GroupMember[i].user_id, GroupMember[i]);
|
||||
for (let i = 0, len = _groupMembers.length; i < len; i++) {
|
||||
MemberMap.set(_groupMembers[i].user_id, _groupMembers[i]);
|
||||
}
|
||||
// 合并数据
|
||||
for (let i = 0, len = WebGroupMember.length; i < len; i++) {
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
import {
|
||||
OB11MessageCustomMusic,
|
||||
OB11MessageData,
|
||||
OB11MessageDataType,
|
||||
OB11MessageDataType, OB11MessageIdMusic,
|
||||
OB11MessageMixType,
|
||||
OB11MessageNode,
|
||||
OB11PostSendMsg
|
||||
@ -27,10 +27,10 @@ import { log, logDebug, logError } from '@/common/utils/log';
|
||||
import { sleep } from '@/common/utils/helper';
|
||||
import { uri2local } from '@/common/utils/file';
|
||||
import { getFriend, getGroup, getGroupMember, getUidByUin, selfInfo } from '@/core/data';
|
||||
import { NTQQMsgApi } from '../../../core/src/apis';
|
||||
import { NTQQFileApi } from '../../../core/src/apis';
|
||||
import { NTQQMsgApi } from '@/core/apis';
|
||||
import { NTQQFileApi } from '@/core/apis';
|
||||
import { ob11Config } from '@/onebot11/config';
|
||||
import { CustomMusicSignPostData, MusicSign } from '@/core/apis/sign';
|
||||
import { CustomMusicSignPostData, IdMusicSignPostData, MusicSign } from '@/core/apis/sign';
|
||||
|
||||
const ALLOW_SEND_TEMP_MSG = false;
|
||||
|
||||
@ -46,23 +46,29 @@ function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
||||
const data = msg['data'];
|
||||
if (type === 'text' && !data['text']) {
|
||||
return 400;
|
||||
} else if (['image', 'voice', 'record'].includes(type)) {
|
||||
}
|
||||
else if (['image', 'voice', 'record'].includes(type)) {
|
||||
if (!data['file']) {
|
||||
return 400;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (checkUri(data['file'])) {
|
||||
return 200;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (type === 'at' && !data['qq']) {
|
||||
return 400;
|
||||
} else if (type === 'reply' && !data['id']) {
|
||||
}
|
||||
else if (type === 'at' && !data['qq']) {
|
||||
return 400;
|
||||
}
|
||||
} else {
|
||||
else if (type === 'reply' && !data['id']) {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 400;
|
||||
}
|
||||
}
|
||||
@ -82,16 +88,18 @@ export function convertMessage2List(message: OB11MessageMixType, autoEscape = fa
|
||||
text: message
|
||||
}
|
||||
}];
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
message = decodeCQCode(message.toString());
|
||||
}
|
||||
} else if (!Array.isArray(message)) {
|
||||
}
|
||||
else if (!Array.isArray(message)) {
|
||||
message = [message];
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
async function genCustomMusicElement(url: string, audio: string, title: string, image: string | undefined, singer: string | undefined): Promise<SendArkElement | undefined> {
|
||||
async function genMusicElement(postData: IdMusicSignPostData | CustomMusicSignPostData): Promise<SendArkElement | undefined> {
|
||||
// const musicJson = {
|
||||
// app: 'com.tencent.structmsg',
|
||||
// config: {
|
||||
@ -123,35 +131,19 @@ async function genCustomMusicElement(url: string, audio: string, title: string,
|
||||
// ver: '0.0.0.1',
|
||||
// view: 'news'
|
||||
// };
|
||||
try{
|
||||
const postData: CustomMusicSignPostData = {
|
||||
type: 'custom',
|
||||
url,
|
||||
audio,
|
||||
title,
|
||||
image,
|
||||
singer
|
||||
};
|
||||
const musicJson = await new MusicSign(ob11Config.musicSignUrl).sign(postData);
|
||||
return SendMsgElementConstructor.ark(musicJson);
|
||||
}catch (e) {
|
||||
logError('生成音乐消息失败', e);
|
||||
const signUrl = ob11Config.musicSignUrl;
|
||||
if (!signUrl) {
|
||||
throw Error('音乐消息签名地址未配置');
|
||||
}
|
||||
}
|
||||
|
||||
async function genIdMusicElement(type: 'qq' | '163', id: string | number): Promise<SendArkElement | undefined> {
|
||||
try {
|
||||
const postData = {
|
||||
type,
|
||||
id
|
||||
};
|
||||
const musicJson = await new MusicSign(ob11Config.musicSignUrl).sign(postData);
|
||||
const musicJson = await new MusicSign(signUrl).sign(postData);
|
||||
return SendMsgElementConstructor.ark(musicJson);
|
||||
} catch (e) {
|
||||
logError('生成音乐消息失败', e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function createSendElements(messageData: OB11MessageData[], group: Group | undefined, ignoreTypes: OB11MessageDataType[] = []) {
|
||||
const sendElements: SendMessageElement[] = [];
|
||||
const deleteAfterSentFiles: string[] = [];
|
||||
@ -176,7 +168,8 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
atQQ = atQQ.toString();
|
||||
if (atQQ === 'all') {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, '全体成员'));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// const atMember = group?.members.find(m => m.uin == atQQ)
|
||||
const atMember = await getGroupMember(group?.groupCode, atQQ);
|
||||
if (atMember) {
|
||||
@ -203,7 +196,12 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case OB11MessageDataType.mface: {
|
||||
sendElements.push(
|
||||
SendMsgElementConstructor.mface(sendMsg.data.emoji_package_id, sendMsg.data.emoji_id, sendMsg.data.key, sendMsg.data.summary),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case OB11MessageDataType.image:
|
||||
case OB11MessageDataType.file:
|
||||
case OB11MessageDataType.video:
|
||||
@ -215,9 +213,11 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
if (cache) {
|
||||
if (fs.existsSync(cache.path)) {
|
||||
file = 'file://' + cache.path;
|
||||
} else if (cache.url) {
|
||||
}
|
||||
else if (cache.url) {
|
||||
file = cache.url;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
const fileMsg = await dbUtil.getMsgByLongId(cache.msgId);
|
||||
if (fileMsg) {
|
||||
const downloadPath = await NTQQFileApi.downloadMedia(fileMsg.msgId, fileMsg.chatType, fileMsg.peerUid,
|
||||
@ -247,7 +247,8 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
if (sendMsg.type === OB11MessageDataType.file) {
|
||||
logDebug('发送文件', path, payloadFileName || fileName);
|
||||
sendElements.push(await SendMsgElementConstructor.file(path, payloadFileName || fileName));
|
||||
} else if (sendMsg.type === OB11MessageDataType.video) {
|
||||
}
|
||||
else if (sendMsg.type === OB11MessageDataType.video) {
|
||||
logDebug('发送视频', path, payloadFileName || fileName);
|
||||
let thumb = sendMsg.data?.thumb;
|
||||
if (thumb) {
|
||||
@ -257,9 +258,11 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
}
|
||||
}
|
||||
sendElements.push(await SendMsgElementConstructor.video(path, payloadFileName || fileName, thumb));
|
||||
} else if (sendMsg.type === OB11MessageDataType.voice) {
|
||||
}
|
||||
else if (sendMsg.type === OB11MessageDataType.voice) {
|
||||
sendElements.push(await SendMsgElementConstructor.ptt(path));
|
||||
} else if (sendMsg.type === OB11MessageDataType.image) {
|
||||
}
|
||||
else if (sendMsg.type === OB11MessageDataType.image) {
|
||||
sendElements.push(await SendMsgElementConstructor.pic(path, sendMsg.data.summary || '', <PicSubType>parseInt(sendMsg.data?.subType?.toString() || '0')));
|
||||
}
|
||||
}
|
||||
@ -283,43 +286,38 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
case OB11MessageDataType.markdown: {
|
||||
const content = sendMsg.data?.content;
|
||||
sendElements.push(SendMsgElementConstructor.markdown(content));
|
||||
}break;
|
||||
case OB11MessageDataType.music:{
|
||||
}
|
||||
break;
|
||||
case OB11MessageDataType.music: {
|
||||
const musicData = sendMsg.data;
|
||||
try {
|
||||
let musicMsgElement: SendArkElement | undefined;
|
||||
if (musicData.type === 'custom'){
|
||||
if (!musicData.url){
|
||||
logError('自定义音卡缺少参数url');
|
||||
break;
|
||||
}
|
||||
if (!musicData.audio){
|
||||
logError('自定义音卡缺少参数audio');
|
||||
break;
|
||||
}
|
||||
if (!musicData.title){
|
||||
logError('自定义音卡缺少参数title');
|
||||
break;
|
||||
}
|
||||
musicMsgElement = await genCustomMusicElement(musicData.url, musicData.audio, musicData.title, musicData.image, musicData.singer);
|
||||
if (musicData.type === 'custom') {
|
||||
if (!musicData.url) {
|
||||
logError('自定义音卡缺少参数url');
|
||||
break;
|
||||
}
|
||||
else{
|
||||
if (!['qq', '163'].includes(musicData.type)){
|
||||
logError('音乐卡片type错误, 只支持qq和163,当前type:', musicData.type);
|
||||
break;
|
||||
}
|
||||
if (!musicData.id){
|
||||
logError('音乐卡片缺少参数id');
|
||||
break;
|
||||
}
|
||||
musicMsgElement = await genIdMusicElement(musicData.type, musicData.id);
|
||||
if (!musicData.audio) {
|
||||
logError('自定义音卡缺少参数audio');
|
||||
break;
|
||||
}
|
||||
logDebug('生成音乐消息', musicMsgElement);
|
||||
if (musicMsgElement) {
|
||||
sendElements.push(musicMsgElement);
|
||||
if (!musicData.title) {
|
||||
logError('自定义音卡缺少参数title');
|
||||
break;
|
||||
}
|
||||
} catch (e) {
|
||||
logError('生成音乐消息失败', e);
|
||||
}
|
||||
else {
|
||||
if (!['qq', '163'].includes(musicData.type)) {
|
||||
logError('音乐卡片type错误, 只支持qq、163、custom,当前type:', musicData.type);
|
||||
break;
|
||||
}
|
||||
if (!musicData.id) {
|
||||
logError('音乐卡片缺少参数id');
|
||||
break;
|
||||
}
|
||||
}
|
||||
const musicMsgElement = await genMusicElement(sendMsg.data);
|
||||
logDebug('生成音乐消息', musicMsgElement);
|
||||
if (musicMsgElement) {
|
||||
sendElements.push(musicMsgElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,7 +410,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
if (friend) {
|
||||
// peer.name = friend.nickName
|
||||
peer.peerUid = friend.uid;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
peer.chatType = ChatType.temp;
|
||||
const tempUserUid = getUidByUin(payload.user_id.toString());
|
||||
if (!tempUserUid) {
|
||||
@ -426,11 +425,14 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
if (payload?.group_id && payload.message_type === 'group') {
|
||||
await genGroupPeer();
|
||||
|
||||
} else if (payload?.user_id) {
|
||||
}
|
||||
else if (payload?.user_id) {
|
||||
await genFriendPeer();
|
||||
} else if (payload.group_id) {
|
||||
}
|
||||
else if (payload.group_id) {
|
||||
await genGroupPeer();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw ('发送消息参数错误, 请指定group_id或user_id');
|
||||
}
|
||||
const messages = convertMessage2List(payload.message, payload.auto_escape === true || payload.auto_escape === 'true');
|
||||
@ -440,25 +442,19 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
if (returnMsg) {
|
||||
const msgShortId = await dbUtil.addMsg(returnMsg!, false);
|
||||
return { message_id: msgShortId };
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw Error('发送转发消息失败');
|
||||
}
|
||||
} catch (e: any) {
|
||||
throw Error('发送转发消息失败 ' + e.toString());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (this.getSpecialMsgNum(payload, OB11MessageDataType.music)) {
|
||||
const music: OB11MessageCustomMusic = messages[0] as OB11MessageCustomMusic;
|
||||
if (music) {
|
||||
const { url, audio, title, content, image } = music.data;
|
||||
const selfPeer: Peer = { peerUid: selfInfo.uid, chatType: ChatType.friend };
|
||||
// 搞不定!
|
||||
// const musicMsg = await this.send(selfPeer, [this.genMusicElement(url, audio, title, content, image)], [], false)
|
||||
// 转发
|
||||
// const res = await NTQQApi.forwardMsg(selfPeer, peer, [musicMsg.msgId])
|
||||
// log("转发音乐消息成功", res);
|
||||
// return {message_id: musicMsg.msgShortId}
|
||||
}
|
||||
// if (music) {
|
||||
// }
|
||||
}
|
||||
}
|
||||
// log("send msg:", peer, sendElements)
|
||||
@ -525,7 +521,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
const nodeMsg = await dbUtil.getMsgByShortId(parseInt(nodeId));
|
||||
if (!needClone) {
|
||||
nodeMsgIds.push(nodeMsg!.msgId);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (nodeMsg!.peerUid !== selfInfo.uid) {
|
||||
const cloneMsg = await this.cloneMsg(nodeMsg!);
|
||||
if (cloneMsg) {
|
||||
@ -533,7 +530,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// 自定义的消息
|
||||
// 提取消息段,发给自己生成消息id
|
||||
try {
|
||||
@ -555,7 +553,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
sendElementsSplit[splitIndex] = [ele];
|
||||
splitIndex++;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sendElementsSplit[splitIndex].push(ele);
|
||||
}
|
||||
logDebug(sendElementsSplit);
|
||||
@ -586,7 +585,8 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
nodeMsgArray.push(nodeMsg);
|
||||
if (!srcPeer) {
|
||||
srcPeer = { chatType: nodeMsg.chatType, peerUid: nodeMsg.peerUid };
|
||||
} else if (srcPeer.peerUid !== nodeMsg.peerUid) {
|
||||
}
|
||||
else if (srcPeer.peerUid !== nodeMsg.peerUid) {
|
||||
needSendSelf = true;
|
||||
srcPeer = selfPeer;
|
||||
}
|
||||
@ -628,7 +628,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
export default SendMsg;
|
||||
|
@ -17,7 +17,7 @@ import {
|
||||
GrayTipElementSubType,
|
||||
Group,
|
||||
GroupMember,
|
||||
IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT,
|
||||
IMAGE_HTTP_HOST, IMAGE_HTTP_HOST_NT, mFaceCache,
|
||||
RawMessage,
|
||||
SelfInfo,
|
||||
Sex,
|
||||
@ -232,7 +232,7 @@ export class OB11Constructor {
|
||||
}
|
||||
else if (element.marketFaceElement) {
|
||||
message_data['type'] = OB11MessageDataType.mface;
|
||||
message_data['data']['text'] = element.marketFaceElement.faceName;
|
||||
message_data['data']['summary'] = element.marketFaceElement.faceName;
|
||||
const md5 = element.marketFaceElement.emojiId;
|
||||
// 取md5的前两位
|
||||
const dir = md5.substring(0, 2);
|
||||
@ -240,6 +240,10 @@ export class OB11Constructor {
|
||||
// const url = `https://p.qpic.cn/CDN_STATIC/0/data/imgcache/htdocs/club/item/parcel/item/${dir}/${md5}/300x300.gif?max_age=31536000`;
|
||||
const url = `https://gxh.vip.qq.com/club/item/parcel/item/${dir}/${md5}/raw300.gif`;
|
||||
message_data['data']['url'] = url;
|
||||
message_data['data']['emoji_id'] = element.marketFaceElement.emojiId;
|
||||
message_data['data']['emoji_package_id'] = String(element.marketFaceElement.emojiPackageId);
|
||||
message_data['data']['key'] = element.marketFaceElement.key;
|
||||
mFaceCache.set(md5, element.marketFaceElement.faceName);
|
||||
}
|
||||
else if (element.markdownElement) {
|
||||
message_data['type'] = OB11MessageDataType.markdown;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { PicSubType, RawMessage } from '@/core';
|
||||
import { EventType } from './event/OB11BaseEvent';
|
||||
import { CustomMusicSignPostData, IdMusicSignPostData } from '@/core/apis/sign';
|
||||
|
||||
export interface OB11User {
|
||||
user_id: number;
|
||||
@ -124,10 +125,12 @@ export enum OB11MessageDataType {
|
||||
}
|
||||
|
||||
export interface OB11MessageMFace {
|
||||
type: OB11MessageDataType.mface,
|
||||
type: OB11MessageDataType.mface
|
||||
data: {
|
||||
text: string,
|
||||
url: string
|
||||
emoji_package_id: number
|
||||
emoji_id: string
|
||||
key: string
|
||||
summary: string
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,22 +206,11 @@ export interface OB11MessageNode {
|
||||
|
||||
export interface OB11MessageIdMusic {
|
||||
type: OB11MessageDataType.music
|
||||
data: {
|
||||
type: 'qq' | '163',
|
||||
id: string | number,
|
||||
}
|
||||
data: IdMusicSignPostData
|
||||
}
|
||||
export interface OB11MessageCustomMusic {
|
||||
type: OB11MessageDataType.music
|
||||
data: {
|
||||
type: 'custom'
|
||||
url: string,
|
||||
audio: string,
|
||||
title: string,
|
||||
content?: string,
|
||||
image?: string,
|
||||
singer?: string,
|
||||
}
|
||||
data: CustomMusicSignPostData
|
||||
}
|
||||
|
||||
export interface OB11MessageJson {
|
||||
|
Loading…
Reference in New Issue
Block a user