둘째 날: Perl Hubot

저자

@aanoaa - Perl, 콧수염, 야구, 자전거, 낙타, 돌고래, 포청천 마니아. 아이유 열혈 삼촌팬. Perl과 Javascript, 안드로이드 어플리케이션 개발에 능하다. 일신 상의 이유로 Vim을 버리고 Emacs로 투신. 콧수염 블로그를 운영 중. 최근 hubot 모듈 운영에 애정을 쏟고 있다.

시작하며

p5-hubot은 쉽게 확장 가능한 IRC 봇입니다. 하지만 IRC에 국한되지 않고 다양한 프로토콜 환경에서 동작할 수 있습니다. p5-hubot을 소개하고 이를 사용하고 확장하는 방법에 대해 이야기합니다.

p5?

p5는 Perl 5를 뜻합니다. 펄 모듈의 이름은 대문자로 시작하지만, 소스저장소의 이름로 사용할 때에는 다른 프로젝트와 구별하기 위해 p5를 접두어로 붙이곤 합니다.

hubot?

hubot 그림 1. hubot (원본)

hubotgithub에서 만든 채팅용 봇입니다. 어댑터(adapter)와 스크립트(script)를 확장해서 사용할 수 있습니다. CoffeeScript로 작성되어 있고, node.js로 동작합니다.


    adapter                                script
                                        +---------+
                                        |  ascii  |
 +-----------+   +---------++----------+|---------|
 |           |   |         ||          ||  help   |
 | Campfire  | - |         ||          ||---------|
 |           |   |         || Brain    ||  roles  |
 +-----------+   |         || Robot    ||---------|
                 | Adapter || Listener ||  eval   |
                 |         || User     ||---------|
 +-----------+   |         || Message  ||  google |
 |           |   |         || Response ||---------|
 |   IRC     | - |         ||          || standup |
 |           |   |         ||          ||---------|
 +-----------+   +---------++----------+| twitter |
                                        |---------|
                                        |  .....  |
                                        +---------+

위와 같이 어댑터와 스크립트 단이 분리된 구조로 설계되어 있기 때문에 다음의 장점이 있습니다.

p5-hubot?

p5-hubot은 펄로 만든 hubot입니다. CoffeeScript보다 펄에 친숙한 사용자를 위해 만들어졌습니다. 구조를 자세히 살펴봅시다.

Adapter

먼저, 어댑터입니다. Hubot::Adapter는 연계될 서비스와의 인터페이스입니다. 현재 기본으로 제공되는 어댑터는 다음과 같습니다.

따라서 동일한 버전의 p5-hubot은 IRC에서도 구동될 수 있고, 다른 환경에서도 구동될 수 있습니다. 카카오톡, 마이피플 등의 API가 공개되면 새 어댑터를 구현하면 쉽게 p5-hubot을 확장하여 사용할 수 있겠죠?

참고로, 원래 버전의 hubot은 아래와 같은 어댑터가 구현되어 있습니다. 이것을 p5-hubot을 위해 포팅해 보는 것은 어떨까요?

Script

특정 패턴에 대해 반응하여 예약된 작업을 하는 논리적 코드의 집합입니다. 예를 들면, 어댑터가 "hi"라는 텍스트 입력을 보내면 해야 할 작업이 될 것입니다.

$robot->hear(qr/hi/i, sub { shift->send('hello') });

위 코드는 어댑터가 받은 입력이 "hi"라는 텍스트가 정규표현식에 일치하면, "hello"라는 출력을 보내는 코드입니다.

hshong> hi
hubot> hello

이와 같이 다양한 상황의 패턴에 대해 예약된 작업을 작성하여 기능을 확장해 나갈 수 있습니다. 이렇게 편리한 인터페이스를 통해 쉽게 확장할 수 있습니다.

확장

직접 hello라는 스크립트를 만들어 p5-hubot을 확장해 봅시다. 먼저 hello.pm 파일을 생성하고 아래와 같이 작성합니다.

# /path/to/lib/Hubot/Scripts/hello.pm
package Hubot::Scripts::hello;
sub load {
    my ( $class, $robot ) = @_;

    ## robot respond only called its name first. `hubot xxx`
    $robot->respond(
        qr/hi/i,                 # aanoaa> hubot: hi
        sub {
            my $msg = shift;     # Hubot::Response
            $msg->reply('hi');   # hubot> aanoaa: hi
        }
    );

    $robot->hear(
        qr/(hello)/i,    # aanoaa> hello
                         # () 안에 있는건 capture 됨
                         # $msg->match->[0] eq 'hello'
        sub {
            my $msg = shift;
            $msg->send('hello');  # hubot> hello
        }
    );
}

1;

=head1 SYNOPSIS

    hello - say hello
    hubot hi - say hi to sender

=cut

이제 이것을 PERL5LIB 환경변수에 @INC에 등록할 경로를 추가해 사용할 수 있습니다. 아래와 같이 json 포맷으로 구성된 설정파일을 만들면 hubot이 구동될 때 자동으로 스크립트를 불러옵니다.

// hubot-scripts.json
["hello","help"]

이제, 여러분이 작성한 스크립트를 사용할 수 있습니다!

주요 메소드

가장 좋은 방법은 이미 구현되어 있는 스크립트의 소스 코드를 살펴보는 것입니다. tell 스크립트의 구현을 직접 살펴보세요.

설치 및 실행

CPAN을 통해 hubot을 설치합니다.

$ cpanm Hubot

그런 다음 바로 hubot을 입력하면 실행됩니다. 옵션을 지정하지 않으면 Shell 어댑터를 기본으로 사용합니다.

$ hubot
hubot> hubot help
# hubot help - Displays all of the help commands that Hubot knows about
# hubot help <query> - Displays all help commands that match <query>
# hello - say hello
# hubot hi - say hi to sender
Hubot> hello
hello
Hubot> hubot hi
Shell: hi

IRC에 접속하려면 -a irc 옵션을 추가합니다.

# irc 에 접속하시려면..
$ hubot -a irc

직접 만든 모듈을 로드하기 위해서는 PERL5LIB에 해당 모듈 경로를 등록합니다.

$ vim /path/to/lib/MyScript.pm
$ export PERL5LIB=/path/to/lib:$PERL5LIB
$ hubot

정리하며

프리노드의 #perl-kr 채널에는 최신 버전의 p5-hubothongbot이라는 이름으로 동작하고 있습니다. 와서 구경해보시는 것도 좋겠지요. 확장해서 사용하고 싶은데 어려움을 느끼는 분은 채널에 들어오셔서 저에게 메세지를 남겨주세요.

### @freenode #perl-kr
you> hongbot tell hshong 아 이걸 이렇게 저렇게 하고 싶어여.

봇은 이제 그만 만들고 확장 스크립트를 만들어 공유하면 좋겠습니다.

참고

blog comments powered by Disqus