Compare commits

...

2 Commits

6 changed files with 248 additions and 4 deletions

View File

@ -0,0 +1,51 @@
package cn.axzo.workflow.server.devops;
import cn.axzo.riven.client.model.DingtalkReceiveMqModel;
import cn.axzo.riven.client.model.ReplyMessage;
import cn.axzo.riven.client.model.SampleText;
import org.springframework.util.StringUtils;
import java.util.Objects;
/**
* TODO
*
* @author wangli
* @since 2024-10-25 09:39
*/
public abstract class AbstractKeywordProcessor implements KeywordProcessor {
private DingtalkReceiveMqModel receiveModel;
@Override
public void setReceiveModel(DingtalkReceiveMqModel receiveModel) {
this.receiveModel = receiveModel;
}
protected final DingtalkReceiveMqModel getReceiveModel() {
return receiveModel;
}
@Override
public final ReplyMessage process(String content) {
String originalContent = content.trim();
for (String s : getKeywords()) {
content = content.trim().replaceFirst(s, "");
}
if (!StringUtils.hasText(content)) {
ReplyMessage help = help();
if (Objects.isNull(help) && Objects.equals(content, "")) {
help = SampleText.from("当前命令(" + originalContent + ")未配置帮助信息哦");
}
return help;
}
return doProcess(content);
}
/**
* 这里的 content 已经移除了命令字符串仅需对内容或者参数做解析处理即可
*
* @param content
* @return
*/
protected abstract ReplyMessage doProcess(String content);
}

View File

@ -0,0 +1,39 @@
package cn.axzo.workflow.server.devops;
import cn.axzo.riven.client.model.DingtalkReceiveMqModel;
import cn.axzo.riven.client.model.ReplyMessage;
import org.springframework.core.Ordered;
/**
* 机器人支持的关键词
*
* @author wangli
* @since 2024-10-24 16:29
*/
public interface KeywordProcessor extends Ordered {
default int getOrder() {
return 0;
}
/**
* 透传钉钉机器人回调的消息
*/
void setReceiveModel(DingtalkReceiveMqModel receiveModel);
String[] getKeywords();
/**
* 当使用了关键词但是内容为空时提出响应的使用提示
*
* @return
*/
ReplyMessage help();
/**
* 根据关键词的内容进行处理
*
* @param content 含有关键词的完整消息
* @return
*/
ReplyMessage process(String content);
}

View File

@ -0,0 +1,78 @@
package cn.axzo.workflow.server.devops;
import cn.axzo.riven.client.model.DingtalkReceiveMqModel;
import cn.axzo.riven.client.model.ReplyMessage;
import cn.axzo.workflow.server.devops.impl.HelpKeywordProcessor;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* 注册会话
* <p>
* 新创建的群添加机器人后在群内@机器人并发送注册两个字即可完成注册
*
* @author wangli
* @since 2024-10-23 17:30
*/
@Slf4j
@Component
@AllArgsConstructor
public class KeywordProcessorStrategy {
// 容器中所有实现了的关键词 Spring's Bean
private final List<KeywordProcessor> keywordProcessorHandles;
// 关键词对应的处理 Bean Map
private Map<String, KeywordProcessor> keywordMap;
// 具体的关键词
private Set<String> words;
@PostConstruct
public void init() {
keywordProcessorHandles.forEach(bean -> {
words.addAll(Lists.newArrayList(bean.getKeywords()));
for (String keyword : bean.getKeywords()) {
keywordMap.put(keyword, bean);
}
});
}
public boolean support(String keyword) {
for (String word : words) {
if (keyword.trim().startsWith(word)) {
return true;
}
}
return false;
}
public ReplyMessage doHandle(DingtalkReceiveMqModel receiveModel) {
if (log.isDebugEnabled()) {
log.debug(" KeywordProcessorStrategy Entrance ");
}
KeywordProcessor keywordProcessor = getKeywordHandle(receiveModel.getContent());
keywordProcessor.setReceiveModel(receiveModel);
return keywordProcessor.process(receiveModel.getContent());
}
private KeywordProcessor getKeywordHandle(String content) {
content = content.trim();
if (StringUtils.hasText(content)) {
for (String word : words) {
if (content.startsWith(word)) {
return keywordMap.get(word);
}
}
}
return new HelpKeywordProcessor();
}
}

View File

@ -0,0 +1,28 @@
package cn.axzo.workflow.server.devops.impl;
import cn.axzo.riven.client.model.ReplyMessage;
import cn.axzo.riven.client.model.SampleText;
import cn.axzo.workflow.server.devops.AbstractKeywordProcessor;
/**
* 默认的关键词处理器对于那些无法识别的命令无需被 Spring 管理
*
* @author wangli
* @since 2024-10-31 16:44
*/
public class DefaultKeywordProcessor extends AbstractKeywordProcessor {
@Override
public ReplyMessage doProcess(String content) {
return SampleText.from(content);
}
@Override
public String[] getKeywords() {
return new String[0];
}
@Override
public ReplyMessage help() {
return null;
}
}

View File

@ -0,0 +1,39 @@
package cn.axzo.workflow.server.devops.impl;
import cn.axzo.riven.client.model.ReplyMessage;
import cn.axzo.riven.client.model.SampleMarkdown;
import cn.axzo.workflow.server.devops.AbstractKeywordProcessor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 帮助的关键词
*
* @author wangli
* @since 2024-10-24 17:01
*/
@Slf4j
@Component
public class HelpKeywordProcessor extends AbstractKeywordProcessor {
private final static String[] KEYWORD = {"help", "帮助"};
@Override
public int getOrder() {
return Integer.MAX_VALUE;
}
@Override
public String[] getKeywords() {
return KEYWORD;
}
@Override
public ReplyMessage help() {
return doProcess(null);
}
@Override
public ReplyMessage doProcess(String content) {
return SampleMarkdown.from("帮助信息", "需要我帮你做什么呢?不妨@我发送“help”或者“帮助”试试吧");
}
}

View File

@ -6,7 +6,10 @@ import cn.axzo.framework.rocketmq.EventHandler;
import cn.axzo.riven.client.common.enums.DingtalkEventEnum;
import cn.axzo.riven.client.model.DingtalkReceiveMqModel;
import cn.axzo.riven.client.model.DingtalkSendMqModel;
import cn.axzo.riven.client.model.ReplyMessage;
import cn.axzo.riven.client.model.SampleText;
import cn.axzo.workflow.server.devops.KeywordProcessorStrategy;
import cn.axzo.workflow.server.devops.impl.DefaultKeywordProcessor;
import cn.axzo.workflow.server.outside.mq.producer.DingtalkSendProducer;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
@ -29,6 +32,8 @@ public class DingtalkReceiveListener implements EventHandler, InitializingBean {
@Value("${spring.application.name}")
private String applicationName;
@Resource
private KeywordProcessorStrategy keywordProcessorStrategy;
@Resource
private EventConsumer eventConsumer;
@Resource
private DingtalkSendProducer dingtalkSendProducer;
@ -45,18 +50,22 @@ public class DingtalkReceiveListener implements EventHandler, InitializingBean {
log.debug("message data: {}", JSON.toJSONString(data));
}
DingtalkSendMqModel<SampleText> sendModel = new DingtalkSendMqModel<>();
DingtalkSendMqModel sendModel = new DingtalkSendMqModel<>();
sendModel.setTraceId(data.getTraceId());
sendModel.setConversationId(data.getConversationId());
sendModel.setMsgId(data.getMsgId());
sendModel.setRobotCode(data.getRobotCode());
sendModel.setMessage(SampleText.from("由 WorkflowEngine 处理的消息: " + data.getContent()));
if (keywordProcessorStrategy.support(data.getContent())) {
sendModel.setMessage(keywordProcessorStrategy.doHandle(data));
} else {
String msg = "" + applicationName + " 处理的机器人消息,但暂未能理解你说的话:" + data.getContent();
sendModel.setMessage(new DefaultKeywordProcessor().doProcess(msg));
}
dingtalkSendProducer.send(sendModel);
}
@Override
public void afterPropertiesSet() throws Exception {
public void afterPropertiesSet() {
eventConsumer.registerHandler(DingtalkEventEnum.receive.getEventCode(), this);
}
}