105 lines
3.3 KiB
TypeScript
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>`;
|
|
}
|
|
} |