Skip to content

Commit

Permalink
Support command parse
Browse files Browse the repository at this point in the history
  • Loading branch information
zxdong262 committed May 23, 2022
1 parent 9d1b047 commit 73c78cf
Show file tree
Hide file tree
Showing 9 changed files with 941 additions and 785 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ function eventHandler ({
group, // the group object, can get chat group id from group.id
userId, // message creator's id
isPrivateChat, // if it is a private chat
message // message object, check ringcentral api document for detail
message, // message object, check ringcentral api document for detail
commandLineOptions, // only if set commandLineConfigs in botConfig, would get parse result from text, check doc/command-line-parser.md for detail
}) {
console.log(
type,
Expand Down Expand Up @@ -71,7 +72,18 @@ const botConfig = {
botRoute: '/bot', // optional
models: { // optional
Bot: 'your bot data model defination' // check src/models/Bot.ts as a example, optional
},
commandLineConfigs: { // optional
{
command: 'add'
options: [
['-f, --float <number>', 'float argument'],
['-i, --integer <number>', 'integer argument'],
['-v, --verbose', 'verbosity that can be increased']
]
}
}
// if set commandLineConfigs in botConfig, would get parsed commandLineOptions object from text, check doc/command-line-parser.md for detail(use commander module)
}

let app = express()
Expand Down
95 changes: 95 additions & 0 deletions doc/command-line-parser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
```js
function myParseInt(value, dummyPrevious) {
// parseInt takes a string and a radix
const parsedValue = parseInt(value, 10);
if (isNaN(parsedValue)) {
throw new commander.InvalidArgumentError('Not a number.');
}
return parsedValue;
}

function increaseVerbosity(dummyValue, previous) {
return previous + 1;
}

function collect(value, previous) {
return previous.concat([value]);
}

function commaSeparatedList(value, dummyPrevious) {
return value.split(',');
}

const botConfig = {
adminRoute: '/admin', // optional
botRoute: '/bot', // optional
models: { // optional
Bot: 'your bot data model defination' // check src/models/Bot.ts as a example, optional
},
commandLineConfigs: { // optional
{
command: 'adjust'
options: [
['-f, --float <number>', 'float argument', parseFloat],
['-i, --integer <number>', 'integer argument', myParseInt],
['-v, --verbose', 'verbosity that can be increased', increaseVerbosity, 0],
['-c, --collect <value>', 'repeatable value', collect, []],
['-l, --list <items>', 'comma separated list', commaSeparatedList]
]
},
{
command: 'list' // this command no option
},
{
command: 'add' // this command no option
}
}
// if set commandLineConfigs in botConfig, would get parsed options object from text, check doc/command-line-parser.md for detail
}


function eventHandler ({
type, // could be 'BotRemoved', 'Message4Bot', 'Message4Others', 'BotGroupLeft', 'BotJoinGroup', 'Maintain', 'SetupDatabase'
bot, // the bot instance, check src/models/Bot.ts for instance methods
text, // the text message user posted in chat group
group, // the group object, can get chat group id from group.id
userId, // message creator's id
isPrivateChat, // if it is a private chat
message, // message object, check ringcentral api document for detail
commandLineOptions, // only if set commandLineConfigs in botConfig, would get parse result from text, check doc/command-line-parser.md for detail
}) {
console.log(
type,
bot,
text,
group,
userId,
message
)
// when text === 'list'
expect(commandLineOptions).tobeEqual({
command: 'list',
rest: ''
})
// when text = 'add more text desc'
expect(commandLineOptions).tobeEqual({
command: 'add',
rest: 'more text desc',
options: {
verbose: 0,
collect: []
}
})
// when text = 'adjust -f 5.8 -i 5654 some other not related text '
expect(commandLineOptions).tobeEqual({
command: 'add',
rest: ' -f 5.8 -i 5654 some other not related text ',
options: {
verbose: 0,
collect: [],
integer: 5654,
float: 5.8
}
})
}
```
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ringcentral-chatbot-core",
"version": "1.4.0",
"version": "1.5.1",
"license": "MIT",
"scripts": {
"test": "RINGCENTRAL_CHATBOT_DATABASE_CONNECTION_URI=sqlite:// jest -c test/jest.config.ts",
Expand All @@ -13,6 +13,7 @@
"@types/supertest": "^2.0.11",
"@types/validator": "^13.6.3",
"axios": "^0.24.0",
"commander": "^9.2.0",
"dynamo-sequelize": "^3.0.0",
"express": "^4.17.1",
"express-basic-auth": "^1.2.0",
Expand All @@ -28,10 +29,10 @@
"jest": "^27.0.6",
"ramda": "^0.27.1",
"sqlite3": "^5.0.2",
"supertest": "^6.1.4",
"ts-jest": "^27.0.4",
"ts-node": "^10.1.0",
"typescript": "^4.3.5",
"supertest": "^6.1.4",
"yarn-upgrade-all": "^0.5.4"
},
"files": [
Expand Down
2 changes: 1 addition & 1 deletion src/apps/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const createApp = (handle: Function, conf: BotConfig) => {
break;
}
case 'PostAdded': {
const result = await postAdded(Bot, message);
const result = await postAdded(Bot, message, conf);
if (result) {
await handle({type: 'Message4Bot', ...result});
}
Expand Down
31 changes: 31 additions & 0 deletions src/handlers/command-line-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* parse text to command line
*/

import { program } from 'commander'

export default (text: string, commandLineConfigs: any []): any => {
const arr = text.split(' ')
const cmd: any = arr[0]
if (!cmd) {
return {}
}
const conf: any = commandLineConfigs.find(c => c.command === cmd)
if (!conf) {
return {}
}
const rest = arr.slice(1)
const res: any = {
command: cmd,
rest: rest.join(' ')
}
if (conf.options && rest.length) {
for (const opt of conf.options) {
(program.option as any)(...opt)
}
program.parse(rest, { from: 'user' })
const options = program.opts()
res.options = options
}
return res
}
30 changes: 22 additions & 8 deletions src/handlers/postAdded.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import axios from 'axios';
import {BotType, Message, BotConfig} from '../types';
import commandParser from './command-line-parser'

import {BotType, Message} from '../types';

export const postAdded = async (Bot: any, message: Message) => {
let text = message.body.text;
if (!text) {
export const postAdded = async (Bot: any, message: Message, conf: BotConfig) => {
const originalText = message.body.text;
if (!originalText) {
return; // not a text message
}
const botId = message.ownerId;
Expand All @@ -25,7 +25,7 @@ export const postAdded = async (Bot: any, message: Message) => {
!message.body.mentions.some(m => m.type === 'Person' && m.id === botId))
) {
return {
text,
text: originalText,
group,
bot,
userId,
Expand All @@ -35,7 +35,7 @@ export const postAdded = async (Bot: any, message: Message) => {
};
}
const regex = new RegExp(`!\\[:Person\\]\\(${bot.id}\\)`);
text = text.replace(regex, ' ').trim();
const text = originalText.replace(regex, ' ').trim();
if (text.startsWith('__rename__')) {
await bot.rename(text.substring(10).trim());
return;
Expand All @@ -55,5 +55,19 @@ export const postAdded = async (Bot: any, message: Message) => {
await bot.updateToken(text.substring(15).trim());
return;
}
return {text, group, bot, userId, isPrivateChat, message: message.body};
const result: any = {
originalText,
text,
group,
bot,
userId,
isPrivateChat,
message:
message.body
};
if (conf.commandLineConfigs) {
const commandLineOptions = commandParser(text, conf.commandLineConfigs)
result.commandLineOptions = commandLineOptions
}
return result
};
8 changes: 5 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ export const extendApp = (
adminRoute: '/admin',
botRoute: '/bot',
models: {}
}
},
commandLineConfigs?: any [],
) => {
const conf = {
commandLineConfigs,
...config,
models: Object.assign({}, defaultModels, config.models || {})
}
Expand All @@ -42,12 +44,12 @@ export const extendApp = (

if (process.env.RINGCENTRAL_CHATBOT_ADMIN_USERNAME && process.env.RINGCENTRAL_CHATBOT_ADMIN_PASSWORD) {
app.use(
config.adminRoute,
conf.adminRoute,
adminApp(mergedHandle, conf)
);
}
app.use(
config.botRoute,
conf.botRoute,
botApp(mergedHandle, conf)
);
for (const skill of skills) {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export type AttachmentType = {
};

export interface BotConfig {
commandLineConfigs?: any [],
adminRoute: string,
botRoute: string,
models?: any,
Expand Down
Loading

0 comments on commit 73c78cf

Please sign in to comment.