优化
This commit is contained in:
163
server/services/openapi/bot.service.ts
Normal file
163
server/services/openapi/bot.service.ts
Normal file
@@ -0,0 +1,163 @@
|
||||
import { TcService, config, TcContext, call } from 'tailchat-server-sdk';
|
||||
import { isValidStr, isValidUrl } from '../../lib/utils';
|
||||
import type { OpenApp } from '../../models/openapi/app';
|
||||
import got from 'got';
|
||||
import _ from 'lodash';
|
||||
|
||||
class OpenBotService extends TcService {
|
||||
get serviceName(): string {
|
||||
return 'openapi.bot';
|
||||
}
|
||||
|
||||
onInit(): void {
|
||||
if (!config.enableOpenapi) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.registerEventListener('chat.inbox.append', async (payload, ctx) => {
|
||||
const userInfo = await call(ctx).getUserInfo(String(payload.userId));
|
||||
|
||||
if (!userInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (userInfo.type !== 'openapiBot') {
|
||||
return;
|
||||
}
|
||||
|
||||
// 开放平台机器人
|
||||
const botId: string | null = await ctx.call('user.findOpenapiBotId', {
|
||||
email: userInfo.email,
|
||||
});
|
||||
|
||||
if (!(isValidStr(botId) && botId.startsWith('open_'))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 是合法的机器人id
|
||||
|
||||
const appId = botId.replace('open_', '');
|
||||
const appInfo: OpenApp | null = await ctx.call('openapi.app.get', {
|
||||
appId,
|
||||
});
|
||||
const callbackUrl = _.get(appInfo, 'bot.callbackUrl');
|
||||
|
||||
if (!isValidUrl(callbackUrl)) {
|
||||
this.logger.info('机器人回调地址不是一个可用的url, skip.');
|
||||
return;
|
||||
}
|
||||
|
||||
got
|
||||
.post(callbackUrl, {
|
||||
json: payload,
|
||||
headers: {
|
||||
'X-TC-Payload-Type': 'inbox',
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
this.logger.info('调用机器人通知接口回调成功');
|
||||
})
|
||||
.catch((err) => {
|
||||
this.logger.error('调用机器人通知接口回调失败:', err);
|
||||
});
|
||||
});
|
||||
|
||||
this.registerAction('login', this.login, {
|
||||
params: {
|
||||
appId: 'string',
|
||||
token: 'string',
|
||||
},
|
||||
});
|
||||
this.registerAction('getOrCreateBotAccount', this.getOrCreateBotAccount, {
|
||||
params: {
|
||||
appId: 'string',
|
||||
},
|
||||
visibility: 'public',
|
||||
});
|
||||
|
||||
this.registerAuthWhitelist(['/login']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*
|
||||
* 并自动创建机器人账号
|
||||
*/
|
||||
async login(ctx: TcContext<{ appId: string; token: string }>) {
|
||||
const { appId, token } = ctx.params;
|
||||
const valid = await ctx.call('openapi.app.authToken', {
|
||||
appId,
|
||||
token,
|
||||
capability: ['bot'],
|
||||
});
|
||||
|
||||
if (!valid) {
|
||||
throw new Error('Auth failed.');
|
||||
}
|
||||
|
||||
// 校验通过, 获取机器人账号存在
|
||||
const { userId, email, nickname, avatar } = await this.localCall(
|
||||
'getOrCreateBotAccount',
|
||||
{
|
||||
appId,
|
||||
}
|
||||
);
|
||||
|
||||
const jwt: string = await ctx.call('user.generateUserToken', {
|
||||
userId,
|
||||
email,
|
||||
nickname,
|
||||
avatar,
|
||||
});
|
||||
|
||||
return { jwt, userId, email, nickname, avatar };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建机器人账号
|
||||
*/
|
||||
async getOrCreateBotAccount(ctx: TcContext<{ appId: string }>): Promise<{
|
||||
userId: string;
|
||||
email: string;
|
||||
nickname: string;
|
||||
avatar: string;
|
||||
}> {
|
||||
const appId = ctx.params.appId;
|
||||
await this.waitForServices(['user']);
|
||||
|
||||
const appInfo: OpenApp = await ctx.call('openapi.app.get', {
|
||||
appId,
|
||||
});
|
||||
|
||||
try {
|
||||
const botId = 'open_' + appInfo.appId;
|
||||
const nickname = appInfo.appName;
|
||||
const avatar = appInfo.appIcon;
|
||||
const { _id: botUserId, email } = await ctx.call<
|
||||
{
|
||||
_id: string;
|
||||
email: string;
|
||||
},
|
||||
any
|
||||
>('user.ensureOpenapiBot', {
|
||||
botId,
|
||||
nickname,
|
||||
avatar,
|
||||
});
|
||||
|
||||
this.logger.info('[getOrCreateBotAccount] Bot Id:', botUserId);
|
||||
|
||||
return {
|
||||
userId: String(botUserId),
|
||||
email,
|
||||
nickname,
|
||||
avatar,
|
||||
};
|
||||
} catch (e) {
|
||||
this.logger.error(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default OpenBotService;
|
||||
Reference in New Issue
Block a user