join the dots so server starts on reload_config
[scpubgit/Clifton.git] / lib / App / Clifton / Tower / Jabber.pm
1 package App::Clifton::Tower::Jabber;
2
3 use aliased 'App::Clifton::UserConfigSet';
4 use aliased 'App::Clifton::ChainSetByJabberUser' => 'ChainSet';
5 use aliased 'Net::Async::XMPP::Client' => 'XMPP_Client';
6 use Log::Contextual qw(:log);
7 use Moo;
8
9 extends 'App::Clifton::Component';
10
11 has xmpp_client => (is => 'lazy');
12
13 sub xmpp_active { shift->xmpp_client->xmpp->is_loggedin }
14
15 has $_ => (is => 'ro', required => 1)
16   for qw(bridge_name jabber_config irc_config);
17
18 has server => (is => 'ro', required => 1, weak_ref => 1);
19
20 has userconfig_set => (
21   is => 'ro', # Moobug init_arg => undef,
22   default => sub { UserConfigSet->new }
23 );
24
25 has chain_set => (
26   is => 'ro', # Moobug init_arg => undef,
27   default => sub { ChainSet->new }
28 );
29
30 sub _build_xmpp_client {
31   my ($self) = @_;
32   $self->_login_xmpp_client($self->_new_child(XMPP_Client, {
33     on_message => $self->_replace_weakself('handle_message'),
34   }));
35 }
36
37 sub _login_xmpp_client {
38   my ($self, $xmpp) = @_;
39   my $conf = $self->jabber_config;
40   $xmpp->login(
41     jid => $conf->user, host => $conf->server, password => $conf->pass,
42   );
43   $xmpp;
44 }
45
46 sub BUILD { $_[0]->xmpp_client }
47
48 sub handle_message {
49   my ($self, $msg) = @_;
50
51   my $me = $self->jabber_config->user;
52
53   return log_debug {
54     "Received message for ${\$msg->to} instead of $me - ignoring"
55   } unless $msg->to eq $me;
56
57   (my $from = $msg->from) =~ s/\/.*//;
58
59   return log_debug {
60     "Received message from me ($me) - ignoring"
61   } if $from eq $me;
62
63   return log_debug {
64     "Received message from user ${from} not in my config"
65   } unless my $user = $self->userconfig_set->get({ name => $from });
66
67   if (my $chain = $self->chain_set->get({ jabber_user => $from })) {
68     $chain->handle_xmpp_message($msg);
69   } else {
70     if ($msg->body =~ m{^\s*/start\s*$}) {
71       $self->send_xmpp_message({
72         to => $from, body => 'Connecting ...'
73       });
74       $self->start_chain_for($user)->on_finished(
75         $self->_capture_weakself(sub {
76           my ($self, $result) = @_;
77           if ($result->{chain}) {
78             $self->chain_set->add($result->{chain});
79           }
80           $self->send_xmpp_message({
81             to => $from, body => 'Connection result: '.$result->{message}
82           });
83         })
84       );
85     } else {
86       $self->send_xmpp_message({
87         to => $from,
88         body => 'Not currently connected - send /start to connect'
89       });
90     }
91   }
92 }
93
94 sub send_xmpp_message {
95   my ($self, $args) = @_;
96   $self->xmpp_client->compose(%$args)->send;
97 }
98
99 sub start_chain_for {
100   my ($self, $user) = @_;
101   $self->server->start_chain({
102     jabber_tower => $self,
103     jabber_user => $user->name,
104     irc_tower => {
105       server => $self->irc_config->server,
106       irc_nick => $user->irc_nick
107     },
108     irc_channel => $self->irc_config->channel,
109   });
110 }
111
112 1;
113
114 # and later
115
116 # package App::Clifton::Tower::IRC;
117
118 # has irc_client
119
120 # has irc_server_name
121
122 # has user_config
123
124 # has chain_set
125
126 # package App::Clifton::Chain
127
128