GithubHelp home page GithubHelp logo

yunyoujun / mirai-ts Goto Github PK

View Code? Open in Web Editor NEW
245.0 3.0 36.0 787 KB

🔧 Mirai(QQ Bot) JavaScript/TypeScript SDK for Node.js/Browser

Home Page: https://yunyoujun.github.io/mirai-ts/

License: GNU Affero General Public License v3.0

TypeScript 99.87% Shell 0.06% JavaScript 0.07%
mirai nodejs typescript sdk javascript qq bot

mirai-ts's Introduction

docs Compatible Version npm GitHub Codacy Badge

mirai-api-http 的 JavaScript/TypeScript SDK,附带声明文件,拥有良好的注释和类型提示。可运行于 Node.js 与浏览器端。

shindo-ai.gif

除了 Node.js,它还兼容浏览器端。这意味着你可以使用它来开发 Web 界面与你的 mirai 机器人进行交互。(可以参考还在咕的 el-bot-web

如何使用

自行配置好你的 miraimirai-api-http,确保 localhost:你配置的端口号/about 是可访问的。 settings.ymladapterSettingshttpws 是必须的。

npm install mirai-ts
# yarn add mirai-ts

# 尝试新版本(比如 ES Module)
npm i mirai-ts@next

由于 mirai-api-http 2.x 已经稳定,mirai-ts@latest 为 2.x 版本,如果您想使用 mirai-api-http 1.x,请安装 [email protected] 版本。

快速开始

JavaScript

示例代码

node demo/index.js

TypeScript

示例代码

ts-node demo/index.ts

Browser

基于 mirai-ts 开发面向浏览器端的应用程序时,您还需要安装 events 以在浏览器端替代 Node.js 原生 events 模块。

pnpm i events
# yarn add events
# npm install events mirai-ts

Why Typescript & mirai-ts?

Make JavaScript Great Again!

  • 更友好的提示:TypeScript 配合 VSCode 代码提示有奇效。
  • 更清晰的语义:函数命名与 mirai-api-http 保持一致。
  • 更易懂的注释:因为会用到 QQ 机器人 99.99% 是国人,所以是全中文注释。
  • 更优雅的结构:看起来是在自吹自擂,但自我感觉良好。
  • 更广泛的平台:支持 Node.js 与浏览器端,以及 WebSocket。

简介

结构

types 目录下为对应类型定义

  • api: API 发送与响应
    • response: API 响应格式
  • contact: 用户信息格式(如 Friend, Member, Group 等)
  • event-type: 事件类型
  • message-type: 消息类型

工具类

const { Message, Logger, check, MessageType, EventType } = require('mirai-ts')
import { EventType, Logger, Message, MessageType, check } from 'mirai-ts'

详情请参见 API 文档

  • Message: 生成对应消息的辅助方法,如生成艾特某人的消息 Message.At(qq)

消息链应当是一个数组,如 messageChain = [Message.At(qq), Message.Plain('来点色图')]

简单的日志工具,当然你可以自由使用其他工具替代它。

import { Logger } from 'mirai-ts'
// 你可以自定义你的前缀
const logger = new Logger({ prefix: '[mirai-ts]' })
logger.success('We are free!')

消息匹配与检测。

如判断消息链是否有艾特某人:

const { check } = require('mirai-ts')
// msg 为消息链 MessageChain
// qq 为 QQ 号
check.isAt(msg, qq)

// or just
msg.isAt(qq)
// 留空则判断是否艾特机器人自身

示例模版

  • el-bot:你可以参考它的使用方式,你也可以直接使用它。

el-bot 展示了整个 mirai-ts 的使用流程,并内置了一些如自动应答、转发、命令行、RSS 等常用功能(默认插件),开箱即用。

你只需要一些自定义的配置,而不再需要编写繁琐的脚本内容。

但这并不是束缚,在插件系统中你仍然可以调用机器人所有的上下文,并通过编写插件的形式快速实现你想要的功能。

更多请参见文档 el-bot | El Bot Docs

开发

# clone 本项目
git clone https://github.com/YunYouJun/mirai-ts
cd mirai-ts

# 安装 mirai-console-loader,放置于 `mirai-ts/mcl` 文件夹下
# https://github.com/iTXTech/mirai-console-loader
mkdir mcl
cd mcl
# 修改链接下载 mcl 对应版本
wget https://github.com/iTXTech/mirai-console-loader/releases/download/v2.1.1/mcl-2.1.1.zip
unzip mcl-2.1.1.zip
chmod +x mcl
./mcl

# 使用 mcl 安装 mirai-api-http
# https://github.com/project-mirai/mirai-api-http#%E5%AE%89%E8%A3%85mirai-api-http
./mcl --update-package net.mamoe:mirai-api-http --channel stable-v2 --type plugin
# mcl 自动更新
./mcl -u

cd ..
pnpm mcl

# 参考 https://github.com/project-mirai/mirai-login-solver-selenium 获取 ticket

# 开发(监听文件变动并构建)(打开新终端窗口)
pnpm dev

# 启动 demo(打开新终端窗口)
pnpm demo

mirai-ts's People

Contributors

cl-jeremy avatar darcjc avatar drincann avatar frederick-wang avatar geraltx avatar heatonz avatar moheng233 avatar nfwsa avatar rabbitkiller-dev avatar samarium150 avatar u-u-z avatar yoshino-s avatar yunyoujun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mirai-ts's Issues

ts-node 报错

node_modules/mirai-ts/dist/index.js:5
import Mirai from "./mirai";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at wrapSafe (node:internal/modules/cjs/loader:1024:16)
    at Module._compile (node:internal/modules/cjs/loader:1072:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
    at Module.load (node:internal/modules/cjs/loader:973:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Module.require (node:internal/modules/cjs/loader:997:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at Object.<anonymous> (/home/lighthouse/mirai/bot/src/index.ts:1:1)
    at Module._compile (node:internal/modules/cjs/loader:1108:14)
    at Module.m._compile (/home/lighthouse/mirai/bot/node_modules/ts-node/src/index.ts:1056:23)
[nodemon] app crashed - waiting for file changes before starting...

MessageChain 无法正确发送

· app 的函数如下:

async function app() {
  await mirai.link(qq);
  mirai.on("message", async (msg: MessageType.ChatMessage) => {
    console.log(msg);
    msg.reply([Message.Plain("aaa"), Message.Plain("bbbbb")]);
  });
  mirai.listen();
}

输出如下:

{
  type: 'FriendMessage',
  messageChain: [
    { type: 'Source', id: 24271, time: 1611411354 },
    { type: 'Plain', text: 's' }
  ],
  sender: { id: 1817408881, nickname: '抱歉圣光', remark: '' },
  bubbles: true,
  stopPropagation: [Function (anonymous)],
  plain: 's',
  reply: [Function (anonymous)]
}

mirai-http-api的输出如下:

2021-01-23 22:15:53 V/Bot.2366491342: Event: FriendInputStatusChangedEvent(friend=Friend(QQNUMBER), inputting=true)
2021-01-23 22:15:54 V/Bot.2366491342: Event: FriendInputStatusChangedEvent(friend=Friend(QQNUMBER), inputting=false)
2021-01-23 22:15:54 V/Bot.2366491342: NAME(QQNUMBER) -> [mirai:source:[24271],[8406717921],[840671792]]s
2021-01-23 22:15:54 V/Bot.2366491342: Friend(QQNUMBER) <- aaabbbbb

但是QQ没有返回

如果把

msg.reply([Message.Plain("aaa"), Message.Plain("bbbbb")]);

改为

msg.reply([Message.Plain("aaabbbbb")])

则可以在其他输出都相同的情况下QQ正常发送消息

前天的修改之后又找不到 export 了

刚刚更新“生产环境”的机器人,才发现 2ce9e92 的修改是不是在使用的时候需要改动 import 的语法? import Mirai from 'mirai-ts'; 会报错,现在只有 require('mirai-ts') 可用……

请问使用 MAH 2.10.0 时 ws 报错

Describe the bug

不知佬目前是否还维护着这个项目,试着提个 issue 吧..
MAH 近期发布的 2.10.0 适配了 mirai core 2.16.0 的一些新功能,比如终于支持了短视频发送。有需求所以将 MAH 升级到了 2.10.0,结果与 mirai-ts 对接时 ws 报错。

MobaXterm_MDiZHph0QE

不确定是不是 mirai-ts 这边的问题,请佬看一下.... 🙏🏾

Reproduction

使用 MAH 2.10.0

System Info

System:
    OS: Linux 4.11 CentOS Linux 7 (Core)
    CPU: (2) x64 QEMU Virtual CPU version (cpu64-rhel6)
    Memory: 455.55 MB / 1.97 GB
    Container: Yes
    Shell: 4.2.46 - /bin/bash
  Binaries:
    Node: 20.6.1 - ~/.nvm/versions/node/v20.6.1/bin/node
    npm: 10.1.0 - ~/.nvm/versions/node/v20.6.1/bin/npm
    pnpm: 8.7.5 - ~/.nvm/versions/node/v20.6.1/bin/pnpm
    bun: 1.0.0 - ~/.bun/bin/bun
  Browsers:
    Chrome: 116.0.5845.179

Used Package Manager

npm

Validations

  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Check that this is a concrete bug. For Q&A, please open a GitHub Discussion instead.
  • The provided reproduction is a minimal reproducible of the bug.

`utils/check.ts#match` 函数的实现问题

如果直接调用match的话,会导致后面的配置失效。例如 @el-bot/plugin-setu 这个插件,includes 中的内容永远不会被匹配到。

/**
* 是否匹配
* @param str 字符串
* @param ans 回答的语法配置
*/
export function match(
str: string,
ans: Match
): boolean | RegExpMatchArray | null {
if (ans.re) return re(str, ans.re);
if (ans.is) return is(str, ans.is);
if (ans.includes) return includes(str, ans.includes);
return false;
}

改成或的关系会不会更好,如果re存在且匹配成功则返回正则匹配的结果。如下,个人见解,仅供参考。

export function match(
  str: string,
  ans: Match
): boolean | RegExpMatchArray | null {
  if (ans.re) {
    const res = re(str, ans.re);
    if (res) return res;
  }
  if (ans.is && is(str, ans.is))
    return true;
  if (ans.includes && includes(str, ans.includes)) {
    return true;
  }
  return false;
}

src/mirai-api-http/resp.ts 中注释有误

为什么注释写的是1和2,代码写的是0和1??

/**
* - `1` 同意邀请
* - `2` 拒绝邀请
*/
export type BotInvitedJoinGroupRequestOperationType = 0 | 1;

建议把此文件中的几个OperationType类型声明改为enum

export enum BotInvitedJoinGroupRequestOperationType {
    accept = 0,
    refuse = 1,
}

MessageType怎么引用?

import { Mirai, MessageType } from 'mirai-ts'
import type { MiraiApiHttpSetting } from 'mirai-ts'
import { config } from 'src/config'
import { BaseMessageHandler, MessageHandler } from 'src/types'

console.log(MessageType)


貌似取不到GroupMessage
对nodejs不熟悉。。。

发送语音消息

现在 Voice 虽然是 BaseSingleMessage 但不是 SingleMessage,导致无法发送
如果是故意不列出来的话(因为只支持群消息)请至少在 sendGroupMessage 处允许 Voice

V2.0 MiraiApiHttpSetting interface

2.0的MiraiApiHttpSetting整个interface中的参数都为必传参数,ts编译无法通过,是否可以加入默认配置,并使用?标识attr不为必传参数

读取mirai-api-http配置时报错

尝试使用js-yaml读取以下配置时报错

adapters: 
  - http
  - ws
debug: false
enableVerify: true
verifyKey: el-psy-congroo
singleMode: false
cacheSize: 4096
adapterSettings:
  http:
      host: localhost
      port: 8080
      cors: [*]
  ws:
      host: localhost
      port: 8080
      reservedSyncId: -1

stacktrace如下

YAMLException: name of an alias node must contain at least one character at line 13, column 15:
          cors: [*]
                  ^
    at generateError (**\node_modules\js-yaml\lib\js-yaml\loader.js:167:10)
    at throwError (**\node_modules\js-yaml\lib\js-yaml\loader.js:173:9)
    at readAlias (**\node_modules\js-yaml\lib\js-yaml\loader.js:1270:5)
    at composeNode (**\node_modules\js-yaml\lib\js-yaml\loader.js:1368:20)
    at readFlowCollection (**\node_modules\js-yaml\lib\js-yaml\loader.js:735:5)
    at composeNode (**\node_modules\js-yaml\lib\js-yaml\loader.js:1360:11)
    at readBlockMapping (**\node_modules\js-yaml\lib\js-yaml\loader.js:1089:11)
    at composeNode (**\node_modules\js-yaml\lib\js-yaml\loader.js:1359:12)
    at readBlockMapping (**\node_modules\js-yaml\lib\js-yaml\loader.js:1089:11)
    at composeNode (**\node_modules\js-yaml\lib\js-yaml\loader.js:1359:12) {
  reason: 'name of an alias node must contain at least one character',
  mark: Mark {
    name: null,
    buffer: 'adapters: \n' +
      '  - http\n' +
      '  - ws\n' +
      'debug: false\n' +
      'enableVerify: true\n' +
      'verifyKey: el-psy-congroo\n' +
      'singleMode: false\n' +
      'cacheSize: 4096\n' +
      'adapterSettings:\n' +
      '  http:\n' +
      '      host: localhost\n' +
      '      port: 8080\n' +
      '      cors: [*]\n' +
      '  ws:\n' +
      '      host: localhost\n' +
      '      port: 8080\n' +
      '      reservedSyncId: -1\n' +
      '\x00',
    position: 197,
    line: 12,
    column: 14
  }
}

我觉得应该js-yaml的问题?直接import手写的json config就能连上mirai-api-http

有没有群组At自己的消息类型呢?

我现在判断是否at机器人自己的消息我是通过messageChain的At来判断的,是否提供了更简洁的方案呢?

{
  type: 'GroupMessage',
  messageChain: [
    { type: 'Source', id: 599, time: 1603352515 },
    { type: 'At', target: 1000009, display: '@测试' }
  ],
  sender: {
    id: 1000003,
    memberName: 'L 、',
    permission: 'OWNER',
    group: { id: 23423424, name: '测试群组', permission: 'MEMBER' }
  },
  plain: '',
  reply: [Function]
}

部分接口的请求未传递参数

async friendProfile(): Promise<UserProfile> {
const { data } = await this.axios.get('/friendProfile')
return data
}
/**
* 此接口获取群成员的消息资料
* @returns
*/
async memberProfile(): Promise<UserProfile> {
const { data } = await this.axios.get('/memberProfile')
return data
}

在mirai-api-http中的接口形式:
https://docs.mirai.mamoe.net/mirai-api-http/api/API.html#%E8%8E%B7%E5%8F%96%E5%A5%BD%E5%8F%8B%E8%B5%84%E6%96%99

[Usage Problem] mirai-api-http 中 /command/send 无法使用 login 命令

实际无法使用以下方式通过 mirai-api-http 在 mirai 中登录账号,故只能在 mirai 控制台处实现。

bot.login(qq, password)

  /**
   * 在 mirai 中登录 QQ
   * @param qq
   * @param password
   */
  async login(qq: number, password: string) {
    const data = await this.mirai.api.command.send("login", [qq, password]);
    return data;
  }

将返回 请在后台使用该指令 的信息。

Why “TypeError: Mirai is not a constructor”?

Hi!

when I use demo code in nodejs,Threw such a mistake:

const mirai = new Mirai(setting);
              ^

TypeError: Mirai is not a constructor
    at Object.<anonymous> (C:\Users\Administrator\Desktop\start\2.js:16:15)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
    at node:internal/main/run_main_module:17:47

Code I use:

const Mirai = require("mirai-ts");
const fs = require("fs");
const path = require("path");
const yaml = require("js-yaml");
// const { Message } = require("mirai-ts");

// 你的 QQ 号
const qq = xxxxxxx;
// 读取你的 `mcl/config/net.mamoe.mirai-api-http/setting.yml` 并解析为 JSON
// 或手动书写对象
const setting = yaml.load(
   fs. readFileSync(
      "C:/Users/Administrator/Downloads/mcl-1.2.2/config/net.mamoe.mirai-api-http/setting.yml")
  );

const mirai = new Mirai(setting);

async function app() {
  // 登录 QQ
  await mirai.link(qq);

  // 对收到的消息进行处理
  // message 本质相当于同时绑定了 FriendMessage GroupMessage TempMessage
  // 你也可以单独对某一类消息进行监听
  // console.log("on message");
  mirai.on("message", (msg) => {
    console.log(msg);
    // 复读
    msg.reply(msg.messageChain);
  });

  // 调用 mirai-ts 封装的 mirai-api-http 发送指令
  console.log("send command help");
  const data = await mirai.api.command.send("/help", []);
  console.log("帮助信息:" + data);

  // 处理各种事件类型
  // 事件订阅说明(名称均与 mirai-api-http 中事件名一致)
  // console.log("on other event");
  // https://github.com/project-mirai/mirai-api-http/blob/master/docs/EventType.md#群消息撤回
  mirai.on("GroupRecallEvent", ({ operator }) => {
    const text = `${operator.memberName} 撤回了一条消息,并拜托你不要再发色图了。`;
    mirai.api.sendGroupMessage(text, operator.group.id);
  });

  // 开始监听
  // mirai.listen()
  // 可传入回调函数对监听的函数进行处理,如:
  mirai.listen((msg) => {
    console.log(msg);
  });
}

app();

I don't know why?

node:16.10.0

mirai-api-http 文档链接指向错误

Hi! 文档应该是迁移了,这里的 EventType.md 地址应该是 https://github.com/project-mirai/mirai-api-http/blob/master/docs/EventType.md 。另外在 el-bot 的文档中也有这个链接

mirai-ts/src/mirai.ts

Lines 192 to 200 in 45819b3

/**
* 绑定事件列表
* message: FriendMessage | GroupMessage | TempMessage
* [mirai-api-http事件类型一览](https://github.com/project-mirai/mirai-api-http/blob/master/EventType.md)
* mirai.on('MemberMuteEvent', ()=>{})
* @param type
* @param callback
*/
on<T extends "message" | EventType.EventType | MessageType.ChatMessageType>(

export more types

It's reasonale for plugins to access all types of data in the api.

import type { Member, Group } from "mirai-ts/dist/types/contact";

// ...

const getGroupName = (group: Group) => `群 ${group.name}(${group.id})`;
const getMemberName = (member: Member) => `${member.memberName}(${member.id})`;

// ...

But these types are no longer available in latest release. Maybe more types should be exported.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.