원문: http://www.onlamp.com/pub/a/onlamp/2006/06/15/aim-answerbot.html
저자: Robert Treat, 한동훈 역
대단하지 않은 것(The Mosquito Bites)
IRC를 사용해 본 적이 있다면 봇(bot)이라 불리는 프로그램들을 실행해본 경험이 아마도 있을 것이다. 이들 로봇은 보통의 IRC 사용자처럼 보이며, 메시지를 검색하고, 정해진대로 반응한다. IRC에는 온갖 봇들이 있는데, 사소한 역할을 하는 봇, 방문자를 기록하는 봇, 채널 정보나 주제에 대한 FAQ를 제공하는 봇 등이 있다.
(역주: Mosquito bites는 모기 물린 곳을 뜻하며, 다른 의미로는 "대수롭지 않은 것"을 뜻한다.)
freenode의 #postgresql 채널의 봇은 초보자들이 도움을 요청하는 것들에 대한 모든 링크를 저장하고 있다. 또한, 전문가들에게는 필요한 정보가 어디에 있는지 빠르게 알려주는 훌륭한 레퍼런스 역할을 수행한다. 이 봇에 접근하려면 ??와 함께 키워드를 채널에 메시지로 전송하면 된다. 봇은 이 같은 메시지를 발견하면 관련된 URL을 검색하고, 채널에 관련 링크를 전송한다. 그림1은 예제 세션을 나타낸 것이다. IRC에서 많은 시간을 보내게 되면서 이용가능한 봇들에 점점 더 익숙해지게 되었다.
그림1. IRC에 도움을 요청하기
불행히도, 나의 현재 고용주는 IRC에 접속하는 것을 금지하고 있기 때문에 일할 때는 구글이나 pgsql.ru 같은 검색 엔진을 사용하거나 메신저 친구 목록에 있는 사람들을 괴롭히고 있다. 이는 일하는 것처럼 보이긴 하지만 IRC 봇에게 키워드 요청을 보내는 것 보단 훨씬 시간을 소모하는 일이다.
이런 모든 것들이 나를 궁금하게 만들었다. IRC 봇들을 내 메신저(AIM) 목록에 올릴 방법이 뭘까? 메신저를 사용할 수 없는 일터에서도 봇에게 쿼리를 할 수 있고, 사용을 위해 열려 있으며, IRC를 사용하지 않는 내 친구들이 PostgreSQL 관련 정보들도 찾아볼 수 있는 새로운 리소스가 될 수 있지 않을까?
신중한 조사
전에 AIM 봇을 만드는 것에 대해 들은 적이 있었지만, 내 자신의 아이디어로 시작하기엔 장애가 있었다. 이전에 이런 문제를 부딪혔거나 비슷한 문제를 해결한 경우가 있는지 조사해보기 시작했다. 물론, 오라일리의 웹 사이트에서 펄과 아마존 웹 서비스를 사용해서 "
아마존 AIM 봇 만들기"에 대한 기사를 보았다. 이 핵은 나에게 작업을 위한 튼튼한 토대를 제공했으며, 내 아이디어가 실행할 수 있는 것이며, 그리 복잡한 것도 아니라는 사실을 알게 해주었다. 이 기사의 한 가지 단점은 이제는 사용되지 않는 Net::AIM 모듈을 사용한 것이라는 점이다. 대신에, 나는 새로운 Net::OSCAR 모듈을 사용하였다. 펄이 좋은 점은 CPAN 다운로드에서 빠르게 받을 수 있다는 점이다.
AIM 봇의 측면에서는 정확히 AIM 봇이 어떻게 동작하는지 이해해야 한다는 점이다. 다시, 이런 문제에 대한 해결책이 있는지 찾아보았다. 잠깐의 검색을 통해
pg_docbot 프로젝트 홈페이지를 발견했다. 이 홈페이지는 #postgresql에 IRC 봇을 위한 코드를 담고 있었다. 이 사이트는 키워드 정보를 포함한 데이터베이스를 생성하기 위해 사용한 SQL 문장을 모두 제공하고 있었으며, 이는 나만의 AIM 봇에 대한 아이디어를 제공했다. 이제, 이 조각들을 하나로 합칠 때가 된 셈이었다.
핵심을 만들기
pg_docbot 프로젝트의 실제 스키마는 내가 필요하다고 생각한 것보다 훨씬 더 정교하게 되어 있었다. 때문에, 나는 보다 단순화된 버전의 데이터베이스 스키마를 사용하였다.
CREATE TABLE urls (
url_id serial PRIMARY KEY NOT NULL,
url text UNIQUE NOT NULL
);
CREATE TABLE keywords (
keyword text PRIMARY KEY NOT NULL,
url_id integer NOT NULL REFERENCES urls(url_id)
ON DELETE CASCADE
);
CREATE VIEW keylist AS
SELECT keyword, url
FROM keywords JOIN urls USING (url_id);
기본적으로 정보는 두 개의 테이블에 있다. urls 테이블은 시스템에 있는 다른 URL을 모두 저장한다. keywords 테이블은 urls 테이블에서 URL과 일치하는 키워드들을 담고 있다. 이런 식으로 테이블을 나누어 놓은 이유는 하나의 URL이 여러 개의 키워드와 연결될 수 있기 때문이다. 예를 들어, 솔라리스에서 PostgreSQL을 설치하는 방법에 대한 가이드를 썼다면, 이 기사에 대한 키워드로 install, solaris 등으로 붙일 수 있다. URL과 키워드를 분리하는 것은 데이터에 약간의 정규화가 필요하지만, 저장소와 유지보수를 훨씬 쉽게 만들어 준다.
다시 말하지만, 나는 가능한한 단순하게 데이터에 대한 쿼리를 원했기 때문에, 이들 두 테이블을 합한 keywordlist 뷰를 만들었다. 이제, 코드는 뷰를 이용하기만 하면 되며, 쿼리와 결과는 매우 직관적이 될 것이다. 다행히도, docbot 프로젝트에서 데이터의 사본을 얻을 수 있었기 때문에 내 데이터베이스에 이를 임포트하기만 하면 되었다. 만약, 자신만의 시스템을 구축하고 싶다면, 어떤 정보를 표시할 것이고, 데이터베이스에 추가할 것인지를 결정해야 한다.
봇 만들기
데이터베이스가 준비되었으면, 이젠 봇을 만들 차례다. 코드는 aimbot.pl을 복사한 것이며, 기본적으로 AIM 서비스에 로그인을 하는 부분과 om_im 이벤트가 발생하기를 기다리는 부분, 그리고, 데이터베이스에 쿼리를 보내고 결과를 받기 위해 펄의
DBI 모듈을 사용하는 것으로 구성되어 있다.
#!/usr/bin/perl
use warnings;
use strict;
use Net::OSCAR qw(:standard);
use DBI;
# Config
my $screenname = "rtfmbot";
my $password = "secreto";
my $dbconn = "host=localhost dbname=docbot";
my $dbuser = "rtfmbot";
my $dbpasswd = "secreto"
my $oscar;
$oscar = Net::OSCAR->new();
$oscar->set_callback_im_in(&im_in);
$oscar->signon($screenname, $password);
while(1)
{
$oscar->do_one_loop();
# do stuff here
}
sub im_in {
my($oscar, $sender, $message, $is_away) = @_;
print "[AWAY] " if $is_away;
print "$sender: $message
";
# Some AIM clients send HTML, we need
# to convert it to plain text
$message =~ s/<(.|
)+?>//g;
my $key = $message;
my $dbh = DBI->connect("dbi:Pg:$dbconn","$dbuser","$dbpasswd);
my $SQL = "SELECT url FROM keylist WHERE keyword = ?";
my $sth = $dbh->prepare_cached($SQL);
$sth->execute($key);
if ($sth->rows == 0)
{
$oscar->send_im($sender,"nothing found :-(");
}
else
{
my $url;
$sth->bind_columns(undef,$url);
while( $sth->fetch() )
{
$oscar->send_im($sender,$url);
}
}
$sth->finish();
$dbh->disconnect();
}
시연하기
이제, 모든 준비가 되었다. 명령줄에서 "perl rtfmbot.pl"을 입력해서 봇을 시작할 수 있다. 일단, 이렇게 하고 나면 AIM에 로그인을 하고, 친구 목록의 다른 사람들처럼 대화할 수 있다.(그림2)
그림2. rtfmbot의 사용
GRANT 명령의 문법에 대한 도움이 필요한가? 문제 없다. 초보자가 윈도우에 PostgreSQL을 사용하는 것에 대해 알고 싶다고? 오케이. PostgreSQL 복제에 대한 정보 검색이 필요하다고? 여기 참조할만한 링크들이 있다.
로그아웃 하기
이제, 이런 봇이 어떻게 당신의 조직에 도움이 되는지 궁금할 것이다. 이는 새로운 종업원에게는 간편한 레퍼런스 역할을 하며, 기존의 종업원들에게는 레퍼런스를 제공할 것이다. 좀 더 깊이 살펴보면, 여기서 제공하는 쉘은 실제로 어떤 데이터베이스에도 연결할 수 있고, 회사에 관한 어떤 정보도 제공할 수 있다는 것을 알 수 있을 것이다. "holidays"라는 키워드에 대해 여러분의 docbot은 회사의 공식 휴뮤일에 대한 정보를 제공할 수 있을 것이다. 이는 꽤 편리한 물건이며, 다른 어떤 것들을 합쳐도 이만큼의 편의를 제공하지 못한다.
이 정보를 AOL의 네트워크를 통해 제공하는 것도 가치있을 것이며, 이런 경우에는 민감한 정보를 제공하지 않아야하며, 일반적인 정보 또는 상점 운영 시간, 고객 지원 전화 번호, 제품 정보 같이 고객들이 접근할 수 있는 정보만 제공해야 한다.
만약, 보다 강력한 개인보호 기능이 필요하다면, 자신만의
재버 서버를 운영하는 것이 좋을 것이다.
또한, 참고할만한 링크는
AOL의 봇 홈페이지다. 자신만의 봇을 만들 생각이 있다면, 내가 사용했던 리소스들을 추천한다.