如何在Mirth中延迟消息投递至预约系统允许的30天窗口内?
在Mirth中实现预约消息的延迟投递(适配30天预约窗口)
核心逻辑
先从源消息中提取预约日期,计算当前日期与「预约日期前30天」的时间差:
- 若差值为正,说明消息需要延迟,等到差值归零后再投递到目标系统
- 若差值为负或零,直接转发消息
具体实现方案
方案1:使用Mirth内置延迟队列(推荐)
Mirth原生支持消息延迟投递,无需额外依赖,步骤如下:
- 解析预约日期:在Channel的Transformer中编写脚本,从源消息里提取预约日期并转为Date对象。示例(根据实际消息结构调整):
// 假设消息中预约日期字段为appointmentDateTime var apptDateTime = new Date(msg['appointmentDateTime'].text()); - 计算延迟时长:算出当前时间到「预约日期前30天」的毫秒差:
var now = new Date(); var triggerTime = new Date(apptDateTime.getTime() - 30 * 24 * 60 * 60 * 1000); var delayMs = triggerTime.getTime() - now.getTime(); - 设置延迟投递:
- 如果
delayMs > 0,在Postprocessor或Destination脚本中设置消息延迟:if (delayMs > 0) { message.setDelay(delayMs); } - 将Destination的发送模式设为「Queue」,确保消息进入延迟队列等待触发。
- 如果
方案2:数据库存储+定时轮询(复杂场景适配)
如果内置队列无法满足自定义持久化、重试逻辑等需求,可采用数据库存储+定时轮询方案:
- 创建存储表:在数据库中创建表(以MySQL为例):
CREATE TABLE delayed_appointments ( id INT AUTO_INCREMENT PRIMARY KEY, message_content TEXT NOT NULL, appointment_date DATETIME NOT NULL, status VARCHAR(20) DEFAULT 'PENDING', created_at DATETIME DEFAULT CURRENT_TIMESTAMP ); - 存储待延迟消息:在源Channel的Transformer中,判断需要延迟的消息,将内容和预约日期插入表中:
if (delayMs > 0) { // 插入数据库,需配置Mirth的数据库连接 var dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.cj.jdbc.Driver', 'jdbc:mysql://localhost:3306/mirth_db', 'user', 'password'); var sql = "INSERT INTO delayed_appointments (message_content, appointment_date) VALUES (?, ?)"; dbConn.executeUpdate(sql, [JSON.stringify(msg), apptDateTime.toISOString()]); dbConn.close(); // 终止当前消息流程,避免直接发送 responseMap.put('Destination 1', ResponseFactory.getSuccessResponse('Message queued for delayed delivery')); } - 定时轮询发送:新建一个Mirth Channel,配置定时触发器(比如每小时执行一次),查询符合条件的消息并发送:
var dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.cj.jdbc.Driver', 'jdbc:mysql://localhost:3306/mirth_db', 'user', 'password'); var now = new Date(); var thirtyDaysLater = new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000); var sql = "SELECT * FROM delayed_appointments WHERE status = 'PENDING' AND appointment_date <= ?"; var results = dbConn.executeQuery(sql, [thirtyDaysLater.toISOString()]); while (results.next()) { var msgContent = JSON.parse(results.getString('message_content')); // 发送消息到目标系统(调用目标Destination的发送逻辑) var response = ChannelUtil.sendToChannel('目标ChannelID', msgContent); if (response.isSuccess()) { dbConn.executeUpdate("UPDATE delayed_appointments SET status = 'SENT' WHERE id = ?", [results.getInt('id')]); } } dbConn.close();
关键注意事项
- 日期时区处理:确保所有日期计算使用统一时区,避免因时区偏移导致延迟时间计算错误,可使用
toUTCString()或Moment.js(Mirth内置支持)统一处理。 - 消息持久化:内置队列需开启「Queue Persistence」配置,避免Mirth重启后丢失延迟消息;数据库方案需定期清理已发送的消息,避免表膨胀。
- 重试机制:在Destination中配置重试次数和间隔,或在数据库方案中增加重试次数字段,处理发送失败的情况。
- 性能优化:数据库方案需为
appointment_date和status字段添加联合索引,提升查询效率。
内容的提问来源于stack exchange,提问作者Mitch
相关产品推荐
相关产品推荐

