QQ机器人Markdown使用心得(教程)

MD 权限的申请

基本权限

在 QQ 机器人的开发-高阶能力菜单中可以申请 MD 基本权限,申请后会获得4个模板额度,可以添加 MD 模板或按钮模板

进阶权限

在月平均 DAU 达到门槛后可以填写机器人激励-报名表获得更多权限, 详见机器人激励体系

银牌机器人:DAU400-2000

  • 获得被动 ARK 权限
  • 可添加模板提升至 10 个
  • 获得按钮模板权限

金牌机器人:DAU2000-10000DAU

  • 获得被动 MD 权限
  • 可添加模板提升至 20 个
  • 获得每周两次紧急提审机会

钻石机器人:DAU10000+

  • 获得原生 MD 和自定义按钮权限
  • 建立机器人专属服务群

QQ 频道严格遵守以上权限,QQ 群可以直接发送被动 MD 和自定义按钮

特殊权限

有些权限可通过其他渠道申请,方法如下

回调按钮权限:发送邮件申请

订阅消息权限:联系官方人员申请

没有回调按钮权限也可以发送回调按钮并接收到回调信息,但无法确认,具体表现为用户点击按钮显示访问远程服务超时

MD 的使用

本部分默认观看者有一定的 QQ 官方机器人使用基础并且掌握了基本的 Markdown 语法

申请 MD 模板

申请基础 MD 权限通过后,可以在 QQ 机器人的开发-高阶能力菜单申请 MD 模板

  • MD 模板最多包含 10 个插值,用以在发送时动态提交
  • 插值内不允许使用 MD 语法和\n 换行符
  • MD 模板的实际使用不需要和填写的内容一致,可以申请比较通用的 MD 模板用于多个场景

    插值的 MD 语法检测只针对单个插值

MD 语法支持情况

  • 桌面端 QQNT 支持所有 MD 语法,包括 HTML 标签
  • 安卓只支持列表/图片/链接/文字加粗斜体/引用等基础语法,新版本支持代码块
  • IOS 在安卓的基础上全版本支持代码块,同时在某些语法的表现上与安卓不同,例如安卓可以展示超链接文本,图片可以使用![img#0 #0]进行自动缩放,但 IOS 不行

发送 MD

示例 1: 使用 MD 模板发送消息

image
image

import {} from "@satorijs/adapter-qq";
import { Context } from "koishi";

export async function apply(ctx: Context) {
  ctx.command("test").action(async ({ session }) => {
    await session.qq.sendMessage(session.channelId, {
      msg_type: 2,
      msg_id: session.messageId,
      markdown: {
        custom_template_id: "102076388_1707387724",
        params: [
          {
            key: "t1",
            values: ["你好"],
          },
          {
            key: "t2",
            values: ["芝士Kooshi"],
          },
        ],
      },
    });
  });
}

示例 2: 发送图片

image

MD 的图片会在第一次被用户加载时从图片链接下载并保存,如果同时在看群的用户较多,在缓存完成之前就会有多次访问
官方 server-temp 会在第一次访问后删除图片造成同时看群的其他用户加载不出图片,需要重新点开群才能正常加载,所以建议使用支持多次访问的第三方 server-temp 或其它图床服务

import {} from "@satorijs/adapter-qq";
import { Context } from "koishi";
import {} from "@satorijs/server-temp";
import { readFile } from "fs/promises";

export async function apply(ctx: Context) {
  ctx.command("test").action(async ({ session }) => {
    const image: Buffer = await readFile("test.png");
    const width = 100;
    const height = 100;

    const { url } = await ctx.get("server.temp").create(image);

    await session.qq.sendMessage(session.channelId, {
      msg_type: 2,
      msg_id: session.messageId,
      markdown: {
        custom_template_id: "102076388_1707387221",
        params: [
          {
            key: "info",
            values: [`![img#${width} #${height}]`],
          },
          {
            key: "url",
            values: [`(${url})`],
          },
        ],
      },
    });
  });
}

示例 3: 发送消息按钮

详细参数见官方文档

import {} from "@satorijs/adapter-qq";
import { Context } from "koishi";

export async function apply(ctx: Context) {
  ctx.command("test").action(async ({ session }) => {
    await session.qq.sendMessage(session.channelId, {
      msg_type: 2,
      msg_id: session.messageId,
      markdown: {
        custom_template_id: "102076388_1707387724",
        params: [
          {
            key: "t1",
            values: ["你好"],
          },
          {
            key: "t2",
            values: ["芝士Kooshi"],
          },
        ],
      },
      keyboard: {
        content: {
          rows: [
            {
              // 第一行
              buttons: [
                {
                  // 第一行的第一个按钮
                  render_data: { label: "这是指令" }, // 按钮名称
                  action: {
                    type: 2, // 指令按钮
                    permission: { type: 2 }, // 所有人可点击
                    data: `/你好`, // 点击后会发送 @机器人 /你好
                    enter: true, // 点击直接发送, 若 false 则填入输入框
                  },
                },
                {
                  // 第一行的第二个按钮
                  render_data: { label: "这是链接" },
                  action: {
                    type: 0, // 链接按钮
                    permission: { type: 1 }, // 群管理员可点击
                    data: "http://foo.bar", // 跳转到这个链接
                  },
                },
              ],
            },
            {
              // 第二行
              buttons: [
                {
                  // 第二行的第一个按钮
                  id: "VERIFICATION_FORUM", // 回调事件接收到的 ID
                  render_data: { label: "这是回调" },
                  action: {
                    type: 1,
                    permission: {
                      type: 0, // 指定的用户可点击
                      specify_user_ids: [session.userId], // 用户
                    },
                    data: `${Date.now()}`, // 回调事件接收到的 data
                  },
                },
              ],
            },
          ],
        },
      },
    });
  });
}
7 个赞

欢迎 22 :tada:

4 个赞

欢迎 22 :tada:

3 个赞

欢迎 22 :tada:

3 个赞

欢迎 22 :tada:

4 个赞

欢迎 22 :tada:

3 个赞

谢谢楼主分享的教程!真的很有帮助,特别感谢!

2 个赞