-
Notifications
You must be signed in to change notification settings - Fork 8
/
alarmBot.ts
156 lines (127 loc) · 4.36 KB
/
alarmBot.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { MemoryStorage, ConsoleAdapter } from 'botbuilder';
import { Topic, TextPrompt, prettyConsole, WSTelemetry, consoleOnTurn, doTopic } from '../src/topical';
import { SimpleForm, SimpleFormSchema } from './SimpleForm';
interface Alarm {
name: string;
when: string;
}
const listAlarms = (alarms: Alarm[]) => alarms
.map(alarm => `* "${alarm.name}" set for ${alarm.when}`)
.join('\n');
class ShowAlarms extends Topic<Alarm[]> {
async onStart (
args: Alarm[],
) {
if (args.length === 0)
await this.send(`You haven't set any alarms.`);
else
await this.send(`You have the following alarms set:\n${listAlarms(args)}`);
await this.end();
}
}
ShowAlarms.register();
interface DeleteAlarmState {
alarms: Alarm[];
alarmName: string;
child: string;
}
class DeleteAlarm extends Topic<Alarm[], DeleteAlarmState, string> {
async onStart (
args: Alarm[],
) {
if (args.length === 0) {
await this.send(`You don't have any alarms.`);
await this.end();
return;
}
this.state.alarms = args;
await this.startChild(TextPrompt, {
name: 'whichAlarm',
prompt: `Which alarm do you want to delete?\n${listAlarms(this.state.alarms)}`,
});
}
async onDispatch () {
await this.dispatchToChild();
}
async onChildEnd(
child: TextPrompt,
) {
switch (child.return!.args!.name) {
case 'whichAlarm':
this.state.alarmName = child.return!.result.value!;
await this.startChild(TextPrompt, {
name: 'confirm',
prompt: `Are you sure you want to delete alarm "${child.return!.result.value}"? (yes/no)"`,
});
break;
case 'confirm':
await this.end(child.return!.result.value === 'yes'
? this.state.alarmName
: undefined
)
break;
default:
throw `unknown prompt name ${child.return!.args!.name}`;
}
}
}
DeleteAlarm.register();
interface AlarmBotState {
alarms: Alarm[];
}
const helpText = `I know how to set, show, and delete alarms.`;
class AlarmBot extends Topic<any, AlarmBotState> {
async onStart () {
await this.send(`Welcome to Alarm Bot!\n${helpText}`);
this.state.alarms = [];
}
async onDispatch () {
if (await this.dispatchToChild())
return;
if (this.text) {
if (/set|add|create/i.test(this.text)) {
await this.startChild(SimpleForm, {
name: {
type: 'string',
prompt: 'What do you want to call it?',
},
when: {
type: 'string',
prompt: 'For when do you want to set it?',
},
} as SimpleFormSchema);
} else if (/show|list/i.test(this.text)) {
await this.startChild(ShowAlarms, this.state.alarms);
} else if (/delete|remove/i.test(this.text)) {
await this.startChild(DeleteAlarm, this.state.alarms);
} else {
await this.send(helpText);
}
}
}
async onChildEnd(
child: Topic,
) {
if (child instanceof SimpleForm) {
this.state.alarms.push({ ... child.return! } as any as Alarm);
await this.send(`Alarm successfully added!`);
} else if (child instanceof DeleteAlarm) {
if (child.return) {
this.state.alarms = this.state.alarms
.filter(alarm => alarm.name !== child.return!);
await this.send(`Alarm "${child.return!}" has been deleted.`)
} else {
await this.send(`Okay, the status quo has been preserved.`)
}
} else if (!(child instanceof ShowAlarms)) {
throw `unexpected child topic`;
}
}
}
AlarmBot.register();
// const wst = new WSTelemetry('ws://localhost:8080/server');
// Topic.telemetry = action => wst.send(action);
Topic.init(new MemoryStorage());
const adapter = new ConsoleAdapter()
.use(prettyConsole);
consoleOnTurn(adapter, context => doTopic(AlarmBot, context));