Skip to content

Commit

Permalink
refactor: add new dingbot adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
bytemain committed Sep 30, 2024
1 parent 7f91d47 commit 4949478
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 102 deletions.
3 changes: 2 additions & 1 deletion libs/dingtalk-bot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
},
"scripts": {
"build": "tsc",
"watch": "tsc -w",
"watch": "../../node_modules/.bin/tsc -w",
"test": "jest",
"prepublishOnly": "npm run build"
},
"dependencies": {
"@opensumi/bot-commander": "workspace:^",
"@opensumi/workers-utils": "workspace:^",
"dingtalk-stream": "^2.1.4"
}
Expand Down
11 changes: 11 additions & 0 deletions libs/dingtalk-bot/src/bot/base-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Message, SendMessage } from '../types';

export interface IBotAdapter {
id: string;
msg: Message;

replyText(text: string, contentExtra?: Record<string, any>): Promise<void>;
reply(content: SendMessage): Promise<void>;

handle(): Promise<void>;
}
53 changes: 53 additions & 0 deletions libs/dingtalk-bot/src/bot/dingtalk-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { CommandCenter, ICommandCenterOptions } from '@opensumi/bot-commander';
import * as types from '../types';
import { send } from '../utils';
import { IBotAdapter } from './base-adapter';

function prepare(s: string) {
return s.toString().trim();
}

export class DingBotAdapter<CommandCenterContext extends Record<string, any>>
implements IBotAdapter
{
public cc: CommandCenter<CommandCenterContext>;

constructor(
public id: string,
public msg: types.Message,
public commandOptions?: ICommandCenterOptions<CommandCenterContext>,
) {
this.cc = new CommandCenter(commandOptions);
}

public async getContext(): Promise<CommandCenterContext> {
return {} as CommandCenterContext;
}

async handle(options?: {
timeout?: number | null;
}) {
const msg = this.msg;
console.log(
`${this.id} receive dingtalk msg: `,
JSON.stringify(msg, null, 2),
);

// 其实目前钉钉机器人也就支持这一种消息类型
if (msg.msgtype === 'text') {
const text = prepare(msg.text.content);
console.log(`DingBot ~ handle ~ text`, text);

await this.cc.tryHandle(text, await this.getContext(), options);
}
}

async replyText(text: string, contentExtra: Record<string, any> = {}) {
await this.reply(types.compose(types.text(text), contentExtra));
}

async reply(content: types.SendMessage) {
console.log(`DingBot ~ reply:`, JSON.stringify(content));
await send(content, this.msg.sessionWebhook);
}
}
14 changes: 14 additions & 0 deletions libs/dingtalk-bot/src/bot/session.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { IBotAdapter } from './base-adapter';

export class Session {
constructor(public impl: IBotAdapter) {}

async run() {
await this.impl.handle().catch(async (err: Error) => {
await this.impl.replyText(
`处理消息出错: ${(err as Error).message} ${(err as Error).stack}`,
);
throw err;
});
}
}
4 changes: 4 additions & 0 deletions libs/dingtalk-bot/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,7 @@ export async function verifyMessage(headers: Headers, token: string) {
// return 'not valid ding msg, missing validation field';
}
}

export { IBotAdapter } from './bot/base-adapter';
export { DingBotAdapter } from './bot/dingtalk-adapter';
export { Session } from './bot/session';
6 changes: 2 additions & 4 deletions src/api/controllers/ding.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Session } from '@/im/bot';
import { DingBotAdapter } from '@/im/ding/bot';
import { DingKVManager } from '@/kv/ding';
import { verifyMessage } from '@opensumi/dingtalk-bot';
import { Session, verifyMessage } from '@opensumi/dingtalk-bot';

export function route(hono: THono) {
hono.post('/ding/:id', async (c) => {
Expand Down Expand Up @@ -36,7 +35,6 @@ export function route(hono: THono) {
}

const session = new Session(
c,
new DingBotAdapter(
id,
c,
Expand All @@ -47,7 +45,7 @@ export function route(hono: THono) {
),
);

session.runInBackground();
c.executionCtx.waitUntil(session.run());

return c.send.message('ok');
});
Expand Down
23 changes: 0 additions & 23 deletions src/im/bot.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/im/commands/index.ts

This file was deleted.

6 changes: 3 additions & 3 deletions src/im/commands/opensumi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import { IBotAdapter } from '../types';

import { KnownRepo } from './constants';
import { Context, IMCommandCenter, IMCommandCenterContext } from './types';
import { CommandCenterContext, Context, IMCommandCenter } from './types';
import { hasApp, replyIfAppNotDefined } from './utils';

/**
Expand Down Expand Up @@ -157,7 +157,7 @@ export function registerOpenSumiCommand(it: IMCommandCenter) {

async function publishNextVersion(
command: string,
{ ctx, bot }: IMCommandCenterContext,
{ ctx, bot }: CommandCenterContext,
payload: ICommand<any>,
repo: 'core' | 'codeblitz',
) {
Expand Down Expand Up @@ -217,7 +217,7 @@ async function publishNextVersion(
}

async function syncVersion(
{ ctx, bot }: IMCommandCenterContext,
{ ctx, bot }: CommandCenterContext,
command: ICommand<any>,
repo: 'core' | 'codeblitz',
) {
Expand Down
7 changes: 4 additions & 3 deletions src/im/commands/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import { CommandCenter } from '@opensumi/bot-commander';
import { Message } from '@opensumi/dingtalk-bot/lib/types';

import { IBotAdapter } from '../types';

export interface Context {
message: Message;
app?: App;
}

export interface IMCommandCenterContext {
export type CommandCenterContext = {
bot: IBotAdapter;
ctx: Context;
}
};

export type IMCommandCenter = CommandCenter<IMCommandCenterContext>;
export type IMCommandCenter = CommandCenter<CommandCenterContext>;
67 changes: 24 additions & 43 deletions src/im/ding/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,15 @@ import { App, initApp } from '@/github/app';
import { DingKVManager, DingUserKVManager } from '@/kv/ding';
import { GitHubKVManager } from '@/kv/github';
import { IDingBotSetting } from '@/kv/types';
import * as types from '@opensumi/dingtalk-bot/lib/types';
import { DingBotAdapter as BaseDingBotAdapter } from '@opensumi/dingtalk-bot';
import { Message } from '@opensumi/dingtalk-bot/lib/types';
import { send } from '@opensumi/dingtalk-bot/lib/utils';

import { cc } from '../commands';
import { IBotAdapter } from '../types';
import { registerCommonCommand } from '../commands/common';
import { registerGitHubCommand } from '../commands/github';
import { registerOpenSumiCommand } from '../commands/opensumi';
import { CommandCenterContext } from '../commands/types';

function prepare(s: string) {
return s.toString().trim();
}

export class DingBotAdapter implements IBotAdapter {
export class DingBotAdapter extends BaseDingBotAdapter<CommandCenterContext> {
githubKVManager: GitHubKVManager;
userInfoKVManager: DingUserKVManager;

Expand All @@ -28,50 +25,34 @@ export class DingBotAdapter implements IBotAdapter {
public ctx: ExecutionContext,
public setting: IDingBotSetting,
) {
super(id, msg, {
prefix: [''],
});

registerCommonCommand(this.cc);
registerGitHubCommand(this.cc);
registerOpenSumiCommand(this.cc);

this.githubKVManager = GitHubKVManager.instance();
this.userInfoKVManager = new DingUserKVManager();
}

async handle() {
const msg = this.msg;
console.log(
`${this.id} receive dingtalk msg: `,
JSON.stringify(msg, null, 2),
);
override async handle(): Promise<void> {
super.handle({
timeout: Environment.instance().timeout,
});
}

override async getContext(): Promise<CommandCenterContext> {
let app: App | undefined;
const setting = await this.githubKVManager.getAppSettingById(this.id);
if (setting) {
app = await initApp(setting);
}

// 其实目前钉钉机器人也就支持这一种消息类型
if (msg.msgtype === 'text') {
const text = prepare(msg.text.content);
console.log(`DingBot ~ handle ~ text`, text);

await cc.tryHandle(
text,
{
bot: this,
ctx: {
message: msg,
app,
},
},
{
timeout: Environment.instance().timeout,
},
);
}
}

async replyText(text: string, contentExtra: Record<string, any> = {}) {
await this.reply(types.compose(types.text(text), contentExtra));
}

async reply(content: types.SendMessage) {
console.log(`DingBot ~ reply:`, JSON.stringify(content));
await send(content, this.msg.sessionWebhook);
return {
bot: this,
ctx: { message: this.msg, app },
};
}
}
11 changes: 2 additions & 9 deletions src/im/types.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import type { DingKVManager, DingUserKVManager } from '@/kv/ding';
import { Message, SendMessage } from '@opensumi/dingtalk-bot/lib/types';
import { IBotAdapter as _IBotAdapter } from '@opensumi/dingtalk-bot/lib/bot/adapter';

export interface IBotAdapter {
id: string;
export interface IBotAdapter extends _IBotAdapter {
kvManager: DingKVManager;
userInfoKVManager: DingUserKVManager;
msg: Message;

replyText(text: string, contentExtra?: Record<string, any>): Promise<void>;
reply(content: SendMessage): Promise<void>;

handle(): Promise<void>;
}
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "@opensumi/dingtalk-bot@workspace:libs/dingtalk-bot"
dependencies:
"@opensumi/bot-commander": "workspace:^"
"@opensumi/workers-utils": "workspace:^"
dingtalk-stream: "npm:^2.1.4"
languageName: unknown
Expand Down

0 comments on commit 4949478

Please sign in to comment.