Skip to content

Commit

Permalink
fix: update learn ctrl to use named data
Browse files Browse the repository at this point in the history
  • Loading branch information
ssube committed Dec 28, 2018
1 parent b7292b1 commit 4a53d4a
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 33 deletions.
6 changes: 2 additions & 4 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,20 @@ TODO: react to an existing message

#### Learn Keyword

TODO: the learn controller needs to be refactored to use named data (vs args)

The bot is able to learn commands and execute them later using a keyword.

To teach the bot a new keyword:

```
> !!learn time get tgif
> !!learn tgif time get
> @you, Learned command tgif.
```

To execute the command, passing some extra data (to be merged with any saved data):

```
> !!args --noun keyword --verb update --args tgif
> !!args --noun keyword --verb update --keyword tgif
> @you, 12/28/2018, 1:39:06 PM
```
Expand Down
4 changes: 2 additions & 2 deletions docs/parser/split-parser-learn.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ metadata:
name: default-learn
data:
dataMapper:
take: [noun, verb]
take: [keyword, future-noun, future-verb]
skip: 0
rest: args
rest: body
every: false

preferData: false
Expand Down
55 changes: 28 additions & 27 deletions src/controller/LearnController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,44 +32,37 @@ export class LearnController extends BaseController<LearnControllerData> impleme
}

public async handle(cmd: Command): Promise<void> {
const args: Array<string> = cmd.get('args');
if (!args) {
return this.reply(cmd.context, 'missing args to learn controller');
}

const [keyword, ...body] = args;

this.logger.debug({ body, keyword }, 'handling learned keyword');

switch (cmd.verb) {
case CommandVerb.Create:
return this.createKeyword(keyword, cmd, body);
return this.createKeyword(cmd);
case CommandVerb.Delete:
return this.deleteKeyword(keyword, cmd.context);
return this.deleteKeyword(cmd);
case CommandVerb.Update:
default:
return this.executeKeyword(keyword, cmd.context, body);
return this.executeKeyword(cmd);
}
}

protected async createKeyword(key: string, cmd: Command, args: Array<string>): Promise<void> {
const noun = cmd.getHead('noun');
const verb = cmd.getHead('verb') as CommandVerb;
protected async createKeyword(cmd: Command): Promise<void> {
const body = cmd.getOrDefault('body', []);
const key = cmd.getHead('keyword');
const noun = cmd.getHead('future-noun');
const verb = cmd.getHead('future-verb') as CommandVerb;

if (!this.checkNoun.check(noun)) {
return this.reply(cmd.context, 'invalid noun');
}

const keyword = new Keyword({
controllerId: this.getId(true),
data: { args },
data: { body },
key,
labels: {},
noun,
verb,
});

this.logger.debug({ args, cmd, key, keyword }, 'learning command');
this.logger.debug({ body, cmd, key, keyword }, 'learning command');

const existing = await this.keywordRepository.findOne({
key,
Expand All @@ -82,38 +75,46 @@ export class LearnController extends BaseController<LearnControllerData> impleme
return this.reply(cmd.context, `Learned command ${key}.`);
}

protected async deleteKeyword(key: string, context: Context): Promise<void> {
protected async deleteKeyword(cmd: Command): Promise<void> {
const key = cmd.getHead('keyword');

const keyword = await this.keywordRepository.findOne({
key,
});
if (!keyword) {
return this.reply(context, `command ${key} does not exist.`);
return this.reply(cmd.context, `command ${key} does not exist.`);
}

await this.keywordRepository.delete(key);
return this.reply(context, `deleted command ${key}.`);
await this.keywordRepository.delete({
id: keyword.id,
key,
});
return this.reply(cmd.context, `deleted command ${key}.`);
}

protected async executeKeyword(key: string, context: Context, body: Array<string>) {
protected async executeKeyword(cmd: Command) {
const body = cmd.getOrDefault('body', []);
const key = cmd.getHead('keyword');

const keyword = await this.keywordRepository.findOne({
key,
});

if (!keyword) {
return this.reply(context, 'missing keyword or command');
return this.reply(cmd.context, 'missing keyword or command');
}

// TODO: merge with saved data before executing
const cmd = new Command({
const merged = new Command({
...keyword,
context,
context: cmd.context,
data: {
[this.data.field]: body,
},
});

this.logger.debug({ cmd, keyword }, 'executing keyword command');
await this.bot.executeCommand(cmd);
this.logger.debug({ cmd, keyword, merged }, 'executing keyword command');
await this.bot.executeCommand(merged);
return;
}
}

0 comments on commit 4a53d4a

Please sign in to comment.