packageDocumentation export * from "./command" ; export * from "./message" ; export * from "./file" ; export * from "./resp" ; export * from "./utils" ; import type { AxiosResponse , AxiosStatic } from "axios" ; import type { Api , Config , EventType , MessageType , MiraiApiHttpSetting , UserProfile , } from "../types" ; import FormData from "form-data" ; import WebSocket from "ws" ; import { Command } from "./command" ; import { File } from "./file" ; import { Resp } from "./resp" ; import { getMessageFromStatusCode } from "./utils" ; import Logger from "@yunyoujun/logger" ; import chalk from "chalk" ; import { toMessageChain } from "./message" ; import type { Mirai } from "../mirai" ; type WsCallbackMap = { message : ( msg : MessageType . ChatMessage ) => any ; event : ( event : EventType . Event ) => any ; all : ( data : EventType . Event | MessageType . ChatMessage ) => any ; } ; /**
 * 基础的验证参数
 */ interface BaseVerifyParams { verifyKey : string ; } export class MiraiApiHttp { setting : MiraiApiHttpSetting ; sessionKey = "" ; /**
     * http adapter
     */ http : { address : string ; } = { address : "" , } ; /**
     * WebSocket SessionKey
     */ ws : { sessionKey : string ; address : string ; client ? : WebSocket ; } = { sessionKey : "" , address : "" , } ; qq = 0 ; verified = false ; command : Command ; file : File ; /**
     * [申请事件 | EventType](https://github.com/project-mirai/mirai-api-http/blob/master/docs/EventType.md#%E7%94%B3%E8%AF%B7%E4%BA%8B%E4%BB%B6)
     */ resp : Resp ; public logger = new Logger ( { prefix : chalk . cyan ( "[mirai-api-http]" ) } ) ; constructor ( public mirai , public axios ) { this . setting = this . mirai . mahSetting ; const wsSetting = this . setting . adapterSettings . ws ; this . ws . address = this . mirai . options . ws ?. address || `ws://${ wsSetting . host }:${ wsSetting . port }` ; const httpSetting = this . setting . adapterSettings . http ; this . http . address = this . mirai . options . http ?. address || `http://${ httpSetting . host }:${ httpSetting . port }` ; this . axios . defaults . baseURL = this . http . address ; this . axios . defaults . maxContentLength = Infinity ; this . axios . defaults . maxBodyLength = Infinity ; this . command = new Command ( this ) ; this . file = new File ( this ) ; this . resp = new Resp ( this ) ; } /**
     * 拦截 mirai 错误信息
     */ async handleStatusCode ( ) { this . axios . interceptors . response . use ( async ( res ) => { if ( res . status === 200 && res . data ) { const statusCode = ( res . data as any ) . code ; const message = getMessageFromStatusCode ( statusCode ) ; if ( statusCode && message ) { this . logger . error ( `Code ${ statusCode }: ${ message }` ) ; if ( statusCode === 3 || statusCode === 4 ) { this . logger . warning ( "正在尝试重新建立连接..." ) ; await this . verify ( ) ; await this . bind ( this . qq ) ; } } } return res ; } , ( err ) => { this . logger . error ( `响应失败：${ err . message }` ) ; if ( process . env . NODE_ENV !== "production" ) { console . error ( err ) ; } return Promise . reject ( err ) ; } ) ; } /**
     * 使用此方法获取插件的信息，如版本号
     * data.data: { "version": "v1.0.0" }
     */ async about ( ) { const { data } = await this . axios . get < null , AxiosResponse < Api . Response . About > > ( "/about" ) ; return data ; } /**
     * 使用此方法验证你的身份，并返回一个会话
     */ async verify ( verifyKey = this . setting . verifyKey ) { this . logger . info ( `[http] Address: ${ this . http . address }` ) ; const { data } = await this . axios . post < BaseVerifyParams , AxiosResponse < Api . Response . Auth > > ( "/verify" , { verifyKey , } ) ; if ( data . code === 0 ) { this . sessionKey = data . session ; if ( this . axios . defaults . headers ) ( this . axios . defaults . headers . common as any ) [ "sessionKey" ] = this . sessionKey ; } return data ; } /**
     * 使用此方法校验并激活你的Session，同时将Session与一个已登录的Bot绑定
     */ async bind ( qq ) { this . qq = qq ; const { data } = await this . axios . post < Api . Params . RequestParams < { qq : number ; } > , AxiosResponse < Api . Response . BaseResponse > > ( "/bind" , { sessionKey : this . sessionKey , qq , } ) ; this . verified = data . code === 0 ; return data ; } /**
     * 使用此方式释放 session 及其相关资源（Bot不会被释放） 不使用的 Session 应当被释放，长时间（30分钟）未使用的 Session 将自动释放。
     * 否则 Session 持续保存Bot收到的消息，将会导致内存泄露(开启websocket后将不会自动释放)
     */ async release ( qq = this . qq ) { const { data } = await this . axios . post < Api . Params . RequestParams < { qq : number ; } > , AxiosResponse < Api . Response . BaseResponse > > ( "/release" , { sessionKey : this . sessionKey , qq , } ) ; if ( data . code === 0 ) { this . verified = false ; } return data ; } param count async fetchMessage ( count = 10 ) { const { data } = await this . axios . get < Api . Params . RequestParams < { count : number ; } > , AxiosResponse < Api . Response . FetchMessage > > ( "/fetchMessage" , { params : { sessionKey : this . sessionKey , count , } , } ) ; return data ; } param count async fetchLatestMessage ( count = 10 ) { const { data } = await this . axios . get < Api . Params . RequestParams < { count : number ; } > , AxiosResponse < Api . Response . FetchMessage > > ( "/fetchLatestMessage" , { params : { sessionKey : this . sessionKey , count , } , } ) ; return data ; } param count async peekMessage ( count = 10 ) { const { data } = await this . axios . get < Api . Params . RequestParams < { count : number ; } > , AxiosResponse < Api . Response . FetchMessage > > ( "/peekMessage" , { params : { sessionKey : this . sessionKey , count , } , } ) ; return data ; } param count async peekLatestMessage ( count = 10 ) { const { data } = await this . axios . get < Api . Params . RequestParams < { count : number ; } > , AxiosResponse < Api . Response . FetchMessage > > ( "/peekLatestMessage" , { params : { sessionKey : this . sessionKey , count , } , } ) ; return data ; } param id async messageFromId ( id ) { const { data } = await this . axios . get < Api . Params . RequestParams < { id : number ; } > , AxiosResponse < Api . Response . MessageFromId > > ( "/messageFromId" , { params : { sessionKey : this . sessionKey , id , } , } ) ; if ( data . code === 0 ) { return data . data ; } else { return data ; } } param messageChain param target param quote returns async sendFriendMessage ( messageChain , target , quote ? ) { messageChain = toMessageChain ( messageChain ) ; const payload = { sessionKey : this . sessionKey , target , messageChain , } ; if ( quote ) { payload . quote = quote ; } const { data } = await this . axios . post < Api . Params . SendFriendMessage , AxiosResponse < Api . Response . SendMessage > > ( "/sendFriendMessage" , payload ) ; return data ; } param messageChain param target param quote return { code async sendGroupMessage ( messageChain , target , quote ? ) { messageChain = toMessageChain ( messageChain ) ; const payload = { sessionKey : this . sessionKey , target , messageChain , } ; if ( quote ) { payload . quote = quote ; } const { data } = await this . axios . post < Api . Params . SendGroupMessage , AxiosResponse < Api . Response . SendMessage > > ( "/sendGroupMessage" , payload ) ; return data ; } param messageChain param qq param group param quote async sendTempMessage ( messageChain , qq , group , quote ? ) { messageChain = toMessageChain ( messageChain ) ; const payload = { sessionKey : this . sessionKey , qq , group , messageChain , } ; if ( quote ) { payload . quote = quote ; } const { data } = await this . axios . post < Api . Params . SendTempMessage , AxiosResponse < Api . Response . SendMessage > > ( "/sendTempMessage" , payload ) ; return data ; } param urls param target param qq param group async sendImageMessage ( urls , target ? , qq ? , group ? ) { const { data } = await this . axios . post < Api . Params . SendImageMessage , AxiosResponse < string [ ] > > ( "/sendImageMessage" , { sessionKey : this . sessionKey , target , qq , group , urls , } ) ; return data ; } param type param img async uploadImage ( type , img ) { const form = new FormData ( ) ; form . append ( "sessionKey" , this . sessionKey ) ; form . append ( "type" , type ) ; form . append ( "img" , img ) ; const { data } = await this . axios . post < FormData , AxiosResponse < Api . Response . UploadImage > > ( "/uploadImage" , form , { headers : form . getHeaders ( ) , } ) ; return data ; } param type param voice async uploadVoice ( type , voice ) { const form = new FormData ( ) ; form . append ( "sessionKey" , this . sessionKey ) ; form . append ( "type" , type ) ; form . append ( "voice" , voice ) ; const { data } = await this . axios . post < FormData , AxiosResponse < Api . Response . UploadVoice > > ( "/uploadVoice" , form , { headers : form . getHeaders ( ) , } ) ; return data ; } param type param target param path param file async uploadFileAndSend ( type , target , path , file ) { const form = new FormData ( ) ; form . append ( "sessionKey" , this . sessionKey ) ; form . append ( "type" , type ) ; form . append ( "target" , target ) ; form . append ( "path" , path ) ; form . append ( "file" , file ) ; const { data } = await this . axios . post ( "/uploadFileAndSend" , form , { headers : form . getHeaders ( ) , } ) ; return data ; } param target async recall ( target ) { let messageId = target ; if ( typeof target !== "number" && target . messageChain [ 0 ] . id ) { messageId = target . messageChain [ 0 ] . id ; } const { data } = await this . axios . post < Api . Params . Recall , AxiosResponse < Api . Response . BaseResponse > > ( "/recall" , { sessionKey : this . sessionKey , target : messageId , } ) ; return data ; } /**
     * 获取 bot 的好友列表
     */ async friendList ( ) { const { data } = await this . axios . get < Api . Params . BaseRequestParams , AxiosResponse < Api . Response . FriendList > > ( "/friendList" , { params : { sessionKey : this . sessionKey , } , } ) ; return data ; } /**
     * 获取 bot 的群列表
     */ async groupList ( ) { const { data } = await this . axios . get < Api . Params . BaseRequestParams , AxiosResponse < Api . Response . GroupList > > ( "/groupList" , { params : { sessionKey : this . sessionKey , } , } ) ; return data ; } param target async memberList ( target ) { const { data } = await this . axios . get < Api . Params . RequestParams < { target : number ; } > , AxiosResponse < Api . Response . MemberList > > ( "/memberList" , { params : { sessionKey : this . sessionKey , target , } , } ) ; return data ; } returns async botProfile ( ) { const { data } = await this . axios . get ( "/botProfile" ) ; return data ; } returns async friendProfile ( ) { const { data } = await this . axios . get ( "/friendProfile" ) ; return data ; } returns async memberProfile ( ) { const { data } = await this . axios . get ( "/memberProfile" ) ; return data ; } param target async muteAll ( target ) { const { data } = await this . axios . post < Api . Params . MuteAll , AxiosResponse < Api . Response . BaseResponse > > ( "/muteAll" , { sessionKey : this . sessionKey , target , } ) ; return data ; } param target async unmuteAll ( target ) { const { data } = await this . axios . post < Api . Params . UnmuteAll , AxiosResponse < Api . Response . BaseResponse > > ( "/unmuteAll" , { sessionKey : this . sessionKey , target , } ) ; return data ; } param target param memberId param time async mute ( target , memberId , time = 60 ) { const { data } = await this . axios . post < Api . Params . Mute , AxiosResponse < Api . Response . BaseResponse > > ( "/mute" , { sessionKey : this . sessionKey , target , memberId , time , } ) ; return data ; } param target param memberId async unmute ( target , memberId ) { const { data } = await this . axios . post < Api . Params . Unmute , AxiosResponse < Api . Response . BaseResponse > > ( "/unmute" , { sessionKey : this . sessionKey , target , memberId , } ) ; return data ; } param target param memberId param msg async kick ( target , memberId , msg = "您已被移出群聊" ) { const { data } = await this . axios . post < Api . Params . Kick , AxiosResponse < Api . Response . BaseResponse > > ( "/kick" , { sessionKey : this . sessionKey , target , memberId , msg , } ) ; return data ; } param target async quit ( target ) { const { data } = await this . axios . post < Api . Params . Quit , AxiosResponse < Api . Response . BaseResponse > > ( "/quit" , { sessionKey : this . sessionKey , target , } ) ; return data ; } param target param config async groupConfig ( target , config ? ) { if ( config ) { const { data } = await this . axios . post < Api . Params . GroupConfig , AxiosResponse < Api . Response . BaseResponse > > ( "/groupConfig" , { sessionKey : this . sessionKey , target , config , } ) ; return data ; } else { const { data } = await this . axios . get < Api . Params . GroupConfig , AxiosResponse < Config . GroupConfig > > ( "/groupConfig" , { params : { sessionKey : this . sessionKey , target , } , } ) ; return data ; } } param target param memberId param info async memberInfo ( target , memberId , info ? ) { if ( info ) { const { data } = await this . axios . post < Api . Params . MemberInfo , AxiosResponse < Api . Response . BaseResponse > > ( "/memberInfo" , { sessionKey : this . sessionKey , target , memberId , info , } ) ; return data ; } else { const { data } = await this . axios . get < Api . Params . MemberInfo , AxiosResponse < Config . MemberInfo > > ( "/memberInfo" , { params : { sessionKey : this . sessionKey , target , memberId , } , } ) ; return data ; } } param type private _buildWsChannel < T extends "message" | "event" | "all" > ( type , callback ) { const typeName = { message : "消息" , event : "事件" , all : "消息与事件" , } ; this . logger . info ( `[websocket] [${ type }](${ typeName [ type ] }) ${ this . ws . address }` ) ; const wsParams = new URLSearchParams ( ) ; wsParams . append ( "verifyKey" , this . setting . verifyKey ) ; wsParams . append ( "qq" , this . qq . toString ( ) ) ; const client = new WebSocket ( `${ this . ws . address }/${ type }?${ wsParams . toString ( ) }` ) ; this . ws . client = client ; client . on ( "open" , ( ) => { const interval = setInterval ( ( ) => client . ping ( ) , this . mirai . options . ws ?. heartbeatInterval || 60000 ) ; client . on ( "close" , ( ) => clearInterval ( interval ) ) ; } ) ; client . once ( "message" , ( data ) => { const response = JSON . parse ( data . toString ( ) ) ; if ( response . data . session ) { this . ws . sessionKey = response . data . session ; this . logger . info ( `[ws] Session: ${ this . ws . sessionKey }` ) ; } else { this . logger . error ( response ) ; } } ) ; client . on ( "message" , ( data ) => { const msg = JSON . parse ( data . toString ( ) ) ; callback ( msg . data ) ; } ) ; } param callback message ( callback ) { this . _buildWsChannel ( "message" , callback ) ; } param callback event ( callback ) { this . _buildWsChannel ( "event" , callback ) ; } param callback all ( callback ) { this . _buildWsChannel ( "all" , callback ) ; } /**
     * 获取 Mangers
     */ async managers ( ) { const { data } = await this . axios . get < null , AxiosResponse < number [ ] > > ( "/managers" , { params : { qq : this . qq , } , } ) ; return data ; } param target async setEssence ( target ) { const { data } = await this . axios . post < Api . Params . SetEssence , AxiosResponse < Api . Response . BaseResponse > > ( "/setEssence" , { sessionKey : this . sessionKey , target , } ) ; return data ; } param target param subject param kind async sendNudge ( target , subject , kind = "Group" ) { const { data } = await this . axios . post < Api . Params . SendNudge , AxiosResponse < Api . Response . BaseResponse > > ( "/sendNudge" , { sessionKey : this . sessionKey , target , subject , kind , } ) ; return data ; } }