MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接
    1. 主页
    2. Dituon
    3. 帖子
    • 资料
    • 关注 0
    • 粉丝 7
    • 主题 12
    • 帖子 289
    • 最佳 50
    • 有争议的 0
    • 群组 1

    Dituon 发布的帖子

    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      还有一个好点子 线上银趴功能 类似b站的放映厅,大家一起看同一集动画

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      @Him188 不会咳特灵,告辞.jpg

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      盗版网站的视频一般是m3u8流格式,本质是一堆视频切片,插入中间广告的原理是在切片索引中加上广告切片,可以根据路径等因素轻松判断移除。

      至于码率问题,确实没法解决,但p2p也有码率高速度慢的缺点 多一种选择感觉更好一些。

      附之前逆向的某盗版网站解密算法 https://github.com/Dituon/yhmgo-parser

      ಠ⁠∀⁠ಠ

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      刚刚体验了一下 用磁力的话对古早小众动画太不友好了..

      f22a6668d519d45e83b200dd8cd16e04.jpg

      不考虑用盗版网站的服务器吗 (^▽^)

      编辑:
      热门番剧速度也好慢,种子的高码率和低速度貌似很难满足流媒体的观看需要

      7e710dc2-e5cd-43df-a0ed-01e034cc968e-b6125756afd4c975e1e355a17dc9c34e.jpg

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      @Him188 p2p具体是什么协议呢 可以用WebRTC解决吗

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 打个小广告, 不要 ban 我 >_< 一站式弹幕追番平台

      这是极好的,如果有网页版就更好了

      发布在 摸鱼区
      Dituon
      Dituon
    • RE: 年度总结插件开发计划

      感谢大家的催更支持,插件正在开发

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @han1549302096 改用json请求可以正常发送吗,这个formdata腾讯说是只用来发图片的,没试过发文本。

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @han1549302096 完整的请求内容是什么呢

      发布在 开发交流
      Dituon
      Dituon
    • Pixiv 免代理 API

      半年前写的,使用某些技术绕开防火墙封锁直连Pixiv,在这里水一下。

      https://github.com/Dituon/pixiv-api-http

      发布在 其他项目发布
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @han1549302096 content字段是什么呢

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @han1549302096 删除Content-Type,由fetch函数自动添加。
      https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @Mr-喜 ws接口只能通过url发送,http formdata接口可以直接发送二进制数据。

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @Mr-喜 不,私域可以监听所有消息,但群bot目前只能公域

      发布在 开发交流
      Dituon
      Dituon
    • RE: 腾讯官方Bot接口扫盲

      @frankcwl 多谢提醒,已更新

      发布在 开发交流
      Dituon
      Dituon
    • 腾讯官方Bot接口扫盲

      最后更新日期 2025/5/10 请关注最新回复

      注意

      由于楼主文化造纸不高,文中掺杂了很多废话,只阅读粗体字即可了解全部信息,细体字为背景信息补充。

      前言

      众所周知,腾讯几年前为了对标discord和一众竞品推出了秋秋频道,为了对标其它平台的Bot生态开放了仅限频道的官方接口,在开发频道Bot接口时顺便开发了群聊接口,不过仅限内部使用。

      不久之后,腾讯官方的群聊Bot陆续上线,例如群聊管家,农药战绩Bot等;这些用新接口的Bot与腾讯之前与微软合作的QQ小冰,BabyQ等烂尾项目最大的区别是带有权限管理系统,例如群主可以指定Bot权限等。这是因为腾讯把内部接口开放给了缴纳保护费的公司开发对应游戏的战绩查询Bot。

      经过漫长的便秘开发周期,腾讯终于在去年 (2023) 9月宣布对个人开发者开放群聊接口,代价是需要参加腾讯组织的比赛。

      最近腾讯宣布比赛马上结束,现有的接口也基本稳定下来,所以就有了这篇文章。

      资质 & 注册

      注册成为个人开发者,只需要绑定个人身份信息的QQ账户即可;因为几年前的相关部门规定,反而很难找到没有绑定个人信息的账号。

      注册网站: q.qq.com

      注册后即可创建Bot,默认创建的Bot只有频道接口的开发权限,群聊权限会在近期开放申请,请期待本贴更新。

      审核

      接下来是大部分人关心的审核问题,Bot默认只能在测试频道/群聊中使用,添加到其它频道需要通过审核。

      下面的内容包含大量黑框框 你知道的太多了

      审核流程

      1. 平台上上传Bot头像, 指令等基本信息。

      2. 填写excel表格,包含bot的功能、用途、测试用例等信息

        表格预览(可能近期失效,下方有截图)

        e92f20ce-1ffc-4439-80a3-601457c853f8-image.png

      3. 等待过审 (三天到一周时间,周末放假)

      4. 更改Bot使用范围为公域 (下文附有腾讯黑话&专有名词解释)

      5. 等待过审 (两天到一周时间,周末放假)

      (令人迷惑的是为什么腾讯一定要审核两遍,咱也不敢问)

      审核时审核员会根据表格里的指令进行测试
      也不一定按照表格里的指令测试,笔者就遇到过审核员没有按照表格内对应的格式回复导致审核不通过再等一周
      还会假设bot有AI机能尝试聊天

      审核尺度

      建议: 送审时尽可能阉割以免不通过再等一周,过审后可以随意编辑

      文本

      腾讯对文本审核尺度把握非常迷惑严格,列举几个一般人觉得没问题但腾讯不允许出现的词汇:

      上瘾,生病,胸,腿(等身体部位),美国(或任何国家),迪士尼系列的所有名词(米奇,某只黄色的熊等)(任天堂没试过),警察,药

      上面的词汇仅限中文,用英文可以过审

      能否过审主要取决于审核的心情,每个审核的G点不一样

      图片

      想象一下你的祖母会如何评价Bot发送的图片,这就是腾讯的图片审核标准没有标准

      封号

      过审并不是腾讯拷打你的终点,而是起点,以下列举几个可能导致封号的行为

      1. 复读用户发过的消息或发送用户的ID。

      2. 复读用户的表情包/图片或处理后发送用户的头像。

      3. 在某些日子发送或回复某些词汇,强烈建议了解以避免踩雷。坦克,蛋炒饭等

      4. 被举报包含AI回复的功能,AI必须有对应资质。

      接口 & SDK

      接口架构

      目前接口有两个大版本,旧版本只能发送频道,新版本群聊和频道皆可

      websocket 用于事件通知与简单消息发送

      也有http消息发送接口,例如使用formdata发送图片等

      官方SDK

      重要建议:不要使用腾讯官方 Go Node SDK!

      重要建议:不要使用腾讯官方 Go Node SDK!

      重要建议:不要使用腾讯官方 Go Node SDK!

      有Python, Go, Node版本;不建议使用 Go Node,理由如下:

      1. 使用旧版接口

      2. 缺少类型 (TS类型全是any之类的)

      3. 太长时间没更新 (截止到本文撰写,Go与Node SDK上次更新时间是2020年)

      笔者没用过 Python SDK,所以持中立态度。

      野生SDK

      有很多,但笔者一个都没用过,体验过的欢迎评论点评,本贴也会积极更新。

      Markdown & 按钮

      大家朝思暮想的md腾讯也有提供,不过目前限制极大(下详)

      腾讯把Markdown分为三种

      专有名词 门槛 功能 审核/限制
      主动 无 根据预先审核过的模板填充变量发送 每月只能发送4条, 模板需要通过审核(每月中旬集中审核)
      被动 每日用户 >= 2000 根据预先审核过的模板填充变量发送 回复用户的指令, 模板需要通过审核(每月中旬集中审核)
      原生 每日用户 >= 10000 可直接发送md格式的消息 无

      限制

      此外,腾讯还制定了一系列匪夷所思的规则,笔者挑选了几个具有代表性的罄竹难书

      1. URL域名必须备案且经过认证(认证方式是在域名的某个路径放置一个文件)

      2. 服务器必须有公网IP(最近突然发公告说Bot必须绑定IP,被骂的挺惨的,腾讯说会考虑取消这个限制 只是套话 应该不会改)

      3. 不能获取用户信息(无法获取用户QQ号,昵称,头像等,取而代之的是一长串openid,即使是同一用户在不同群也会有不同的ID,腾讯半年前说会更新)

      黑话解释

      列举一下文档里经常出现的黑话,欢迎补充

      黑话 解释 备注
      DAU 每日使用过bot的用户数量
      主动消息 Bot主动推送的消息 每月只能发送4条,群主/管理员可关闭
      被动消息 Bot回复用户的消息 相比主动消息没有发送数量限制 但是会随机吞消息
      私域 相对较小的使用场景 女生自用 有加群数量限制,相对限制较少,能监听的事件更多
      公域 相对较大的使用场景 公交车 只能监听at相关的事件(目前群bot只能选这个 可能是接口没做好)
      全量 相对于白名单的概念,谁都可以用 bot默认是白名单,切换时要审核

      后话

      之前对第三方bot疯狂打压,在笔者看来只是为了给官方接口铺路,但腾讯做了五年还是这样实在令人失望。

      以上,想到再补充,本文随意转载,CC-BY-NC-SA 4.0

      前情提要: https://mirai.mamoe.net/topic/2526/qq群bot官方接口-与使用体验

      发布在 开发交流
      Dituon
      Dituon
    • RE: 如何用用户账户在频道发原生markdown

      @starryeye-0001 做不到,应用卡片消息需要腾讯签名,不然发出来就封号,建议用图片绘制md

      发布在 开发交流
      Dituon
      Dituon
    • RE: 如何用用户账户在频道发原生markdown

      @starryeye-0001 官方权限是主动消息,一个月只能发四条

      发布在 开发交流
      Dituon
      Dituon
    • RE: 如何用用户账户在频道发原生markdown

      @starryeye-0001 群聊markdown需要向腾讯申请,要求是每天用户量>10000

      发布在 开发交流
      Dituon
      Dituon
    • RE: 樱&花动漫接口逆向

      更新: 爬虫示例代码

      export const config = {
          fetchHeader: {
              "Sec-Ch-Ua": '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',
              "Dnt": '1',
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
          }
      }
      
      export interface VideoInfo {
          url: string
          // type: string
      }
      
      export abstract class Parser {
          public abstract parse(raw: string): Promise<VideoInfo>
      }
      
      import fetch from 'node-fetch'
      import * as cookie from 'cookie'
      
      const exp = /www\.yhmgo\.com\/vp\/(\d+)-(\d+)-(\d+)/
      const API_BASE = 'https://www.yhmgo.com/playurl'
      const PAGE_BASE = 'https://www.yhmgo.com/vp'
      
      export class YhmgoParser extends Parser {
          async parse(url: string): Promise<VideoInfo> {
              const [match, id, channel, ep] = url.match(exp)
              if (!match) {
                  throw new Error('Invalid url')
              }
              const pageUrl = `${PAGE_BASE}/${id}-${channel}-${ep}.html`
              const page = await fetch(pageUrl)
      
              let {t1, k1} = page.headers.raw()['set-cookie'].reduce((obj, str) => {
                  return {...cookie.parse(str), ...obj}
              }, {})
              let cookies = parseCookie(t1, k1)
      
              const raw = await fetch(
                  `${API_BASE}?aid=${id}&playindex=${channel}&epindex=${ep}&r=${Math.random()}`,
                  {
                      headers: {
                          ...config.fetchHeader,
                          referer: pageUrl,
                          cookie: Object.entries(cookies)
                              .map(c => cookie.serialize(c[0], c[1]))
                              .join('; ')
                      }
                  }
              )
              const {vurl} = parseResult(await raw.text())
      
      
              return {
                  url: decodeURIComponent(vurl),
                  // type: 'm3u8',
              }
          }
      }
      
      export function parseCookie(t1: number, k1: number) {
          let pos = Math.floor(t1 / 0x3e8) >> 0x5
          let offset = 0x89a4
          let k2 = '' + (((((pos * (pos % 0x100) + 0x1) + offset) * ((pos % 0x80) + 0x1)) * ((pos % 0x10) + 0x1)) + pos)
      
          let t2 = ''
          while (true) {
              t2 = '' + Math.floor(new Date().getTime())
              let tOffset = t2.slice(t2.length - 0x3)
              let kOffset = k2.slice(k2.length - 0x1)
              if (tOffset.indexOf(kOffset) >= 0x0) {
                  break
              }
          }
      
          let start = 0x0
          let timeOffset = Math.floor(new Date().getTime() / 0x3e8) >> (0x11 + start)
          let m2t = ((((timeOffset * 0x15 + 0x9a) * (((timeOffset % 0x40) + 0xd)) * ((timeOffset % 0x20) + 0x22) * ((timeOffset % 0x10) + 0x57)) * ((timeOffset % 0x8) + 0x41)) + 0x2ef)
      
          return {
              t1, k1, t2, k2, m2t
          }
      }
      
      export function parseResult(raw: string): {
          purl: string,
          vurl: string,
          inv: string
      } {
          let result = ''
          const offset = 0x619
          const rawLength = raw.length
          for (let i = 0x0; i < rawLength; i += 0x2) {
              let temp = parseInt(raw[i] + raw[i + 1], 0x10)
              temp = (
                  (temp + 0x100000 - offset) - (((rawLength / 0x2) - 0x1) - (i / 0x2))
              ) % 0x100
              result = String.fromCharCode(temp) + result
          }
          return JSON.parse(result)
      }
      

      使用

      import {YhmgoParser} from "./parser/yhmgo";
      
      const parser = new YhmgoParser()
      const video = await parser.parse('https://www.yhmgo.com/vp/11141-2-0.html')
      console.log(video)
      
      // 输出: { url: 'https://vip.lz-cdn16.com/20230317/13224_75d9217b/index.m3u8' }
      
      发布在 开发交流
      Dituon
      Dituon
    • 1
    • 2
    • 3
    • 4
    • 5
    • 14
    • 15
    • 3 / 15