@Override
    public void doAlarm(List<AlarmMessage> alarmMessages) throws Exception {
        Map<String, WeLinkSettings> settingsMap = alarmRulesWatcher.getWeLinkSettings();
        if (settingsMap == null || settingsMap.isEmpty()) {
            return;
        }
        Map<String, List<AlarmMessage>> groupedMessages =  groupMessagesByHook(alarmMessages);
        for (Map.Entry<String, List<AlarmMessage>> entry : groupedMessages.entrySet()) {
            var hookName = entry.getKey();
            var messages = entry.getValue();
            var setting = settingsMap.get(hookName);
            if (setting == null || CollectionUtils.isEmpty(setting.getWebhooks()) || CollectionUtils.isEmpty(
                messages)) {
                continue;
            }
            for (final var webHookUrl : setting.getWebhooks()) {
                final var accessToken = getAccessToken(webHookUrl);
                for (final var alarmMessage : messages) {
                    final var content = String.format(
                        setting.getTextTemplate(),
                        alarmMessage.getAlarmMessage()
                    );
                    sendAlarmMessage(webHookUrl, accessToken, content);
                }
            }
        }
    }
@Test
    public void testWeLinkDoAlarm() throws Exception {
        List<WeLinkSettings.WebHookUrl> webHooks = new ArrayList<>();
        webHooks.add(new WeLinkSettings.WebHookUrl("clientId", "clientSecret",
                                                   "http://127.0.0.1:" + SERVER.httpPort() + "/welinkhook/api/auth/v2/tickets",
                                                   "http://127.0.0.1:" + SERVER.httpPort() + "/welinkhook/api/welinkim/v1/im-service/chat/group-chat",
                                                   "robotName", "1,2,3"
        ));
        Rules rules = new Rules();
        String template = "Apache SkyWalking Alarm: \n %s.";
        WeLinkSettings setting1 = new WeLinkSettings("setting1", AlarmHooksType.welink, true);
        setting1.setWebhooks(webHooks);
        setting1.setTextTemplate(template);
        WeLinkSettings setting2 = new WeLinkSettings("setting2", AlarmHooksType.welink, false);
        setting2.setWebhooks(webHooks);
        setting2.setTextTemplate(template);
        rules.getWeLinkSettingsMap().put(setting1.getFormattedName(), setting1);
        rules.getWeLinkSettingsMap().put(setting2.getFormattedName(), setting2);

        AlarmRulesWatcher alarmRulesWatcher = new AlarmRulesWatcher(rules, null);
        WeLinkHookCallback welinkHookCallback = new WeLinkHookCallback(alarmRulesWatcher);
        List<AlarmMessage> alarmMessages = new ArrayList<>(2);
        AlarmMessage alarmMessage = new AlarmMessage();
        alarmMessage.setScopeId(DefaultScopeDefine.SERVICE);
        alarmMessage.setRuleName("service_resp_time_rule");
        alarmMessage.setAlarmMessage("alarmMessage with [DefaultScopeDefine.All]");
        alarmMessage.getHooks().add(setting1.getFormattedName());
        alarmMessages.add(alarmMessage);
        AlarmMessage anotherAlarmMessage = new AlarmMessage();
        anotherAlarmMessage.setRuleName("service_resp_time_rule_2");
        anotherAlarmMessage.setScopeId(DefaultScopeDefine.ENDPOINT);
        anotherAlarmMessage.setAlarmMessage("anotherAlarmMessage with [DefaultScopeDefine.Endpoint]");
        anotherAlarmMessage.getHooks().add(setting2.getFormattedName());
        alarmMessages.add(anotherAlarmMessage);
        welinkHookCallback.doAlarm(alarmMessages);
        Assertions.assertTrue(IS_SUCCESS.get());
    }