Skip to content

Commit de2fd6f

Browse files
committed
Merge branch 'irc-channel'
2 parents 0ff0e16 + af4b7cd commit de2fd6f

File tree

2 files changed

+154
-1
lines changed

2 files changed

+154
-1
lines changed

lib/Synergy/Channel/IRC.pm

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
use v5.24.0;
2+
use warnings;
3+
package Synergy::Channel::IRC;
4+
5+
use Moose;
6+
use experimental qw(signatures);
7+
8+
use Future::AsyncAwait;
9+
10+
use JSON::MaybeXS;
11+
12+
use Synergy::Event;
13+
use Synergy::Logger '$Logger';
14+
15+
use namespace::autoclean;
16+
17+
use Defined::KV;
18+
use Net::Async::IRC;
19+
20+
has irc_channels => (
21+
isa => 'ArrayRef[Str]',
22+
traits => [ 'Array' ],
23+
handles => { irc_channels => 'elements' },
24+
required => 1,
25+
);
26+
27+
before start => sub ($self) {
28+
# This really should be done with a MooseX::Type, probably, but for now this
29+
# is faster and simpler.
30+
my @irc_channels = $self->irc_channels;
31+
unless (@irc_channels) {
32+
$Logger->log_fatal([
33+
"channel %s: empty irc_channels specified",
34+
$self->name,
35+
]);
36+
}
37+
38+
my @bad = grep {; ! /\A[#&][-_0-9a-z]*\z/ } @irc_channels;
39+
if (@bad) {
40+
$Logger->log_fatal([
41+
"channel %s: invalid irc_channels specified: %s",
42+
$self->name,
43+
\@bad,
44+
]);
45+
}
46+
};
47+
48+
sub describe_event {}
49+
sub describe_conversation {}
50+
51+
async sub send_message_to_user ($self, $user, $text, $alts = {}) {
52+
await $self->send_message(
53+
$user->identity_for($self->name),
54+
$alts->{irc} // $text,
55+
);
56+
}
57+
58+
sub send_message ($self, $address, $text, $alts = {}) {
59+
my @lines = split /\n/, $text;
60+
61+
my $now = Future->done; # The Future is Now!
62+
63+
for my $line (@lines) {
64+
next unless length $line; # I'm not sure this is what I want to do.
65+
$line = Encode::encode('utf-8', $line);
66+
my $now = $now->retain->then(sub {
67+
$self->client->do_PRIVMSG(target => $address, text => $line);
68+
});
69+
}
70+
71+
return $now->else(sub {
72+
my (@error) = @_;
73+
$Logger->log([ "IRC: error sending response: %s", \@error ]);
74+
return Future->done;
75+
});
76+
}
77+
78+
with 'Synergy::Role::Channel';
79+
80+
has host => (is => 'ro', required => 1, isa => 'Str');
81+
has client => (is => 'rw');
82+
83+
async sub start ($channel) {
84+
my $nick = $channel->hub->name;
85+
86+
my $client = Net::Async::IRC->new(
87+
on_message_text => sub {
88+
my ($irc, $message, $hints) = @_;
89+
90+
$Logger->log_debug([
91+
"%s channel: IRC message: %s",
92+
$channel->name,
93+
{ message => $message, hints => $hints }
94+
]);
95+
96+
return if $hints->{is_notice};
97+
98+
my $me = $channel->hub->name; # Should be IRC client name, actually.
99+
my $text = Encode::decode('UTF-8', $hints->{text});
100+
my $was_targeted = $hints->{target_type} eq 'user' ? 1 : 0;
101+
102+
my $new = $channel->text_without_target_prefix($text, $me);
103+
if (defined $new) {
104+
$text = $new;
105+
$was_targeted = 1;
106+
}
107+
108+
my $from_user = $channel->hub->user_directory->user_by_channel_and_address(
109+
$channel->name,
110+
$hints->{prefix_nick},
111+
);
112+
113+
my $event = Synergy::Event->new({
114+
type => 'message',
115+
text => $text,
116+
was_targeted => $was_targeted,
117+
is_public => ($hints->{target_type} eq 'channel' ? 1 : 0),
118+
from_channel => $channel,
119+
from_address => $hints->{prefix_nick},
120+
defined_kv(from_user => $from_user),
121+
transport_data => $hints, # XXX ???
122+
conversation_address => (
123+
$hints->{target_type} eq 'channel'
124+
? $hints->{target_name}
125+
: $hints->{prefix_nick}
126+
)
127+
});
128+
129+
$channel->hub->handle_event($event);
130+
},
131+
);
132+
133+
$channel->client($client);
134+
135+
$channel->hub->loop->add($client);
136+
137+
await $client->login(
138+
host => $channel->host,
139+
nick => $nick,
140+
user => $nick,
141+
realname => $nick,
142+
);
143+
144+
$Logger->log([ "channel %s: connected to IRC server", $channel->name ]);
145+
146+
for my $channel_name ($channel->irc_channels) {
147+
await $client->send_message(JOIN => (undef) => "#synergy-bot");
148+
$Logger->log([ "channel %s: joined %s", $channel->name, $channel_name ]);
149+
}
150+
151+
return;
152+
}
153+
154+
1;

lib/Synergy/Reactor/Emit.pm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use Synergy::CommandPost;
1515
command emit => {
1616
help => "*emit `MESSAGE`*: repeat after me...",
1717
} => async sub ($self, $event, $rest) {
18-
$event->mark_handled;
1918
await $event->reply("$rest", { slack => "$rest" });
2019
};
2120

0 commit comments

Comments
 (0)