Bill Clementson's Blog

Bits and pieces (mostly Lisp-related) that I collect from the ether.

February 2005
Sun Mon Tue Wed Thu Fri Sat
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
Jan  Mar

Minion-bot for AIM

Tuesday, February 15, 2005

I've been meanting to try out John Wiseman's CLAIM package for some time now. CLAIM is a CL package that provides an interface to AOL Instant Messenger (AIM). In order to do something more interesting than just running John's demo programs, I decided to write an Eliza-bot for AIM. There are a number of Eliza implementations available for CL, but I chose to use one that will be familiar to anyone who has visited the #lisp IRC channel - Minion.

Minion is an IRC bot that was written by Brian Mastenbrook (who usually goes by the handle "chandler" on the #lisp IRC channel) and is part of the CL-IRC package (it's in the "example" directory). Minion has a bit of an "attitude" and combines both some useful functionality with an Eliza-like personality.

I combined the CLAIM package with the Eliza-like components of Minion to create an AIM Minion-bot. The following screen shows the result:



To re-create what I did, you will need to:

  1. Download John Wiseman's CLAIM AIM package, Edi Weitz's CL-PPCRE regex package, and the following files from the cl-irc cvs:
    • eliza-rules.lisp
    • mp2eliza.lisp
    Put these two lisp files in a directory called "minion-bot".
  2. Create the following minion-bot.lisp file and put it in the "minion-bot" directory:
    ;;; A version of the Minion IRC bot for AIM, using CLAIM.
    (defpackage :minion-bot (:use :common-lisp :com.lemonodor.claim :eliza) (:export #:start-minion-bot))
    (in-package :minion-bot)
    (defun start-minion-bot (username password) (let ((bot (make-instance 'minion-bot :username username :password password))) (open-aim-connection bot) (unwind-protect (receive-events bot) (close-aim-connection bot))))
    (defclass minion-bot (aim-connection) ((messages :accessor messages :initform '()) (users :accessor users :initform nil)))
    (defmethod handle-im-in ((self minion-bot) user auto-p message) (declare (ignore auto-p)) (format T "~&~A: ~A" user (strip-msg message)) (if (not (member user (users self) :test #'equalp)) (do-send-im self user (format nil "Hi, ~A. I'm a Lisp bot based on the IRC Minion bot. What's up?" user)) (do-send-im self user (format nil "~A" (eliza::print-with-spaces (eliza::flatten (eliza::use-eliza-rules (eliza::read-line-no-punct (strip-msg message)))))))) (pushnew user (users self) :test #'equal))
    (defmethod do-send-im :around ((self minion-bot) user message &key (auto-p)) (declare (ignore user auto-p)) (format T "~&~A: ~A" (aim-connection-username self) message) (call-next-method))
    (defmethod handle-warned ((self minion-bot) warn-level warner) (declare (ignore warn-level)) (do-send-im self warner "I bet that made you feel tough.") (if (zerop (random 2)) (do-warn self warner NIL)))
    (defun strip-msg (msg) (multiple-value-bind (found-p res) (cl-ppcre:scan-to-strings ".*<font .*>(.*)</font></body></html>" msg) (if found-p (aref res 0))))
  3. Create the following ASDF definition minion-bot.asd file and put it in the "minion-bot" directory:
    (in-package #:cl-user)
    (defpackage #:minion-bot-system (:use #:cl #:asdf))
    (in-package #:minion-bot-system)
    (defsystem :minion-bot :name "minion-bot" :author "Bill Clementson" :version "0.1" :licence "MIT" :description "Minion bot for CLAIM" :depends-on (:claim :cl-ppcre) :components ((:file "mp2eliza") (:file "eliza-rules" :depends-on ("mp2eliza")) (:file "minion-bot" :depends-on ("mp2eliza"))))
  4. Make certain the CLAIM, CL-PPCRE, and MINION-BOT directories are all in your asdf:*central-registry* variable and use asdf to build the minion-bot.asd file (it will build the CLAIM and CL-PPCRE dependent libraries as well).
That's it! To use the minion-bot, you will need to first create an AOL IM account for the bot. Then, to start the Minion bot, you execute the following command at the CL repl:
(minion-bot:start-minion-bot "myusername" "mypassword")

emacs Copyright © 2005 by Bill Clementson