OSDN Git Service

split libraries
authorISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
Thu, 25 Oct 2012 09:41:18 +0000 (18:41 +0900)
committerISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
Thu, 25 Oct 2012 09:41:18 +0000 (18:41 +0900)
lib/Mubot4FB.pm [new file with mode: 0644]
lib/Mubot4FB/DB.pm [new file with mode: 0644]
lib/Mubot4FB/FB.pm [new file with mode: 0644]
mubot4fb.pl

diff --git a/lib/Mubot4FB.pm b/lib/Mubot4FB.pm
new file mode 100644 (file)
index 0000000..0b3cf67
--- /dev/null
@@ -0,0 +1,182 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2012 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
+# This program is covered by the GNU General Public License 2
+#
+package Mubot4FB;
+
+use strict;
+use utf8;
+
+use base 'Bot::BasicBot';
+use POSIX 'strftime';
+
+use Mubot4FB::DB;
+use Mubot4FB::FB;
+
+use Data::Dumper;
+
+my $mu_re = qr/^([^\s]+)\s+((?:https?|ftps?):\/\/[^\s]+)\s+(.+)$/i;
+my $irc_type = 1;
+
+sub misc_init {
+       my ($me) = @_;
+
+       $me->{last_search} = {};
+}
+
+sub init {
+       my ($me) = @_;
+       $me->{fb} = Mubot4FB::FB->new($me->{cfg});
+       $me->{db} = Mubot4FB::DB->new($me->{cfg});
+       $me->misc_init;
+       return 1;
+}
+
+sub _format_submit {
+       my ($me, $e) = @_;
+
+       return $e->{submitter}.'が『'.$e->{prefix}.' '.$e->{uri}.' '.$e->{comment}.'』と'.strftime('%Y-%m-%d %H:%M:%S', localtime($e->{post_time}));
+}
+
+sub _response {
+       my ($me, $args, $msg) = @_;
+
+       $me->say(channel => $args->{channel},
+                body => $msg);
+}
+
+sub _add {
+       my ($me, $args)  =@_;
+       my ($resp, $resp_msg);
+
+       if ($args->{body} =~ /$mu_re/) {
+               my $prefix = $1;
+               my $uri = $2;
+               my $comment = $3;
+               my $text = $args->{who} . '曰く、'.$prefix.' '.$comment;
+
+               if (my $res = $me->{db}->check_dup({uri =>$uri})) {
+                       if ($res->{post_time} < time() - 7 * 24 * 60 * 60) {
+                               $resp_msg = 'だいぶ前 '.$me->_format_submit($res).'にいってたにゃー '.$me->{fb}->post_uri($res->{fb_post_id});
+                       } else {
+                               $resp_msg = '既に '.$me->_format_submit($res).'に言ってますよ? '.$me->{fb}->post_uri($res->{fb_post_id});
+                       }
+               } else {
+                       my $post_ok = 1;
+                       eval{$resp = $me->{fb}->publish($text, $uri)};
+                       if ($@) {
+                               $me->{fb}->init();
+                               eval{$resp = $me->{fb}->publish($text, $uri)};
+                               $post_ok = 0 if ($@);
+                       }
+
+                       if ($post_ok) {
+                               my (undef, $post_id) = split(/_/, $resp->{id});
+                               $me->{db}->add({submitter => $args->{who},
+                                               fb_post_id => $post_id,
+                                               uri => $uri,
+                                               prefix => $prefix,
+                                               comment => $comment});
+                               $resp_msg = $args->{who} . ': うい  '.$me->{fb}->post_uri($post_id).' で登録';
+                       } else {
+                               $resp_msg = 'can not post to facebook';
+                       }
+               }
+               return $resp_msg;
+       }
+       return 0;
+}
+
+sub _remove_prev {
+       my ($me, $args) = @_;
+
+       my $last_post = $me->{db}->search_lastpost_by_submitter({who => $args->{who}});
+
+       if (!defined $last_post) {
+               return $args->{who}.': いまのっていつの? というか ないし';
+       } elsif ($last_post->{post_time} < time() - 3600) {
+               return $args->{who}.': いまのっていつの? 最後のはこれだけど古いんだにゃ ' . $me->{fb}->post_uri($last_post->{fb_post_id});
+       } else {
+               return $me->_remove($args, $last_post->{'fb_post_id'});
+       }
+}
+
+sub _remove {
+       my ($me, $args, $post_id)  =@_;
+       my ($resp_msg, $resp);
+
+       $me->{db}->begin;
+       if ($resp = $me->{db}->remove({fb_post_id => $post_id, submitter => $args->{who}})) {
+               # fb 側のエントリを削除しないといけない
+               if ($me->{fb}->remove($post_id)) {
+                       $me->{db}->commit;
+                       $resp_msg = $args->{who} . ': 削除しました ' . $me->{fb}->post_uri($post_id);
+               } else {
+                       $me->{db}->rollback;
+                       $resp_msg = $args->{who} . ': 削除に失敗しましたよ? ' . $me->{fb}->post_uri($post_id);
+               }
+       } else {
+               $me->{db}->rollback;
+               $resp_msg = $args->{who} . ': そんな投稿ないよ? ' . $me->{fb}->post_uri($post_id);
+       }
+       return $resp_msg;
+}
+
+sub _search_start {
+       my ($me, $args)  = @_;
+
+       if ($args->{body} =~ /^ふみくん\s+(.+)\?\s*$/) {
+               $me->{last_search}->{$args->{who}} = undef;
+               $me->{last_search}->{$args->{who}} = $me->{db}->search_by_word({word => $1});
+               return $me->_search_next($args);
+       }
+}
+
+sub _search_next {
+       my ($me, $args)  = @_;
+
+       my $resp_msg = 'ないっす';
+       if (defined $me->{last_search}->{$args->{who}}) {
+               my $ent = pop($me->{last_search}->{$args->{who}});
+               if ($ent) {
+                       my $count = @{$me->{last_search}->{$args->{who}}};
+                       if ($count) {
+                       }
+                       $resp_msg = $args->{who} . ': ' . $me->_format_submit($ent).'に言ってた '.($count ? '[ほか'.$count.'件] ' : '[ほかにはもうないよ] ').$me->{fb}->post_uri($ent->{fb_post_id});
+               }
+       }
+       return $resp_msg;
+}
+
+sub _not_yet {
+       return 'まだ実装してないです';
+}
+
+sub said {
+       my ($me, $args) = @_;
+       my $resp_msg;
+
+       if ($args->{body} =~ /$mu_re/) {
+               $resp_msg = $me->_add($args) unless ($1 eq 'deb');
+       } elsif ($args->{body} =~ /^ふみくん\s+(.+)\s*$/) {
+               my $cmd = $1;
+               if ($cmd eq 'いまのなし') {
+                       $resp_msg = $me->_remove_prev($args);
+               } elsif ($cmd =~ /削除\s+(?:$me->{cfg}->{fb_page_url}\/posts\/)?([0-9]+)$/) {
+                       $resp_msg = $me->_remove($args, $1);
+               } elsif ($cmd =~ /\?$/) {
+                       $resp_msg = $me->_search_start($args);
+               } elsif ($cmd =~ /つぎ/) {
+                       $resp_msg = $me->_search_next($args);
+               } elsif ($cmd =~ /どこ/) {
+                       $resp_msg = $args->{who}.': ここ ' . $me->{cfg}->{fb_page_url};
+               } else {
+                       $resp_msg = $args->{who}.': ん? (' . strftime('%Y-%m-%d %H:%M:%S', localtime) . ')';
+               }
+       }
+
+       $me->_response($args, $resp_msg) if ($resp_msg);
+}
+
+1;
diff --git a/lib/Mubot4FB/DB.pm b/lib/Mubot4FB/DB.pm
new file mode 100644 (file)
index 0000000..7be7acd
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2012 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
+# This program is covered by the GNU General Public License 2
+#
+package Mubot4FB::DB;
+use strict;
+use utf8;
+
+use DBI qw/:sql_types/;
+
+use Data::Dumper;
+
+sub new {
+       my $proto = shift;
+       my $class = ref $proto || $proto;
+       my $self = {cfg => shift};
+       bless $self, $class;
+
+       $self->init();
+       return $self;
+}
+
+sub init {
+       my ($me) = @_;
+       return $me->{dbh} = DBI->connect('DBI:mysql:'.$me->{cfg}->{database}, $me->{cfg}->{db_user}, $me->{cfg}->{db_pass},{mysql_enable_utf8 => 1, mysql_auto_reconnect => 1}) || die $DBI::errstr;
+}
+
+sub check_dup {
+       my ($me, $db_args) = @_;
+       my $sth = $me->{dbh}->prepare('select * from posts where uri = ? order by post_time desc limit 1');
+       my $rv = $sth->execute($db_args->{uri});
+       my $ret = $sth->fetchrow_hashref;
+
+       $sth->finish;
+       return $ret;
+}
+
+sub add {
+       my ($me, $db_args) = @_;
+
+       my ($scheme, $path) = split(/:\/\//, $db_args->{uri});
+       my $sth = $me->{dbh}->prepare("insert into posts (submitter, fb_post_id, uri, prefix, comment, scheme, path, post_time) values (?, ?, ?, ?, ?, ?, ?, ?)");
+       $sth->bind_param(1, $db_args->{submitter}, SQL_VARCHAR);
+       $sth->bind_param(2, $db_args->{fb_post_id}, SQL_BIGINT);
+       $sth->bind_param(3, $db_args->{uri}, SQL_VARCHAR);
+       $sth->bind_param(4, $db_args->{prefix}, SQL_VARCHAR);
+       $sth->bind_param(5, $db_args->{comment}, SQL_VARCHAR);
+       $sth->bind_param(6, $scheme, SQL_VARCHAR);
+       $sth->bind_param(7, $path, SQL_VARCHAR);
+       $sth->bind_param(8, time, SQL_BIGINT);
+       my $rv = $sth->execute();
+       $sth->finish;
+
+       return $rv;
+}
+
+sub remove {
+       my ($me, $db_args) = @_;
+       $db_args->{submitter_type} ||= 1;
+
+       my $sth = $me->{dbh}->prepare("delete from posts where fb_post_id = ? and submitter = ? and submitter_type = ?");
+
+       $sth->bind_param(1, $db_args->{fb_post_id}, SQL_BIGINT);
+       $sth->bind_param(2, $db_args->{submitter}, SQL_VARCHAR);
+       $sth->bind_param(3, $db_args->{submitter_type}, SQL_INTEGER);
+       my $rv = $sth->execute();
+       my $ret = $rv ? $sth->rows : 0;
+
+       $sth->finish;
+
+       return $ret;
+}
+
+sub search_by_word {
+       my ($me, $db_args) = @_;
+
+       my $column = $db_args->{word} =~ /:\/\// ? 'uri' : 'path';
+       my $w = '%' . $db_args->{word} . '%';
+       my $sth = $me->{dbh}->prepare('select * from posts where prefix like ? or '.$column.' like ? or comment like ? order by post_time desc limit 1000');
+       $sth->bind_param(1, $w, SQL_VARCHAR);
+       $sth->bind_param(2, $w, SQL_VARCHAR);
+       $sth->bind_param(3, $w, SQL_VARCHAR);
+       $sth->execute();
+
+       my $ret = $sth->fetchall_arrayref({});
+       $sth->finish;
+
+       return $ret;
+}
+
+sub search_lastpost_by_submitter {
+       my ($me, $db_args) = @_;
+
+       my $sth = $me->{dbh}->prepare('select * from posts where submitter = ? order by post_time desc limit 1');
+       $sth->bind_param(1, $db_args->{who}, SQL_VARCHAR);
+       $sth->execute();
+
+       my $ret = $sth->fetchrow_hashref();
+       $sth->finish;
+
+       return $ret;
+}
+
+sub commit {
+       my ($me) = @_;
+       $me->{dbh}->commit;
+}
+
+sub rollback {
+       my ($me) = @_;
+       $me->{dbh}->rollback;
+}
+
+sub begin {
+       my ($me) = @_;
+       $me->{dbh}->begin_work;
+}
+
+1;
diff --git a/lib/Mubot4FB/FB.pm b/lib/Mubot4FB/FB.pm
new file mode 100644 (file)
index 0000000..185f0b2
--- /dev/null
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2012 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
+# This program is covered by the GNU General Public License 2
+#
+package Mubot4FB::FB;
+use strict;
+use utf8;
+
+use Facebook::Graph;
+use LWP::UserAgent;
+use HTTP::Request::Common;
+
+use Data::Dumper;
+
+sub new {
+       my $proto = shift;
+       my $class = ref $proto || $proto;
+       my $self = {cfg => shift};
+       bless $self, $class;
+
+       $self->init();
+       return $self;
+}
+
+sub init {
+       my ($me) = @_;
+       my $fb = Facebook::Graph->new(app_id   => $me->{cfg}->{fb_app_id},
+                                     secret   => $me->{cfg}->{fb_app_secret},
+                                     postback => $me->{cfg}->{fb_postback_url});
+
+       my $res_token = $fb->request_access_token($me->{cfg}->{fb_access_code});
+       die 'token get error' if (!defined $res_token || !$res_token->response->is_success);
+
+       my $acts = $fb->fetch('me/accounts');
+       die 'can not get account list' if(!defined $acts || !$acts);
+
+       my $page_access_token = '';
+       foreach my $d (@{$acts->{data}}) {
+               if ($d->{id} eq $me->{cfg}->{fb_page_id}) {
+                       $page_access_token = $d->{'access_token'};
+               }
+       }
+       die 'can not get access tokenfor page_id=' . $me->{cfg}->{fb_page_id} if ($page_access_token eq '');
+
+       return $me->{fbo} = Facebook::Graph->new(access_token => $page_access_token);
+}
+
+sub publish {
+       my ($me, $text, $uri) = @_;
+
+       return $me->{fbo}->add_post($me->{cfg}->{fb_page_id})
+           ->set_message($text)
+           ->set_link_uri($uri)
+           ->publish()
+           ->as_hashref();
+}
+
+sub post_uri {
+       my ($me, $post_id) = @_;
+
+       return $me->{cfg}->{fb_page_url} . '/posts/' . $post_id;
+}
+
+sub remove {
+       my ($me, $post_id) = @_;
+
+       my $uri = $me->{fbo}->query->find($me->{cfg}->{fb_page_id}.'_'.$post_id)->uri_as_string;
+       my $req = HTTP::Request::Common::DELETE($uri);
+       warn Dumper($req) if ($me->{cfg}->{debug});
+       my $resp;
+       $resp = LWP::UserAgent->new->request($req);
+       warn Dumper($resp) if ($me->{cfg}->{debug});
+       if ($resp->is_success && $resp->code == 200 && $resp->content eq 'true') {
+               return 1;
+       } else {
+               warn 'DELETE ERROR: http code: ' . $resp->code() . ' , http content: ' . $resp->content;
+               return 0;
+       }
+}
+
+1;
index 82bfc56..1ca9e95 100755 (executable)
@@ -3,373 +3,6 @@
 # Copyright (c) 2012 ISHIKAWA Mutsumi <ishikawa@hanzubon.jp>
 # This program is covered by the GNU General Public License 2
 #
-package Mubot4FB::FB;
-use strict;
-use utf8;
-
-use Facebook::Graph;
-use LWP::UserAgent;
-use HTTP::Request::Common;
-
-use Data::Dumper;
-
-sub new {
-       my $proto = shift;
-       my $class = ref $proto || $proto;
-       my $self = {cfg => shift};
-       bless $self, $class;
-
-       $self->init();
-       return $self;
-}
-
-sub init {
-       my ($me) = @_;
-       my $fb = Facebook::Graph->new(app_id   => $me->{cfg}->{fb_app_id},
-                                     secret   => $me->{cfg}->{fb_app_secret},
-                                     postback => $me->{cfg}->{fb_postback_url});
-
-       my $res_token = $fb->request_access_token($me->{cfg}->{fb_access_code});
-       die 'token get error' if (!defined $res_token || !$res_token->response->is_success);
-
-       my $acts = $fb->fetch('me/accounts');
-       die 'can not get account list' if(!defined $acts || !$acts);
-
-       my $page_access_token = '';
-       foreach my $d (@{$acts->{data}}) {
-               if ($d->{id} eq $me->{cfg}->{fb_page_id}) {
-                       $page_access_token = $d->{'access_token'};
-               }
-       }
-       die 'can not get access tokenfor page_id=' . $me->{cfg}->{fb_page_id} if ($page_access_token eq '');
-
-       return $me->{fbo} = Facebook::Graph->new(access_token => $page_access_token);
-}
-
-sub publish {
-       my ($me, $text, $uri) = @_;
-
-       return $me->{fbo}->add_post($me->{cfg}->{fb_page_id})
-           ->set_message($text)
-           ->set_link_uri($uri)
-           ->publish()
-           ->as_hashref();
-}
-
-sub post_uri {
-       my ($me, $post_id) = @_;
-
-       return $me->{cfg}->{fb_page_url} . '/posts/' . $post_id;
-}
-
-sub remove {
-       my ($me, $post_id) = @_;
-
-       my $uri = $me->{fbo}->query->find($me->{cfg}->{fb_page_id}.'_'.$post_id)->uri_as_string;
-       my $req = HTTP::Request::Common::DELETE($uri);
-       warn Dumper($req) if ($me->{cfg}->{debug});
-       my $resp;
-       $resp = LWP::UserAgent->new->request($req);
-       warn Dumper($resp) if ($me->{cfg}->{debug});
-       if ($resp->is_success && $resp->code == 200 && $resp->content eq 'true') {
-               return 1;
-       } else {
-               warn 'DELETE ERROR: http code: ' . $resp->code() . ' , http content: ' . $resp->content;
-               return 0;
-       }
-}
-
-1;
-
-package Mubot4FB::DB;
-use strict;
-use utf8;
-
-use DBI qw/:sql_types/;
-
-use Data::Dumper;
-
-sub new {
-       my $proto = shift;
-       my $class = ref $proto || $proto;
-       my $self = {cfg => shift};
-       bless $self, $class;
-
-       $self->init();
-       return $self;
-}
-
-sub init {
-       my ($me) = @_;
-       return $me->{dbh} = DBI->connect('DBI:mysql:'.$me->{cfg}->{database}, $me->{cfg}->{db_user}, $me->{cfg}->{db_pass},{mysql_enable_utf8 => 1, mysql_auto_reconnect => 1}) || die $DBI::errstr;
-}
-
-sub check_dup {
-       my ($me, $db_args) = @_;
-       my $sth = $me->{dbh}->prepare('select * from posts where uri = ? order by post_time desc limit 1');
-       my $rv = $sth->execute($db_args->{uri});
-       my $ret = $sth->fetchrow_hashref;
-
-       $sth->finish;
-       return $ret;
-}
-
-sub add {
-       my ($me, $db_args) = @_;
-
-       my ($scheme, $path) = split(/:\/\//, $db_args->{uri});
-       my $sth = $me->{dbh}->prepare("insert into posts (submitter, fb_post_id, uri, prefix, comment, scheme, path, post_time) values (?, ?, ?, ?, ?, ?, ?, ?)");
-       $sth->bind_param(1, $db_args->{submitter}, SQL_VARCHAR);
-       $sth->bind_param(2, $db_args->{fb_post_id}, SQL_BIGINT);
-       $sth->bind_param(3, $db_args->{uri}, SQL_VARCHAR);
-       $sth->bind_param(4, $db_args->{prefix}, SQL_VARCHAR);
-       $sth->bind_param(5, $db_args->{comment}, SQL_VARCHAR);
-       $sth->bind_param(6, $scheme, SQL_VARCHAR);
-       $sth->bind_param(7, $path, SQL_VARCHAR);
-       $sth->bind_param(8, time, SQL_BIGINT);
-       my $rv = $sth->execute();
-       $sth->finish;
-
-       return $rv;
-}
-
-sub remove {
-       my ($me, $db_args) = @_;
-       $db_args->{submitter_type} ||= 1;
-
-       my $sth = $me->{dbh}->prepare("delete from posts where fb_post_id = ? and submitter = ? and submitter_type = ?");
-
-       $sth->bind_param(1, $db_args->{fb_post_id}, SQL_BIGINT);
-       $sth->bind_param(2, $db_args->{submitter}, SQL_VARCHAR);
-       $sth->bind_param(3, $db_args->{submitter_type}, SQL_INTEGER);
-       my $rv = $sth->execute();
-       my $ret = $rv ? $sth->rows : 0;
-
-       $sth->finish;
-
-       return $ret;
-}
-
-sub search_by_word {
-       my ($me, $db_args) = @_;
-
-       my $column = $db_args->{word} =~ /:\/\// ? 'uri' : 'path';
-       my $w = '%' . $db_args->{word} . '%';
-       my $sth = $me->{dbh}->prepare('select * from posts where prefix like ? or '.$column.' like ? or comment like ? order by post_time desc limit 1000');
-       $sth->bind_param(1, $w, SQL_VARCHAR);
-       $sth->bind_param(2, $w, SQL_VARCHAR);
-       $sth->bind_param(3, $w, SQL_VARCHAR);
-       $sth->execute();
-
-       my $ret = $sth->fetchall_arrayref({});
-       $sth->finish;
-
-       return $ret;
-}
-
-sub search_lastpost_by_submitter {
-       my ($me, $db_args) = @_;
-
-       my $sth = $me->{dbh}->prepare('select * from posts where submitter = ? order by post_time desc limit 1');
-       $sth->bind_param(1, $db_args->{who}, SQL_VARCHAR);
-       $sth->execute();
-
-       my $ret = $sth->fetchrow_hashref();
-       $sth->finish;
-
-       return $ret;
-}
-
-sub commit {
-       my ($me) = @_;
-       $me->{dbh}->commit;
-}
-
-sub rollback {
-       my ($me) = @_;
-       $me->{dbh}->rollback;
-}
-
-sub begin {
-       my ($me) = @_;
-       $me->{dbh}->begin_work;
-}
-
-1;
-package Mubot4FB;
-
-use strict;
-use utf8;
-
-use base 'Bot::BasicBot';
-use POSIX 'strftime';
-
-use Data::Dumper;
-
-my $mu_re = qr/^([^\s]+)\s+((?:https?|ftps?):\/\/[^\s]+)\s+(.+)$/i;
-my $irc_type = 1;
-
-sub misc_init {
-       my ($me) = @_;
-
-       $me->{last_search} = {};
-}
-
-sub init {
-       my ($me) = @_;
-       $me->{fb} = Mubot4FB::FB->new($me->{cfg});
-       $me->{db} = Mubot4FB::DB->new($me->{cfg});
-       $me->misc_init;
-       return 1;
-}
-
-sub _format_submit {
-       my ($me, $e) = @_;
-
-       return $e->{submitter}.'が『'.$e->{prefix}.' '.$e->{uri}.' '.$e->{comment}.'』と'.strftime('%Y-%m-%d %H:%M:%S', localtime($e->{post_time}));
-}
-
-sub _response {
-       my ($me, $args, $msg) = @_;
-
-       $me->say(channel => $args->{channel},
-                body => $msg);
-}
-
-sub _add {
-       my ($me, $args)  =@_;
-       my ($resp, $resp_msg);
-
-       if ($args->{body} =~ /$mu_re/) {
-               my $prefix = $1;
-               my $uri = $2;
-               my $comment = $3;
-               my $text = $args->{who} . '曰く、'.$prefix.' '.$comment;
-
-               if (my $res = $me->{db}->check_dup({uri =>$uri})) {
-                       if ($res->{post_time} < time() - 7 * 24 * 60 * 60) {
-                               $resp_msg = 'だいぶ前 '.$me->_format_submit($res).'にいってたにゃー '.$me->{fb}->post_uri($res->{fb_post_id});
-                       } else {
-                               $resp_msg = '既に '.$me->_format_submit($res).'に言ってますよ? '.$me->{fb}->post_uri($res->{fb_post_id});
-                       }
-               } else {
-                       my $post_ok = 1;
-                       eval{$resp = $me->{fb}->publish($text, $uri)};
-                       if ($@) {
-                               $me->{fb}->init();
-                               eval{$resp = $me->{fb}->publish($text, $uri)};
-                               $post_ok = 0 if ($@);
-                       }
-
-                       if ($post_ok) {
-                               my (undef, $post_id) = split(/_/, $resp->{id});
-                               $me->{db}->add({submitter => $args->{who},
-                                               fb_post_id => $post_id,
-                                               uri => $uri,
-                                               prefix => $prefix,
-                                               comment => $comment});
-                               $resp_msg = $args->{who} . ': うい  '.$me->{fb}->post_uri($post_id).' で登録';
-                       } else {
-                               $resp_msg = 'can not post to facebook';
-                       }
-               }
-               return $resp_msg;
-       }
-       return 0;
-}
-
-sub _remove_prev {
-       my ($me, $args) = @_;
-
-       my $last_post = $me->{db}->search_lastpost_by_submitter({who => $args->{who}});
-
-       if (!defined $last_post) {
-               return $args->{who}.': いまのっていつの? というか ないし';
-       } elsif ($last_post->{post_time} < time() - 3600) {
-               return $args->{who}.': いまのっていつの? 最後のはこれだけど古いんだにゃ ' . $me->{fb}->post_uri($last_post->{fb_post_id});
-       } else {
-               return $me->_remove($args, $last_post->{'fb_post_id'});
-       }
-}
-
-sub _remove {
-       my ($me, $args, $post_id)  =@_;
-       my ($resp_msg, $resp);
-
-       $me->{db}->begin;
-       if ($resp = $me->{db}->remove({fb_post_id => $post_id, submitter => $args->{who}})) {
-               # fb 側のエントリを削除しないといけない
-               if ($me->{fb}->remove($post_id)) {
-                       $me->{db}->commit;
-                       $resp_msg = $args->{who} . ': 削除しました ' . $me->{fb}->post_uri($post_id);
-               } else {
-                       $me->{db}->rollback;
-                       $resp_msg = $args->{who} . ': 削除に失敗しましたよ? ' . $me->{fb}->post_uri($post_id);
-               }
-       } else {
-               $me->{db}->rollback;
-               $resp_msg = $args->{who} . ': そんな投稿ないよ? ' . $me->{fb}->post_uri($post_id);
-       }
-       return $resp_msg;
-}
-
-sub _search_start {
-       my ($me, $args)  = @_;
-
-       if ($args->{body} =~ /^ふみくん\s+(.+)\?\s*$/) {
-               $me->{last_search}->{$args->{who}} = undef;
-               $me->{last_search}->{$args->{who}} = $me->{db}->search_by_word({word => $1});
-               return $me->_search_next($args);
-       }
-}
-
-sub _search_next {
-       my ($me, $args)  = @_;
-
-       my $resp_msg = 'ないっす';
-       if (defined $me->{last_search}->{$args->{who}}) {
-               my $ent = pop($me->{last_search}->{$args->{who}});
-               if ($ent) {
-                       my $count = @{$me->{last_search}->{$args->{who}}};
-                       if ($count) {
-                       }
-                       $resp_msg = $args->{who} . ': ' . $me->_format_submit($ent).'に言ってた '.($count ? '[ほか'.$count.'件] ' : '[ほかにはもうないよ] ').$me->{fb}->post_uri($ent->{fb_post_id});
-               }
-       }
-       return $resp_msg;
-}
-
-sub _not_yet {
-       return 'まだ実装してないです';
-}
-
-sub said {
-       my ($me, $args) = @_;
-       my $resp_msg;
-
-       if ($args->{body} =~ /$mu_re/) {
-               $resp_msg = $me->_add($args) unless ($1 eq 'deb');
-       } elsif ($args->{body} =~ /^ふみくん\s+(.+)\s*$/) {
-               my $cmd = $1;
-               if ($cmd eq 'いまのなし') {
-                       $resp_msg = $me->_remove_prev($args);
-               } elsif ($cmd =~ /削除\s+(?:$me->{cfg}->{fb_page_url}\/posts\/)?([0-9]+)$/) {
-                       $resp_msg = $me->_remove($args, $1);
-               } elsif ($cmd =~ /\?$/) {
-                       $resp_msg = $me->_search_start($args);
-               } elsif ($cmd =~ /つぎ/) {
-                       $resp_msg = $me->_search_next($args);
-               } elsif ($cmd =~ /どこ/) {
-                       $resp_msg = $args->{who}.': ここ ' . $me->{cfg}->{fb_page_url};
-               } else {
-                       $resp_msg = $args->{who}.': ん? (' . strftime('%Y-%m-%d %H:%M:%S', localtime) . ')';
-               }
-       }
-
-       $me->_response($args, $resp_msg) if ($resp_msg);
-}
-
-package main;
 use strict;
 use utf8;
 
@@ -377,6 +10,11 @@ use Config::Any;
 use Hash::Merge::Simple;
 use Data::Recursive::Encode;
 
+use FindBin;
+use lib ("$FindBin::Bin/lib", '/usr/share/keitairc/lib');
+
+use Mubot4FB;
+
 use Data::Dumper;
 
 my $config_name = $ARGV[0] || 'not_found';