MiraiForum

    • 注册
    • 登录
    • 搜索
    • 热门
    • 最新
    • 未解决
    • 标签
    • 群组
    • 友情链接

    java如何使用mockbot来做捕获事件测试?

    开发交流
    2
    5
    340
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • hisou
      hisou 最后由 编辑

      一开始是想做一个引用回复的原消息内容的获取,想先本地测试一下避免实操频繁上下线被封号。昨天自己摸索了很久,但是对于单测中如何监听消息并捕获到event中的消息链还是云里雾里的,最下面的订阅事件代码是无效的:

      @Test
          public void test() {
              MockBot mockBot = MockBotFactory.Companion.newMockBotBuilder().create();
              mockBot.addGroup(798100000L, "qqgroup");
      
              Bot bot = mockBot;
              bot.login();
              
              MessageReceipt message = bot.getGroup(798100000L).sendMessage("hello world");
      
              MessageChain messageChain = new MessageChainBuilder().append(message.quote() + " haha").build();
      
              bot.getGroup(798100000L).sendMessage(messageChain);
      
              QuoteReply quoteReply = messageChain.get(QuoteReply.Key);
      
              System.out.println(quoteReply);
      
      // 事件订阅?
      
              bot.getEventChannel().subscribeAlways(GroupMessageEvent.class, (GroupMessageEvent event) -> {
                  System.out.println(event.getMessage().serializeToMiraiCode());
              });
      
              bot.getGroup(798100000L).sendMessage("Hi Hi");
          }
      
      1 条回复 最后回复 回复 引用 0
      • Dituon
        Dituon 最后由 Dituon 编辑

        原消息内容有什么用途呢 ?

        如果只需要获取文本的话,可以 监听消息并取出引用消息实例直接获取文本 (例如: 引用消息的图片或at会转换为 [图片] 和 @xxx 的形式)

        如果需要获取完整的原消息的话,可以考虑 通过消息id进行缓存 ,回复时从缓存取出原消息。

        希望能具体描述一下想要实现的功能,而不是直接放出一段用于测试的代码

        补充: 因为Mirai对于引用消息的处理在这两个获取方式下是有区别的,所以要按情境选择适合的方法进行处理, 建议补充实际使用场景便于解决问题

        hisou 1 条回复 最后回复 回复 引用 0
        • hisou
          hisou @Dituon 最后由 编辑

          如果只需要获取文本的话,可以 监听消息并取出引用消息实例直接获取文本 (例如: 引用消息的图片或at会转换为 [图片] 和 @xxx 的形式)

          昨晚最后试了一下,发现就是这样转换的,不能拿到原消息的miraicode还原图片感觉意义不大了。


          关于想实现的功能,是群成员直接回复任意某条历史消息(可能是图片),带上关键指令(如“保存”),bot识别指令后将原消息的内容进行后台处理。由于群成员回复哪条消息是不可预测的,所以不想把所有历史消息的id都缓存起来。所以考虑使用QuoteReply直接定位

          其实主要问题还是如何用mockbot进行本地消息监听测试,我是在开发这个功能的过程中才知道有模拟bot库的,省去了很多实机测试的麻烦,只是java下的使用没有文档全凭摸索太耗时了,所以来问问

          Dituon 1 条回复 最后回复 回复 引用 0
          • Dituon
            Dituon @hisou 最后由 Dituon 编辑

            @hisou 我实现过这种需求,是用 LinkedHashMap<Long, String> 建立了图片缓存,仅缓存用户发送的图片,并指定缓存容量。

            伪代码

                private LinkedHashMap<Long, String> imageCachePool;
            
            // 插件初始化
                if (service.respondReply) {
                        imageCachePool = new LinkedHashMap<>(service.cachePoolSize, 0.75f, true) {
                            @Override
                            public boolean removeEldestEntry(Map.Entry eldest) {
                                return size() > service.cachePoolSize;
                            }
                        };
                        GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, this::cacheMessageImage);
                        GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessagePostSendEvent.class, this::cacheMessageImage);
                }
            
                private void cacheMessageImage(MessageEvent e) {
                    for (SingleMessage singleMessage : e.getMessage()) {
                        if (singleMessage instanceof Image) {
                            long id = e.getSubject().getId() + e.getMessage().get(MessageSource.Key).getIds()[0];
                            imageCachePool.put(id, Image.queryUrl((Image) singleMessage));
                            return;
                        }
                    }
                }
            
            
            // 主消息处理方法
                for (SingleMessage singleMessage : e.getMessage()) {
                
                            if (singleMessage instanceof QuoteReply && service.respondReply) {
                
                                long id = e.getGroup().getId() + ((QuoteReply) singleMessage).getSource().getIds()[0];
                
                                if (imageCachePool.get(id) == null) continue;
            
                                 //使用缓存的图片链接
                            }
                }
            
            
            hisou 1 条回复 最后回复 回复 引用 0
            • hisou
              hisou @Dituon 最后由 编辑

              @Dituon 看着是petpet的代码,我会去研究的,谢谢

              只是本地测试的方法还是得不到答案

              1 条回复 最后回复 回复 引用 0
              • 1 / 1
              • First post
                Last post
              Powered by Mamoe Technologies & NodeBB | 友情链接 | 服务监控 | Contact