Files
directus-extensions-wechat-…/src/utils/wechatReplyBuilder.ts
R2m1liA 948e7bf109 feat: 微信公众号/服务号 被动回复用户消息功能
- 自动回复:根据用户发送的关键词查询Directus自动回复集合,并返回相应的结果。目前支持文本回复与图文回复
2025-12-13 06:00:21 +00:00

105 lines
3.3 KiB
TypeScript

import { WechatReceivedBaseMessage } from "../types/received-message";
export interface WechatReplyBuilderOptions {
/** 接收方账号(收到的OpenID) */
toUserName: string;
/** 发送方账号(公众号微信号) */
fromUserName: string;
/** 消息创建时间(整型) */
createTime: number;
}
/**
* 微信被动回复消息构造器
*
* - 微信公众号/服务号被动回复用户消息时使用
* - 对应微信官方XML消息结构
*
* @see 微信官方文档: [被动回复用户消息](https://developers.weixin.qq.com/doc/service/guide/product/message/Passive_user_reply_message.html)
*/
export class WechatReplyBuilder {
/** 接收方账号(收到的OpenID) */
private toUserName: string;
/** 发送方账号(公众号微信号) */
private fromUserName: string
/** 消息创建时间(整型) */
private createTime: number;
/**
* WechatReplyBuilder 构造函数
*
* @param options WechatReplyBuilderOptions 配置项
*/
private constructor(options: WechatReplyBuilderOptions) {
const {
toUserName,
fromUserName,
createTime,
} = options;
this.toUserName = toUserName;
this.fromUserName = fromUserName;
this.createTime = createTime;
}
static fromReceivedMessage(msg: WechatReceivedBaseMessage): WechatReplyBuilder {
return new WechatReplyBuilder({
toUserName: msg.FromUserName,
fromUserName: msg.ToUserName,
createTime: Date.now(),
});
}
static fromOptions(options: Omit<WechatReplyBuilderOptions, "createTime"> & {
createTime?: number;
}): WechatReplyBuilder {
return new WechatReplyBuilder({
...options,
createTime: options.createTime ?? Date.now(),
});
}
/**
* 构造文本消息回复XML
*
* @param content 文本消息内容
* @returns 文本消息回复XML字符串
*/
buildTextReply(content: string): string {
return `<xml>
<ToUserName><![CDATA[${this.toUserName}]]></ToUserName>
<FromUserName><![CDATA[${this.fromUserName}]]></FromUserName>
<CreateTime>${this.createTime}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[${content}]]></Content>
</xml>`;
}
/**
* 构造图文消息回复XML
*
* @param title 图文消息标题
* @param description 图文消息描述
* @param picUrl 图文消息图片链接
* @param url 图文消息跳转链接
* @returns 图文消息回复XML字符串
*/
buildNewsReply(title: string, description: string, picUrl: string, url: string): string {
return `<xml>
<ToUserName><![CDATA[${this.toUserName}]]></ToUserName>
<FromUserName><![CDATA[${this.fromUserName}]]></FromUserName>
<CreateTime>${this.createTime}</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[${title}]]></Title>
<Description><![CDATA[${description}]]></Description>
<PicUrl><![CDATA[${picUrl}]]></PicUrl>
<Url><![CDATA[${url}]]></Url>
</item>
</Articles>
</xml>`;
}
}