mirror of
https://github.com/LLOneBot/LLOneBot.git
synced 2024-11-22 01:56:33 +00:00
feat: 发送戳一戳
This commit is contained in:
@@ -47,7 +47,7 @@ import {dbUtil} from "../common/db";
|
||||
import {setConfig} from "./setConfig";
|
||||
import {NTQQUserApi} from "../ntqqapi/api/user";
|
||||
import {NTQQGroupApi} from "../ntqqapi/api/group";
|
||||
import {registerPokeHandler} from "../ntqqapi/external/ccpoke";
|
||||
import {crychic} from "../ntqqapi/external/crychic";
|
||||
import {OB11FriendPokeEvent, OB11GroupPokeEvent} from "../onebot11/event/notice/OB11PokeEvent";
|
||||
import {checkNewVersion, upgradeLLOneBot} from "../common/utils/upgrade";
|
||||
import {log} from "../common/utils/log";
|
||||
@@ -183,7 +183,8 @@ function onLoad() {
|
||||
|
||||
async function startReceiveHook() {
|
||||
if (getConfigUtil().getConfig().enablePoke) {
|
||||
registerPokeHandler((id, isGroup) => {
|
||||
crychic.loadNode()
|
||||
crychic.registerPokeHandler((id, isGroup) => {
|
||||
log(`收到戳一戳消息了!是否群聊:${isGroup},id:${id}`)
|
||||
let pokeEvent: OB11FriendPokeEvent | OB11GroupPokeEvent;
|
||||
if (isGroup) {
|
||||
|
@@ -21,6 +21,10 @@ import {encodeSilk} from "../common/utils/audio";
|
||||
|
||||
|
||||
export class SendMsgElementConstructor {
|
||||
|
||||
static poke(groupCode: string, uin: string){
|
||||
return null
|
||||
}
|
||||
static text(content: string): SendTextElement {
|
||||
return {
|
||||
elementType: ElementType.TEXT,
|
||||
|
28
src/ntqqapi/external/ccpoke/index.ts
vendored
28
src/ntqqapi/external/ccpoke/index.ts
vendored
@@ -1,28 +0,0 @@
|
||||
import {log} from "../../../common/utils/log";
|
||||
|
||||
let pokeEngine: any = null
|
||||
|
||||
type PokeHandler = (id: string, isGroup: boolean)=>void
|
||||
|
||||
let pokeRecords: Record<string, number> = {}
|
||||
export function registerPokeHandler(handler: PokeHandler){
|
||||
if(!pokeEngine){
|
||||
try {
|
||||
pokeEngine = require("./ccpoke/poke-win32-x64.node")
|
||||
pokeEngine.performHooks();
|
||||
}catch (e) {
|
||||
log("戳一戳引擎加载失败", e)
|
||||
return
|
||||
}
|
||||
}
|
||||
pokeEngine.setHandlerForPokeHook((id: string, isGroup: boolean)=>{
|
||||
let existTime = pokeRecords[id]
|
||||
if (existTime){
|
||||
if (Date.now() - existTime < 1500){
|
||||
return
|
||||
}
|
||||
}
|
||||
pokeRecords[id] = Date.now()
|
||||
handler(id, isGroup);
|
||||
})
|
||||
}
|
BIN
src/ntqqapi/external/ccpoke/poke-win32-x64.node
vendored
BIN
src/ntqqapi/external/ccpoke/poke-win32-x64.node
vendored
Binary file not shown.
BIN
src/ntqqapi/external/crychic/crychic-win32-x64.node
vendored
Normal file
BIN
src/ntqqapi/external/crychic/crychic-win32-x64.node
vendored
Normal file
Binary file not shown.
53
src/ntqqapi/external/crychic/index.ts
vendored
Normal file
53
src/ntqqapi/external/crychic/index.ts
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
import {log} from "../../../common/utils";
|
||||
import {NTQQApi} from "../../ntcall";
|
||||
|
||||
type PokeHandler = (id: string, isGroup: boolean) => void
|
||||
type CrychicHandler = (event: string, id: string, isGroup: boolean) => void
|
||||
|
||||
let pokeRecords: Record<string, number> = {}
|
||||
|
||||
class Crychic{
|
||||
private crychic: any = undefined
|
||||
|
||||
loadNode(){
|
||||
if (!this.crychic){
|
||||
try {
|
||||
this.crychic = require("./crychic-win32-x64.node")
|
||||
this.crychic.init()
|
||||
}catch (e) {
|
||||
log("crychic加载失败", e)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
registerPokeHandler(fn: PokeHandler){
|
||||
this.registerHandler((event, id, isGroup)=>{
|
||||
if (event === "poke"){
|
||||
let existTime = pokeRecords[id]
|
||||
if (existTime) {
|
||||
if (Date.now() - existTime < 1500) {
|
||||
return
|
||||
}
|
||||
}
|
||||
pokeRecords[id] = Date.now()
|
||||
fn(id, isGroup);
|
||||
}
|
||||
})
|
||||
}
|
||||
registerHandler(fn: CrychicHandler){
|
||||
if (!this.crychic) return;
|
||||
this.crychic.setCryHandler(fn)
|
||||
}
|
||||
sendFriendPoke(friendUid: string){
|
||||
if (!this.crychic) return;
|
||||
this.crychic.sendFriendPoke(parseInt(friendUid))
|
||||
NTQQApi.fetchUnitedCommendConfig().then()
|
||||
}
|
||||
sendGroupPoke(groupCode: string, memberUin: string){
|
||||
if (!this.crychic) return;
|
||||
this.crychic.sendGroupPoke(parseInt(memberUin), parseInt(groupCode))
|
||||
NTQQApi.fetchUnitedCommendConfig().then()
|
||||
}
|
||||
}
|
||||
|
||||
export const crychic = new Crychic()
|
@@ -77,7 +77,9 @@ export enum NTQQApiMethod {
|
||||
|
||||
SET_QQ_AVATAR = 'nodeIKernelProfileService/setHeader',
|
||||
GET_SKEY = "nodeIKernelTipOffService/getPskey",
|
||||
UPDATE_SKEY = "updatePskey"
|
||||
UPDATE_SKEY = "updatePskey",
|
||||
|
||||
FETCH_UNITED_COMMEND_CONFIG = "nodeIKernelUnitedConfigService/fetchUnitedCommendConfig" // 发包需要调用的
|
||||
}
|
||||
|
||||
enum NTQQApiChannel {
|
||||
@@ -194,4 +196,15 @@ export class NTQQApi {
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
static async fetchUnitedCommendConfig() {
|
||||
return await callNTQQApi<GeneralCallResult>({
|
||||
methodName: NTQQApiMethod.FETCH_UNITED_COMMEND_CONFIG,
|
||||
args:[
|
||||
{
|
||||
groups: ['100243']
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
AtType,
|
||||
ChatType,
|
||||
ElementType,
|
||||
ElementType, Friend,
|
||||
Group, PicSubType,
|
||||
RawMessage,
|
||||
SendArkElement,
|
||||
@@ -35,6 +35,7 @@ import {NTQQMsgApi} from "../../../ntqqapi/api/msg";
|
||||
import {log} from "../../../common/utils/log";
|
||||
import {sleep} from "../../../common/utils/helper";
|
||||
import {uri2local} from "../../../common/utils";
|
||||
import {crychic} from "../../../ntqqapi/external/crychic";
|
||||
|
||||
function checkSendMessage(sendMsgList: OB11MessageData[]) {
|
||||
function checkUri(uri: string): boolean {
|
||||
@@ -93,7 +94,7 @@ export function convertMessage2List(message: OB11MessageMixType, autoEscape = fa
|
||||
return message;
|
||||
}
|
||||
|
||||
export async function createSendElements(messageData: OB11MessageData[], group: Group | undefined, ignoreTypes: OB11MessageDataType[] = []) {
|
||||
export async function createSendElements(messageData: OB11MessageData[], target: Group | Friend | undefined, ignoreTypes: OB11MessageDataType[] = []) {
|
||||
let sendElements: SendMessageElement[] = []
|
||||
let deleteAfterSentFiles: string[] = []
|
||||
for (let sendMsg of messageData) {
|
||||
@@ -109,7 +110,7 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
}
|
||||
break;
|
||||
case OB11MessageDataType.at: {
|
||||
if (!group) {
|
||||
if (!target) {
|
||||
continue
|
||||
}
|
||||
let atQQ = sendMsg.data?.qq;
|
||||
@@ -119,7 +120,7 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atQQ, AtType.atAll, "全体成员"))
|
||||
} else {
|
||||
// const atMember = group?.members.find(m => m.uin == atQQ)
|
||||
const atMember = await getGroupMember(group?.groupCode, atQQ);
|
||||
const atMember = await getGroupMember((target as Group)?.groupCode, atQQ);
|
||||
if (atMember) {
|
||||
sendElements.push(SendMsgElementConstructor.at(atQQ, atMember.uid, AtType.atUser, atMember.cardName || atMember.nick))
|
||||
}
|
||||
@@ -197,7 +198,22 @@ export async function createSendElements(messageData: OB11MessageData[], group:
|
||||
case OB11MessageDataType.json: {
|
||||
sendElements.push(SendMsgElementConstructor.ark(sendMsg.data.data))
|
||||
}
|
||||
break
|
||||
break;
|
||||
case OB11MessageDataType.poke: {
|
||||
let qq = sendMsg.data?.qq || sendMsg.data?.id
|
||||
if (qq) {
|
||||
if ("groupCode" in target) {
|
||||
crychic.sendGroupPoke(target.groupCode, qq.toString())
|
||||
} else {
|
||||
if (!qq) {
|
||||
qq = parseInt(target.uin)
|
||||
}
|
||||
crychic.sendFriendPoke(qq.toString())
|
||||
}
|
||||
sendElements.push(SendMsgElementConstructor.poke("", ""))
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -232,7 +248,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
message: "转发消息不能和普通消息混在一起发送,转发需要保证message只有type为node的元素"
|
||||
}
|
||||
}
|
||||
if (payload.message_type !== "private" && payload.group_id &&!(await getGroup(payload.group_id))) {
|
||||
if (payload.message_type !== "private" && payload.group_id && !(await getGroup(payload.group_id))) {
|
||||
return {
|
||||
valid: false,
|
||||
message: `群${payload.group_id}不存在`
|
||||
@@ -261,6 +277,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
let isTempMsg = false;
|
||||
let group: Group | undefined = undefined;
|
||||
let friend: Friend | undefined = undefined;
|
||||
const genGroupPeer = async () => {
|
||||
group = await getGroup(payload.group_id.toString())
|
||||
peer.chatType = ChatType.group
|
||||
@@ -269,7 +286,7 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
|
||||
const genFriendPeer = () => {
|
||||
const friend = friends.find(f => f.uin == payload.user_id.toString())
|
||||
friend = friends.find(f => f.uin == payload.user_id.toString())
|
||||
if (friend) {
|
||||
// peer.name = friend.nickName
|
||||
peer.peerUid = friend.uid
|
||||
@@ -318,7 +335,12 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
}
|
||||
// log("send msg:", peer, sendElements)
|
||||
const {sendElements, deleteAfterSentFiles} = await createSendElements(messages, group)
|
||||
const {sendElements, deleteAfterSentFiles} = await createSendElements(messages, group || friend)
|
||||
if (sendElements.length === 1){
|
||||
if (sendElements[0] === null){
|
||||
return {message_id: 0}
|
||||
}
|
||||
}
|
||||
const returnMsg = await sendMsg(peer, sendElements, deleteAfterSentFiles)
|
||||
deleteAfterSentFiles.map(f => fs.unlink(f, () => {
|
||||
}));
|
||||
@@ -478,8 +500,6 @@ export class SendMsg extends BaseAction<OB11PostSendMsg, ReturnDataType> {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private genMusicElement(url: string, audio: string, title: string, content: string, image: string): SendArkElement {
|
||||
const musicJson = {
|
||||
app: 'com.tencent.structmsg',
|
||||
|
@@ -116,7 +116,8 @@ export enum OB11MessageDataType {
|
||||
markdown = "markdown",
|
||||
node = "node", // 合并转发消息节点
|
||||
forward = "forward", // 合并转发消息,用于上报
|
||||
xml = "xml"
|
||||
xml = "xml",
|
||||
poke = "poke"
|
||||
}
|
||||
|
||||
export interface OB11MessageMFace{
|
||||
@@ -132,6 +133,14 @@ export interface OB11MessageText {
|
||||
}
|
||||
}
|
||||
|
||||
export interface OB11MessagePoke{
|
||||
type: OB11MessageDataType.poke
|
||||
data: {
|
||||
qq?: number,
|
||||
id?: number
|
||||
}
|
||||
}
|
||||
|
||||
interface OB11MessageFileBase {
|
||||
data: {
|
||||
thumb?: string;
|
||||
@@ -217,7 +226,7 @@ export type OB11MessageData =
|
||||
OB11MessageFace | OB11MessageMFace |
|
||||
OB11MessageAt | OB11MessageReply |
|
||||
OB11MessageImage | OB11MessageRecord | OB11MessageFile | OB11MessageVideo |
|
||||
OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson
|
||||
OB11MessageNode | OB11MessageCustomMusic | OB11MessageJson | OB11MessagePoke
|
||||
|
||||
export interface OB11PostSendMsg {
|
||||
message_type?: "private" | "group"
|
||||
|
Reference in New Issue
Block a user