smartqq java_基于SmartQQ协议的QQ聊天机器人-4

本节的主题是:结合上节的分析,具体分析函数的实现

1. 回复消息模块:

集中在org.b3log.xiaov.service包。主控文件是QQService.java,其他只是回复算法的api和一些支持工具utils,不用管。目前我在研究怎么改写它——支持“基于文本的一问一答”

配置文件有两个目前用得上:

src/main/resources下面的xiaov.properties(针对机器人功能做的一些配置);

log4j.properties(定制整个项目中的Logger模块在各个文件中的级别,用于调试和写日志)

xiaov.properties中设置了bot.follow.keywords和bot.follow.keywordAnswer,就是【捕获关键字】+【返回对应答案魔板】,但是它只是个demo,我要让他支持海量文本,并结构化输入和结构化输出。更多参数的解释见我的代码注释。

2. 下面针对上述3点进行操作:

发送消息与回复消息的调用关系:{结合viso绘制调用流程图}

见代码的修改

我修改了两个函数:

answer里面回复的逻辑+解决编码问题+try-catch;

QQService.java里面的onQQGroupMessage对问题的验证逻辑

/*

// answer里面回复的逻辑+解决编码问题+try-catch;

// xiaov_1_0\src\main\java\org\b3log\xiaov\service\QQService.java

* 这是我对xiaov-1.0的注释1.0

* 这个函数非常重要,定义了提问和回答这两个功能的数据结构及数据来源

* 我会抽时间把这个函数讲清楚 TODO

* */

private String answer(final String content, final String userName) throws SQLException {

if (keywords.size() == 0) // 加载一次即可

{

// 获取keys,只调用一次

keywords = AnswersFromSQLite.getAllKeys();

}

// LOGGER.debug(keywords.get(0));// 测试下content

String keyword = "";

for (final String kw : keywords) {

if (StringUtils.containsIgnoreCase(content, kw)) {

keyword = kw;

break;

}

}

// LOGGER.debug(content);// 测试下content

// LOGGER.debug(keyword);// 测试下keyword有没有捕捉到

String ret = "";

String msg = replaceBotName(content);

if (StringUtils.isNotBlank(keyword)) {

try { // 这部分是我的改写

ret = AnswersFromSQLite.getValue(keyword);// 自定义回复消息

ret= URLEncoder.encode(ret, "UTF-8");

} catch (final UnsupportedEncodingException e) {

LOGGER.log(Level.ERROR, "Search key encoding failed", e);

}

} else if (StringUtils.contains(content, XiaoVs.QQ_BOT_NAME) && StringUtils.isNotBlank(msg)) {

...

// 这部分和作者源码一致,省略了

}

try {

ret= URLDecoder.decode(ret, "UTF-8");

} catch (final UnsupportedEncodingException e) {

LOGGER.log(Level.ERROR, "ret decoding failed", e);

}

return ret;

}

// E:\Software_install\MyEclipse15_20_Work\code_backup\xiaov_1_0\src\main\java\org\b3log\xiaov\service\SQLiteAnswers\AnswersFromSQLite.class

public class AnswersFromSQLite {

... //见我的源码

public static String getValue(String key) throws SQLException {

// 测试查询某条记录

Dao dao = getDao();

List ans = queryByOPtions(dao, key);

// logger.info(ans.get(0).getValue());

if (ans != null) {

return ans.get(0).getValue(); // 仅返回第一条记录的value字段

}

return null;

}

... //省略,见我的代码

}

/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------*/

// QQService.java里面的onQQGroupMessage对问题的验证逻辑

// E:\Software_install\MyEclipse15_20_Work\code_backup\xiaov_1_0\src\main\java\org\b3log\xiaov\service\QQService.java

/*

* 这是我的注释1.0

* 这个函数非常重要,我会抽时间把这个函数讲清楚 TODO

* */

private void onQQGroupMessage(final GroupMessage message) throws SQLException {

final long groupId = message.getGroupId();

final long userId = message.getUserId();// 获取消息的sender的QQ号,与机器人的QQ做比较

//LOGGER.debug(Long.toString(userId));

//final long botId = XiaoVs.getInt("qq.bot.id");//从配置文件中读当前机器人的QQ号 {还有点bug,后面再修}

// 为了解决2872995315溢出的问题,只能把userId和机器人ID比较由 Long比较 转化成 字符串比较

String s_userId = Long.toString(userId);

//final String s_botId = "2872995315";//暂时写死

final String s_botId = XiaoVs.getString("qq.bot.id"); //从xiaov.properties配置文件中读

final String content = message.getContent();

final String userName = Long.toHexString(message.getUserId());

// Push to third system

String qqMsg = content.replaceAll("\\[\"face\",[0-9]+\\]", "");

if (StringUtils.isNotBlank(qqMsg)) {

qqMsg = "

" + qqMsg + "

";

sendToThird(qqMsg, userName);

}

String msg = "";

// 下面是对于QQ用户提问的语句进行合法性分析,如果符合规则,那就收集答案,并发送到QQ群 {要避免机器人自问自答的情况发生}

/*

if (StringUtils.contains(content, XiaoVs.QQ_BOT_NAME)

|| (StringUtils.length(content) > 6

&& (StringUtils.contains(content, "?") || StringUtils.contains(content, "?") || StringUtils.contains(content, "问")))) {

msg = answer(content, userName);

}*/

if ( StringUtils.contains(content, XiaoVs.QQ_BOT_NAME) // TODO:这里是对提问的基本要求{过滤不合法的提问}

|| (StringUtils.length(content) > 0) && !(s_userId.equals(s_botId)) ) { //彻底解决了机器人自问自答的bug

msg = answer(content, userName);

}

if (StringUtils.isBlank(msg)) {

return;

}

if (RandomUtils.nextFloat() >= 0.9) {

Long latestAdTime = GROUP_AD_TIME.get(groupId);

if (null == latestAdTime) {

latestAdTime = 0L;

}

final long now = System.currentTimeMillis();

if (now - latestAdTime > 1000 * 60 * 30) {

msg = msg + "。\n" + ADS.get(RandomUtils.nextInt(ADS.size()));

GROUP_AD_TIME.put(groupId, now);

}

}

sendMessageToGroup(groupId, msg);

}

我觉得必须要放到svn或者git托管了,否则一旦出错了,没有回滚项目就完了

3. 突然发现的小Tips:

突然发现,其实还有个小薇的守护QQ(在哪里有写?防止丢消息??)但是我目前没用守护QQ,依旧正常运行,后面有需要再处理这个tips

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值