feat: add plugin com.msgbyte.wxpusher

just has basic backend logic
pull/90/head
moonrailgun 2 years ago
parent bb2792eb98
commit 32de5b17e5

File diff suppressed because it is too large Load Diff

@ -0,0 +1,14 @@
const path = require('path');
module.exports = {
externalDeps: [
'react',
'react-router',
'axios',
'styled-components',
'zustand',
'zustand/middleware/immer',
],
pluginRoot: path.resolve(__dirname, './web'),
outDir: path.resolve(__dirname, '../../public'),
};

@ -0,0 +1,26 @@
import { db } from 'tailchat-server-sdk';
const { getModelForClass, prop, modelOptions, TimeStamps } = db;
@modelOptions({
options: {
customName: 'p_wxpusher_user',
},
})
export class WXPusherUser extends TimeStamps implements db.Base {
_id: db.Types.ObjectId;
id: string;
@prop()
userId: string;
@prop()
wxpusherUserId: string;
}
export type WXPusherUserDocument = db.DocumentType<WXPusherUser>;
const model = getModelForClass(WXPusherUser);
export type WXPusherUserModel = typeof model;
export default model;

@ -0,0 +1,21 @@
{
"name": "tailchat-plugin-wxpusher",
"version": "1.0.0",
"main": "index.js",
"author": "moonrailgun",
"description": "Add support for wxpusher to notify user",
"license": "MIT",
"private": true,
"scripts": {
"build:web": "ministar buildPlugin all",
"build:web:watch": "ministar watchPlugin all"
},
"devDependencies": {
"@types/react": "18.0.20",
"mini-star": "*"
},
"dependencies": {
"got": "^11.8.3",
"tailchat-server-sdk": "*"
}
}

@ -0,0 +1,142 @@
import { TcService, TcDbService } 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.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;
}
/**
* wxpusherid
*/
async findUserWxpusherUid(userId: string): Promise<string | null> {
const user = await this.adapter.model.findOne({ userId });
if (!user) {
return null;
}
const uid = user.wxpusherUserId;
return uid;
}
/**
*
*/
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;

@ -0,0 +1,9 @@
{
"label": "wxpusher",
"name": "com.msgbyte.wxpusher",
"url": "{BACKEND}/plugins/com.msgbyte.wxpusher/index.js",
"version": "0.0.0",
"author": "moonrailgun",
"description": "Add support for wxpusher to notify user",
"requireRestart": true
}

@ -0,0 +1,16 @@
{
"name": "@plugins/com.msgbyte.wxpusher",
"main": "src/index.tsx",
"version": "0.0.0",
"description": "Add support for wxpusher to notify user",
"private": true,
"scripts": {
"sync:declaration": "tailchat declaration github"
},
"dependencies": {},
"devDependencies": {
"@types/styled-components": "^5.1.26",
"react": "18.2.0",
"styled-components": "^5.3.6"
}
}

@ -0,0 +1,7 @@
{
"compilerOptions": {
"esModuleInterop": true,
"jsx": "react",
"importsNotUsedAsValues": "error"
}
}

@ -0,0 +1,2 @@
declare module '@capital/common';
declare module '@capital/component';
Loading…
Cancel
Save