2e20c3e1 |
1 | \input texinfo @c -*- texinfo -*- |
2 | @c %**start of header |
3 | @setfilename bobot++.info |
4 | @settitle Bobot++: A Schemeable IRC Bot |
5 | @setchapternewpage on |
6 | @c %**end of header |
7 | |
8 | @ifinfo |
9 | This file documents Bobot++ by Clinton Ebadi and Etienne Bernard |
10 | (original author, no longer works on program). |
11 | |
12 | Copyright 2002 Clinton Ebadi |
13 | |
14 | Permission is granted to copy, distribute and/or modify this document |
15 | under the terms of the GNU Free Documentation License, Version 1.1 or |
16 | any later version published by the Free Software Foundation; with no |
17 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover |
18 | Texts. |
19 | |
20 | @end ifinfo |
21 | |
22 | @titlepage |
23 | @title Bobot++: A Schemeable IRC Bot |
24 | @author Clinton Ebadi |
25 | |
26 | @page |
91dddabd |
27 | @c @vskip O plus 1filll |
2e20c3e1 |
28 | Copyright @copyright{} 2002 Clinton Ebadi |
29 | |
30 | Permission is granted to copy, distribute and/or modify this document |
31 | under the terms of the GNU Free Documentation License, Version 1.1 or |
32 | any later version published by the Free Software Foundation; with no |
33 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover |
34 | Texts. |
35 | |
36 | @end titlepage |
37 | |
38 | @node Top, Introduction, (dir), (dir) |
39 | @comment node-name, next, previous, up |
40 | |
41 | @ifinfo |
42 | This document describes Bobot++ by Clinton Ebadi and Etienne Bernard |
43 | (original author, no longer works on program). |
44 | |
45 | This document applies to version 2.1.0 of the program named |
46 | Bobot++ |
439869bf |
47 | |
48 | Copyright 2002 Clinton Ebadi |
49 | |
50 | Permission is granted to copy, distribute and/or modify this document |
51 | under the terms of the GNU Free Documentation License, Version 1.1 or |
52 | any later version published by the Free Software Foundation; with no |
53 | Invariant Sections, with no Front-Cover Texts, and with no Back-Cover |
54 | Texts. |
2e20c3e1 |
55 | @end ifinfo |
56 | |
57 | @menu |
58 | * Introduction:: |
31433d27 |
59 | * Configuration:: |
e07b6b46 |
60 | * Using the Bot:: |
31433d27 |
61 | * Scripting:: |
62 | * Concept Index:: |
63 | * Function Index:: |
64 | * Variable Index:: |
2e20c3e1 |
65 | @end menu |
66 | |
31433d27 |
67 | @node Introduction, Configuration, Top, Top |
2e20c3e1 |
68 | @chapter Introduction |
69 | |
31433d27 |
70 | This manual feels abused and neglected because it has almost no |
71 | content. |
72 | |
e07b6b46 |
73 | @node Configuration, Using the Bot, Introduction, Top |
31433d27 |
74 | @chapter Configuration |
75 | |
76 | Bobot++ is easy to configure. The configuration file format may be |
77 | changing in the 2.1 series, so it is not documented for now. See the |
78 | @file{examples} directory for an example configuration. |
79 | |
80 | @menu |
81 | * Configuration File Syntax:: |
82 | * Configure File Placement:: |
83 | @end menu |
84 | |
85 | @node Configuration File Syntax, Configure File Placement, Configuration, Configuration |
86 | @section Configuration File Syntax |
87 | |
88 | Not here yet. |
89 | |
90 | @node Configure File Placement, , Configuration File Syntax, Configuration |
ad529fde |
91 | @section Configuration File Placement |
31433d27 |
92 | |
93 | Bobot++ will look in @file{/etc/bobotpp/default/} for its default |
94 | config if none is specified on the command line. Put the configuration |
ad529fde |
95 | files you want to be loaded by default in this directory. If you are |
96 | not root or you want to have your own personal configration, put it in |
97 | @file{~/.bobotpp/config/default/}. |
31433d27 |
98 | |
e07b6b46 |
99 | @node Using the Bot, Scripting, Configuration, Top |
100 | @chapter Using Bobot++ |
101 | |
102 | FIXME: stuff here... |
103 | |
104 | @menu |
105 | * User Levels:: |
106 | @end menu |
107 | |
108 | @node User Levels, , Using the Bot, Using the Bot |
109 | @section User Levels |
110 | |
111 | There are five levels that a user may be when interfacing with a bot: |
112 | @var{none}, @var{user}, @var{trusted_user}, @var{friend}, |
113 | @var{master}. All users default to @var{none} unless they are changed |
114 | by a script, the @code{!adduser} command or the @file{bot.users} |
115 | file. @var{none} is for everyone---very few commands (e.g. help) are |
116 | available to the users and almost everyone should be this |
117 | level. A @var{user} can execute many of the bot commands, but can't |
118 | use masks on kicks and bans. A @var{trusted} user can everything a |
119 | @var{user} can do, but can also use masks on kicks and bans. A |
120 | @var{friend} can do everything except for stopping the bot (be |
121 | careful who you give this to!). The @var{master} level is for the |
122 | bot's owner (probably you) and can do @emph{everything} to the bot. Be |
123 | @emph{very} careful if you give @var{master} level access to anyone |
124 | else. You cannot use this symbolic levels with the @code{!adduser} |
125 | command. See (FIXME: ref) for the numbers you must use with |
126 | @code{!adduser}. |
127 | |
128 | @node Scripting, Concept Index, Using the Bot, Top |
31433d27 |
129 | @chapter Scripting |
130 | |
131 | Bobot++'s most powerful feature is its scripting system. You write |
132 | scripts using Guile Scheme. This manual does not cover how to use |
ad529fde |
133 | Guile or how to learn Scheme. @xref{Top, , Guile Reference Manual, |
134 | guile, The Guile Reference Manual}, for the Guile reference manual and |
31433d27 |
135 | @url{http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme.html} for |
136 | a good tutorial on Scheme. |
137 | |
439869bf |
138 | Note that in previous versions the scripting commands where in the |
139 | form @code{bot-@var{function}}. They are now in the form |
140 | @code{bot:@var{function}}. The old names are still available, but are |
141 | deprecated and will be removed in Bobot++ 2.4. The command |
142 | @command{perl -pi -e ``s/bot-/bot:/g'' @var{your-files}} should be enough to |
143 | convert your code to use the new functions. |
144 | |
145 | @menu |
146 | * Adding New Commands:: |
147 | * Hooks:: |
e07b6b46 |
148 | * Scheme User Levels:: |
149 | * Sending Messages:: |
91dddabd |
150 | * Misc Scripting Stuff:: |
439869bf |
151 | @end menu |
152 | |
153 | @node Adding New Commands, Hooks, Scripting, Scripting |
154 | @section Adding New Commands |
155 | |
e07b6b46 |
156 | @findex addcommand |
157 | Adding a new command is simple. To register a new command use |
158 | @code{bot:addcommand}. The prototype for @code{bot:addcommand} is |
159 | @code{(bot:addcommand name func needs-channel? num-of-args |
160 | min-level)}. The @code{name} is a string representing the name of the |
161 | command being added. @code{func} is a function accepting |
162 | @code{num-of-args} arguments. @code{needs-channel?} is a bool that is |
163 | true if the function needs the channel name as its first arg, and |
164 | false otherwise. @code{num-of-args} is the number of args @code{func} |
165 | will take and must be within zero (0) and twenty |
166 | (20). @code{min-level} is one of the @ref{Scheme User Levels}. A user must be |
167 | at least a @code{min-level} user to use the new command. None of the |
168 | arguments are guaranteed to be passed; if they aren't they are set to |
169 | the empty string @code{""}. An example of a new command would be: |
fed59248 |
170 | |
171 | @example |
e07b6b46 |
172 | (define (hello channel name) |
fed59248 |
173 | (if (string=? name "") |
e07b6b46 |
174 | (bot:say channel "Hello world!") |
175 | (bot:say channel (string-append "Hello " name "!"))) |
176 | |
177 | (bot:addcommand "hello" hello #t 2 0) |
fed59248 |
178 | @end example |
179 | |
e07b6b46 |
180 | This will display ``Hello World!'' if called as @kbd{!hello} and |
181 | ``Hello World @code{USER}'' if called as @kbd{!hello @var{USER}}. |
182 | |
183 | @node Hooks, Scheme User Levels, Adding New Commands, Scripting |
439869bf |
184 | @section Hooks |
185 | |
e07b6b46 |
186 | @cindex Background on Hooks |
439869bf |
187 | Hooks are a powerful feature of Bobot++. Hooks are a hybrid of ircII |
fed59248 |
188 | and tiny fugue (a MUD bot) hooks with a little bit of extra stuff |
189 | added in. The basic idea of a hook if that you match a text against |
190 | regular expression and call a function if text in a message matches |
191 | that regex. The different types of hooks provided by Bobot++ |
192 | correspond to the different classes of messages that Bobot++ can |
193 | recieve. A Hook also has several properties, including its priority |
194 | and whether or not it is a fallthrough hook. Higher priority hooks are |
195 | executed before lower priority hooks and fallthrough hooks are |
196 | executed before non-fallthrough hooks of the same priority. A |
197 | fallthrough hook can match and processing of hooks will continue; as |
198 | soon as the first non-fallthrough hooks matches processing of hooks |
199 | stops. |
439869bf |
200 | |
201 | @menu |
202 | * Creating a Hook:: |
203 | * Hook Types:: |
204 | @end menu |
205 | |
206 | @node Creating a Hook, Hook Types, Hooks, Hooks |
207 | @subsection Creating a Hook |
208 | |
e07b6b46 |
209 | @findex addhook |
439869bf |
210 | To add a new hook you use the function |
211 | @code{bot:addhook}. @code{bot:addhook} is prototyped as |
fd7440f1 |
212 | @code{(bot:addhook type regex function pri fall name)}. @code{type} |
439869bf |
213 | specifies the type of hook (the types of hooks are listed in @ref{Hook |
214 | Types}). @code{regex} is a standard regular expression. If |
215 | @code{regex} is matched, @code{function} will be |
216 | called. @code{function} will take a different number of args depending |
217 | on the hook type. @code{pri} specifies the priority of the |
e07b6b46 |
218 | hook---higher priority hooks are executed first. This argument is |
439869bf |
219 | optional and defaults to @code{0}. @code{fall} is @code{#t} if the |
220 | hook is a fallthrough hook and @code{#f} is the hook is not a |
fd7440f1 |
221 | fallthrough hook. This arg is also optional and default to |
222 | @code{#t}. @code{name} is the optional name of the hook that defaults |
223 | to ``DEFAULT''. If you set the name then you can have more than one |
224 | hook that matches the same regexp, as long as they have the same |
225 | name. E.g. in a log script you could have the regexps for the log |
226 | function all be @code{".*"} and set their names to @code{"log"} to |
227 | avoid a conflict with other hooks. |
439869bf |
228 | |
229 | @node Hook Types, , Creating a Hook, Hooks |
230 | @subsection Hook Types |
231 | |
232 | Here is a list of the various hooks are notes on each one. The general |
233 | format of a hook is: |
234 | |
235 | @itemize @bullet |
236 | @item |
237 | @code{hooks/name} (this is the Scheme variable name of the hook) |
238 | @itemize @minus |
239 | @item |
240 | Description of the hook |
241 | @item |
fed59248 |
242 | @var{arg1} @var{arg2} ... @var{argn} |
439869bf |
243 | @itemize @minus |
244 | @item |
fed59248 |
245 | @var{arg1}: desc |
439869bf |
246 | @item |
fed59248 |
247 | @var{arg2}: desc |
439869bf |
248 | @item |
249 | ... |
250 | @item |
fed59248 |
251 | @var{argN}: desc |
439869bf |
252 | @end itemize |
253 | @end itemize |
254 | @end itemize |
255 | |
256 | That said, here is the list of available hooks: |
e07b6b46 |
257 | FIXME: write docs |
439869bf |
258 | |
259 | @itemize @bullet |
e07b6b46 |
260 | |
439869bf |
261 | @item |
e07b6b46 |
262 | @vindex hooks/action |
439869bf |
263 | @code{hooks/action} |
264 | @itemize @minus |
265 | @item |
fed59248 |
266 | This hook is triggered when someone performs an action. |
439869bf |
267 | @item |
fed59248 |
268 | @var{from}, @var{to}, @var{action} |
439869bf |
269 | @itemize @minus |
270 | @item |
fed59248 |
271 | @var{from}: this is the address of the person that performed the |
0b7a49e2 |
272 | action in the form @samp{@var{nick} ! @var{user} @@ @var{host}} |
fed59248 |
273 | (without the spaces). |
274 | @item |
275 | @var{to}: This is the target of the action, which is either a channel |
276 | or the Bot's nick. |
277 | @item |
278 | @var{action}: This is the text of the action. E.g. if someone did |
279 | @samp{* foobar does baz}, then @var{action} would be the string |
280 | @code{"does baz"}. |
439869bf |
281 | @end itemize |
282 | @end itemize |
283 | |
439869bf |
284 | @item |
e07b6b46 |
285 | @vindex hooks/nickname |
439869bf |
286 | @code{hooks/nickname} |
287 | @itemize @minus |
288 | @item |
289 | Description of the hook |
290 | @item |
291 | # of args |
292 | @itemize @minus |
293 | @item |
294 | @code{arg1}: desc |
295 | @end itemize |
296 | @end itemize |
297 | |
439869bf |
298 | @item |
e07b6b46 |
299 | @vindex hooks/signoff |
439869bf |
300 | @code{hooks/signoff} |
301 | @itemize @minus |
302 | @item |
303 | Description of the hook |
304 | @item |
305 | # of args |
306 | @itemize @minus |
307 | @item |
308 | @code{arg1}: desc |
309 | @end itemize |
310 | @end itemize |
311 | |
439869bf |
312 | @item |
e07b6b46 |
313 | @vindex hooks/ctcp |
439869bf |
314 | @code{hooks/ctcp} |
315 | @itemize @minus |
316 | @item |
317 | Description of the hook |
318 | @item |
319 | # of args |
320 | @itemize @minus |
321 | @item |
322 | @code{arg1}: desc |
323 | @end itemize |
324 | @end itemize |
325 | |
439869bf |
326 | @item |
e07b6b46 |
327 | @vindex hooks/ctcp-reply |
439869bf |
328 | @code{hooks/ctcp-reply} |
329 | @itemize @minus |
330 | @item |
331 | Description of the hook |
332 | @item |
333 | # of args |
334 | @itemize @minus |
335 | @item |
336 | @code{arg1}: desc |
337 | @end itemize |
338 | @end itemize |
339 | |
439869bf |
340 | @item |
e07b6b46 |
341 | @vindex hooks/disconnect |
439869bf |
342 | @code{hooks/disconnect} |
343 | @itemize @minus |
344 | @item |
345 | Description of the hook |
346 | @item |
347 | # of args |
348 | @itemize @minus |
349 | @item |
350 | @code{arg1}: desc |
351 | @end itemize |
352 | @end itemize |
353 | |
439869bf |
354 | @item |
e07b6b46 |
355 | @vindex hooks/flood |
439869bf |
356 | @code{hooks/flood} |
357 | @itemize @minus |
358 | @item |
359 | Description of the hook |
360 | @item |
361 | # of args |
362 | @itemize @minus |
363 | @item |
364 | @code{arg1}: desc |
365 | @end itemize |
366 | @end itemize |
367 | |
439869bf |
368 | @item |
e07b6b46 |
369 | @vindex hooks/invite |
439869bf |
370 | @code{hooks/invite} |
371 | @itemize @minus |
372 | @item |
373 | Description of the hook |
374 | @item |
375 | # of args |
376 | @itemize @minus |
377 | @item |
378 | @code{arg1}: desc |
379 | @end itemize |
380 | @end itemize |
381 | |
439869bf |
382 | @item |
e07b6b46 |
383 | @vindex hooks/join |
439869bf |
384 | @code{hooks/join} |
385 | @itemize @minus |
386 | @item |
387 | Description of the hook |
388 | @item |
389 | # of args |
390 | @itemize @minus |
391 | @item |
392 | @code{arg1}: desc |
393 | @end itemize |
394 | @end itemize |
395 | |
439869bf |
396 | @item |
e07b6b46 |
397 | @vindex hooks/kick |
439869bf |
398 | @code{hooks/kick} |
399 | @itemize @minus |
400 | @item |
401 | Description of the hook |
402 | @item |
403 | # of args |
404 | @itemize @minus |
405 | @item |
406 | @code{arg1}: desc |
407 | @end itemize |
408 | @end itemize |
409 | |
439869bf |
410 | @item |
e07b6b46 |
411 | @vindex hooks/part |
439869bf |
412 | @code{hooks/part} |
413 | @itemize @minus |
414 | @item |
415 | Description of the hook |
416 | @item |
417 | # of args |
418 | @itemize @minus |
419 | @item |
420 | @code{arg1}: desc |
421 | @end itemize |
422 | @end itemize |
423 | |
439869bf |
424 | @item |
e07b6b46 |
425 | @vindex hooks/mode |
439869bf |
426 | @code{hooks/mode} |
427 | @itemize @minus |
428 | @item |
429 | Description of the hook |
430 | @item |
431 | # of args |
432 | @itemize @minus |
433 | @item |
434 | @code{arg1}: desc |
435 | @end itemize |
436 | @end itemize |
437 | |
439869bf |
438 | @item |
e07b6b46 |
439 | @vindex hooks/message |
439869bf |
440 | @code{hooks/message} |
441 | @itemize @minus |
442 | @item |
443 | Description of the hook |
444 | @item |
445 | # of args |
446 | @itemize @minus |
447 | @item |
448 | @code{arg1}: desc |
449 | @end itemize |
450 | @end itemize |
451 | |
439869bf |
452 | @item |
e07b6b46 |
453 | @vindex hooks/notice |
439869bf |
454 | @code{hooks/notice} |
455 | @itemize @minus |
456 | @item |
457 | Description of the hook |
458 | @item |
459 | # of args |
460 | @itemize @minus |
461 | @item |
462 | @code{arg1}: desc |
463 | @end itemize |
464 | @end itemize |
465 | |
439869bf |
466 | @item |
e07b6b46 |
467 | @vindex hooks/public |
439869bf |
468 | @code{hooks/public} |
469 | @itemize @minus |
470 | @item |
471 | Description of the hook |
472 | @item |
473 | # of args |
474 | @itemize @minus |
475 | @item |
476 | @code{arg1}: desc |
477 | @end itemize |
478 | @end itemize |
479 | |
439869bf |
480 | @item |
e07b6b46 |
481 | @vindex hooks/public-notice |
439869bf |
482 | @code{hooks/public-notice} |
483 | @itemize @minus |
484 | @item |
485 | Description of the hook |
486 | @item |
487 | # of args |
488 | @itemize @minus |
489 | @item |
490 | @code{arg1}: desc |
491 | @end itemize |
492 | @end itemize |
493 | |
439869bf |
494 | @item |
e07b6b46 |
495 | @vindex hooks/raw |
439869bf |
496 | @code{hooks/raw} |
497 | @itemize @minus |
498 | @item |
499 | Description of the hook |
500 | @item |
501 | # of args |
502 | @itemize @minus |
503 | @item |
504 | @code{arg1}: desc |
505 | @end itemize |
506 | @end itemize |
507 | |
439869bf |
508 | @item |
e07b6b46 |
509 | @vindex hooks/timer |
439869bf |
510 | @code{hooks/timer} |
511 | @itemize @minus |
512 | @item |
513 | Description of the hook |
514 | @item |
515 | # of args |
516 | @itemize @minus |
517 | @item |
518 | @code{arg1}: desc |
519 | @end itemize |
520 | @end itemize |
521 | |
439869bf |
522 | @item |
e07b6b46 |
523 | @vindex hooks/topic |
439869bf |
524 | @code{hooks/topic} |
525 | @itemize @minus |
526 | @item |
527 | Description of the hook |
528 | @item |
529 | # of args |
530 | @itemize @minus |
531 | @item |
532 | @code{arg1}: desc |
533 | @end itemize |
534 | @end itemize |
535 | |
0b7a49e2 |
536 | @item |
537 | @vindex hooks/dcc/begin |
538 | @code{hooks/dcc/begin} |
539 | @itemize @minus |
540 | @item |
541 | This hook is triggered when a user begins a DCC CHAT with the bot. |
542 | @item |
543 | @var{FROM} |
544 | @itemize @minus |
545 | @item |
546 | @var{FROM}: This is the user's address in the form |
547 | @samp{nick!user@@host}. |
548 | @end itemize |
549 | @end itemize |
550 | |
551 | @item |
552 | @vindex hooks/dcc/message |
553 | @code{hooks/dcc/message} |
554 | @itemize @minus |
555 | @item |
556 | This hook is triggered when a user sends a message to the bot through |
557 | a DCC CHAT |
558 | @item |
559 | @var{FROM} @var{MESSAGE} |
560 | @itemize @minus |
561 | @item |
562 | @var{FROM}: This is the user's address in the form |
563 | @samp{nick!user@@host}. |
564 | @item |
565 | @var{MESSAGE}: This is the message the user sent to the bot. |
566 | @end itemize |
567 | @end itemize |
439869bf |
568 | @end itemize |
569 | |
570 | |
e07b6b46 |
571 | @node Scheme User Levels, Sending Messages, Hooks, Scripting |
572 | @section Scheme User Levels |
573 | |
574 | @vindex user-none |
575 | @vindex user-user |
576 | @vindex user-trusted |
577 | @vindex user-friend |
578 | @vindex user-master |
579 | There are five levels that a user may be when interfacing with a bot: |
580 | @var{none}, @var{user}, @var{trusted_user}, @var{friend}, |
581 | @var{master}. The Scheme variables for the user levels are |
582 | @code{bot:user-none}, @code{bot:user-user}, @code{bot:user-trusted}, |
583 | @code{bot:user-friend}, and @code{bot:user-master}. See @ref{User |
584 | Levels} for more information on User Levels. |
585 | |
586 | When adding a new command, think about who should be able to use |
587 | it. Is your command a general purpose command that helps the channel |
588 | (e.g. @code{!seen}) that everyone should be able to use? Or is it |
589 | something that should be restricted? See @ref{User Levels} for |
590 | information on what level users can do what with the built in bot |
591 | commands and think about what level a user your command is targetted |
592 | towards. You must be @emph{very} careful when giving new commands to |
593 | lower level users because you can do basically everything the bot can |
594 | do with a script. As the scripting interface becomes more powerful, |
595 | you must think more about what users can use new commands you add. |
596 | |
91dddabd |
597 | @node Sending Messages, Misc Scripting Stuff, Scheme User Levels, Scripting |
e07b6b46 |
598 | @section Sending Messages |
599 | |
600 | There are several types of messages you can send with Bobot++ from |
601 | scripts. There is the simple, but rather limited, @code{bot:say}, |
602 | @code{bot:action} and @code{bot:msg}, and |
603 | the more powerful, but lower level, @code{bot:send-MESSAGE} |
604 | functions. Most bots will probably only need the higher level |
605 | functions, but for the sake of why-not Bobot++ lets you use the lower |
606 | level functions. |
607 | |
608 | @menu |
609 | * High Level Message Functions:: |
610 | * Low Level Message Functions:: |
611 | @end menu |
612 | |
613 | @node High Level Message Functions, Low Level Message Functions, Sending Messages, Sending Messages |
614 | @subsection ``High Level'' Message Functions |
615 | |
616 | ... |
617 | |
618 | @node Low Level Message Functions, , High Level Message Functions, Sending Messages |
619 | @subsection ``Low Level'' Message Functions |
620 | |
621 | The ``Low Level'' messaging functions allow you to do things like send |
622 | CTCP messages. You probably want to read rfc 2812 and the CTCP spec |
623 | before using these. If you have no idea what these do, read rfc 2812 |
624 | (IRC Client Protocol) and CTCP spec. These functions all return |
625 | @code{*unspecified*} always, so don't use the return value for anything. |
626 | |
627 | @itemize @bullet |
628 | |
629 | @item @code{bot:send-CTCP to command message} |
630 | @code{to} is the target of your CTCP message, @code{command} is the |
631 | CTCP command, and @code{message} is the message (or arguments) of the |
632 | command. Make sure to @code{bot:ctcp-quote} the message! |
633 | |
634 | @end itemize |
635 | |
91dddabd |
636 | @node Misc Scripting Stuff, , Sending Messages, Scripting |
637 | @section Misc. Scripting Stuff |
638 | |
639 | These are a few useful things that I thought people writing scripts |
640 | might want to know. |
641 | |
fed59248 |
642 | @vindex exit-hook |
91dddabd |
643 | If you want to execute code when the bot exits, just do |
644 | @code{add-hook! bot:exit-hook @var{thunk}} where @var{thunk} is an |
645 | argumentless procedure (a thunk). When the bot exits your thunk will |
646 | be called. |
647 | |
fed59248 |
648 | @c Since a bot calls hooks on things it says, you have to be careful |
649 | @c about hooks that output text that might match itself. E.g. if you have |
650 | @c a hook that matches @code{"foo"} and the hook displays @code{"foo to |
651 | @c the whatsit?"}, then the hook will call itself over and over until the |
652 | @c stack overflows! To protect against this I wrote the macro |
653 | @c @code{not-from-me}. You call it like this: @code{(not-from-me from |
654 | @c (stmts if not from bot) (stmts if from bot))}. E.g. |
655 | |
656 | @c @example |
657 | @c (bot:addhook hooks/public "foo" |
658 | @c (lambda (f t p) |
659 | @c (not-from-me f ((bot:say t "foo to the what!"))))) |
660 | @c @end example |
661 | |
662 | @c This say ``foo to the what!'' to the channel that ``foo'' was said in |
663 | @c and do nothing otherwise. You can optionally specify an action to be |
664 | @c executed if the message is from the bot: |
665 | |
666 | @c @example |
667 | @c (bot:addhook hooks/public "foo" |
668 | @c (lambda (f t p) |
669 | @c (not-from-me f ((bot:say t "foo to the what!")) |
670 | @c ((bot:say t "moof"))))) |
671 | @c @end example |
672 | |
673 | @c That will do the same thing as the first example, but the bot will |
674 | @c say ``moof'' if it said ``foo'' before. That probably isn't a very |
675 | @c nice thing to do, but it works as an example. You can have as many |
676 | @c staments as you want in the clauses. |
fd7440f1 |
677 | |
31433d27 |
678 | @node Concept Index, Function Index, Scripting, Top |
679 | @unnumbered Concept Index |
680 | @printindex cp |
681 | |
682 | @node Function Index, Variable Index, Concept Index, Top |
683 | @unnumbered Function Index |
684 | @printindex fn |
685 | |
686 | @node Variable Index, , Function Index, Top |
687 | @unnumbered Variable Index |
688 | @printindex vr |
91dddabd |
689 | |
690 | @bye |