You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/server/plugins/com.msgbyte.wxpusher/services/wxpusher.service.ts

175 lines
4.6 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { TcService, TcDbService, InboxStruct, call } from 'tailchat-server-sdk';
import type {
WXPusherUserDocument,
WXPusherUserModel,
} from '../models/wxpusher-user';
import got from 'got';
import type { TcContext } from 'tailchat-server-sdk';
/**
* wxpusher
*
* Add support for wxpusher to notify user
*/
interface WxpusherService
extends TcService,
TcDbService<WXPusherUserDocument, WXPusherUserModel> {}
class WxpusherService extends TcService {
get serviceName() {
return 'plugin:com.msgbyte.wxpusher';
}
get appToken() {
return process.env.WXPUSHER_APP_TOKEN;
}
/**
* 返回服务是否可用
*/
get serverAvailable(): boolean {
return Boolean(this.appToken);
}
onInit() {
this.registerLocalDb(require('../models/wxpusher-user').default);
this.registerAvailableAction(() => this.serverAvailable);
if (!this.serverAvailable) {
console.warn(
'[plugin:com.msgbyte.wxpusher] require env: WXPUSHER_APP_TOKEN'
);
return;
}
this.registerEventListener(
'chat.inbox.append',
async (inboxItem: InboxStruct, ctx) => {
if (inboxItem.type === 'message') {
const userId = inboxItem.userId;
const message = inboxItem.payload;
let title = 'new';
const senderInfo = await call(ctx).getUserInfo(message.messageAuthor);
if (message.groupId) {
const [groupInfo] = await Promise.all([
call(ctx).getGroupInfo(message.groupId),
]);
title = `[群组] ${groupInfo.name}${senderInfo.nickname}`; // 因为wxpusher插件仅适用于中国大陆因此仅需要中文即可
} else {
title = `[私信] ${senderInfo.nickname}`; // 因为wxpusher插件仅适用于中国大陆因此仅需要中文即可
}
const content = `${senderInfo.nickname}: ${
message.messagePlainContent ?? message.messageSnippet
}`; // 优先使用去节点的内容
try {
await this.sendMessage(userId, [title, content].join('\n'));
} catch (err) {
console.error(err);
}
}
}
);
this.registerAction('getWXPusherUserId', this.getWXPusherUserId);
this.registerAction('createQRCode', this.createQRCode);
this.registerAction('callback', this.callback, {
params: {
action: 'string',
data: 'any',
},
});
this.registerAuthWhitelist(['/callback']);
}
async getWXPusherUserId(ctx: TcContext) {
const userId = ctx.meta.userId;
return await this.findUserWxpusherUid(userId);
}
async createQRCode(ctx: TcContext) {
const userId = ctx.meta.userId;
const json = await got
.post('https://wxpusher.zjiecode.com/api/fun/create/qrcode', {
json: {
appToken: this.appToken, // 必填appToken,前面有说明,应用的标志
extra: userId, // 必填二维码携带的参数最长64位
validTime: 1800, // 可选二维码的有效期默认30分钟最长30天单位是秒
},
})
.json();
return json;
}
async callback(
ctx: TcContext<{
action: string;
data: any;
}>
) {
const { action, data } = ctx.params;
if (action === 'app_subscribe') {
this.logger.info('data', data);
// Reference: https://wxpusher.zjiecode.com/docs/#/?id=subscribe-callback
const userId = data.extra;
const wxpusherUserId = data.uid;
const record = await this.adapter.model.findOne({ userId });
if (!record) {
// 新增
await this.adapter.model.create({
userId,
wxpusherUserId,
});
} else {
record.wxpusherUserId = wxpusherUserId;
await record.save();
}
}
return true;
}
/**
* 查找wxpusher的用户id
*/
async findUserWxpusherUid(userId: string): Promise<string | null> {
const user = await this.adapter.model.findOne({ userId });
if (!user) {
return null;
}
const wxpusherUserId = user.wxpusherUserId;
return wxpusherUserId;
}
/**
* 发送消息
*/
async sendMessage(userId: string, content: string) {
const uid = await this.findUserWxpusherUid(userId);
if (!uid) {
console.warn('This user not bind wxpusher, skip!');
return;
}
await got.post('https://wxpusher.zjiecode.com/api/send/message', {
json: {
appToken: this.appToken,
content,
contentType: 1, //内容类型 1表示文字 2表示html(只发送body标签内部的数据即可不包括body标签) 3表示markdown
uids: [uid],
},
});
}
}
export default WxpusherService;