use v6.d;
use Config::TOML;
use IRC::Client;
my $config = from-toml(
file => (%*ENV<BOHA_CONFIG_FILE> // $?FILE.IO.sibling('boha.toml').Str)
);
role TracksOps does IRC::Client::Plugin {
has %!nick-cache;
has $!waiting-for-names = False;
method !check-op($e) {
return Promise.broken('not a channel message') unless $e.?channel;
return %!nick-cache{$e.channel}{$e.nick} //= Promise.new();
}
method irc-n353($e) {
my ($my-nick,$equal,$channel,$names) = $e.args();
for $names.split(/\s+/) -> $name-str {
my $user = $name-str ~~ / ^ $<sigil> = [ '@' | '+' ]? $<nick> = [ .+ ] $ /;
my $is-op = $user<sigil> eq '@';
my $value := %!nick-cache{$channel}{$user<nick>};
if $value ~~ Promise && $value.status ~~ Planned {
$value.keep($is-op);
}
else {
$value = Promise.kept($is-op);
}
}
$!waiting-for-names = False;
return $.NEXT;
}
method irc-join($e) {
Promise.in(5).then: {
unless ($!waiting-for-names) {
$e.irc.send-cmd('NAMES', $e.channel, :server($e.server));
$!waiting-for-names = True;
}
};
return $.NEXT;
}
}
class Boha1 does TracksOps {
method irc-addressed($e) {
return self!check-op($e).then: sub ($promise) {
if ($promise.status ~~ Broken) {
return Nil;
}
if (so $promise.result) {
return "you're an op";
}
else {
return "you're a normal user";
}
};
}
}
.run with IRC::Client.new(
|($config<server>),
channels => $config<channels>.map(*.<name>),
:debug,
:plugins(
Boha1.new,
),
);