aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENCE26
-rw-r--r--bot.conf8
-rwxr-xr-xsaxrobot114
-rw-r--r--sb_config.pm30
4 files changed, 178 insertions, 0 deletions
diff --git a/LICENCE b/LICENCE
new file mode 100644
index 0000000..3d52b95
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,26 @@
+/*
+ * saxrobot - A novelty irc bot which responds to a whiff of "sax"
+ * Copyright (c) 2017 David Phillips <dbphillipsnz@gmail.com>
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
diff --git a/bot.conf b/bot.conf
new file mode 100644
index 0000000..8b43c3a
--- /dev/null
+++ b/bot.conf
@@ -0,0 +1,8 @@
+nick = somebot
+username = bot
+ircname = a bot
+server = irc.example.net
+channels = #saxtalk,#bot
+ignore = trumpetbot,abusiveuser
+password = pleffquiffle
+admins = snargle!~kleg@glarg.example.com
diff --git a/saxrobot b/saxrobot
new file mode 100755
index 0000000..ac9ccea
--- /dev/null
+++ b/saxrobot
@@ -0,0 +1,114 @@
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use POE;
+use POE::Kernel;
+use POE::Component::IRC;
+use POE::Component::IRC::Plugin::NickServID;
+use HTTP::Tiny;
+use HTML::HeadParser;
+use Config::Tiny;
+use sb_config;
+
+my %config = sb_config::parse_config('bot.conf');
+
+# New PoCo-IRC object
+my $irc = POE::Component::IRC->spawn(
+ nick => $config{nick},
+ ircname => $config{ircname},
+ server => $config{server},
+ username => $config{username},
+) or die "Failed to create new PoCo-IRC: $!";
+
+# Plugins
+$irc->plugin_add('NickServID', POE::Component::IRC::Plugin::NickServID->new(
+ Password => $config{password}
+));
+
+POE::Session->create(
+ package_states => [
+ main => [ qw(_default _start irc_001 irc_public irc_msg) ],
+ ],
+ heap => { irc => $irc },
+);
+
+our $hold_op = {};
+
+$poe_kernel->run();
+
+sub _start {
+ my $heap = $_[HEAP];
+ my $irc = $heap->{irc};
+ $irc->yield(register => 'all');
+ $irc->yield(connect => { });
+ return;
+}
+
+sub irc_001 {
+ my $sender = $_[SENDER];
+ my $irc = $sender->get_heap();
+
+ print "Connected to server ", $irc->server_name(), "\n";
+
+ $irc->yield( join => $_ ) for @{$config{channels}};
+ return;
+}
+
+sub irc_public {
+ my ($sender, $who, $where, $what) = @_[SENDER, ARG0 .. ARG2];
+ my $nick = ( split /!/, $who )[0];
+ my $channel = $where->[0];
+
+ print("$channel $who: $what\n");
+
+ # reject ignored nicks first
+ return if (grep {$_ eq $nick} @{$config{ignore}});
+
+ my $me = $irc->nick_name;
+
+ my $saxcount = () = $what =~ /sa+x/gi;
+
+ if ($saxcount > 0) {
+ $irc->yield(privmsg => $channel => "🎷 " x $saxcount);
+ }
+ return;
+}
+
+sub irc_msg {
+ my ($who, $to, $what, $ided) = @_[ARG0, ARG1, ARG2, ARG3];
+ my $nick = (split /!/, $who)[0];
+ if ($ided != 1) {
+ $irc->yield(privmsg => $nick => "You must identify with services");
+ return;
+ }
+ if (!grep {$_ eq $who} @{$config{admins}}) {
+ $irc->yield(privmsg => $nick => "I am bot, go away");
+ return;
+ }
+ if ($what =~ /^say\s/) {
+ my ($channel, $message) = $what =~ /^say\s+(\S+)\s(.*)$/;
+ if ($channel and $message) {
+ $irc->yield(privmsg => $channel => $message);
+ } else {
+ $irc->yield(privmsg => $nick => "Syntax: say <channel> <msg>");
+ }
+ }
+ return;
+}
+
+sub _default {
+ my ($event, $args) = @_[ARG0 .. $#_];
+ my @output = ( "$event: " );
+
+ for my $arg (@$args) {
+ if ( ref $arg eq 'ARRAY' ) {
+ push( @output, '[' . join(', ', @$arg ) . ']' );
+ }
+ else {
+ push ( @output, "'$arg'" );
+ }
+ }
+ print join ' ', @output, "\n";
+ return;
+}
diff --git a/sb_config.pm b/sb_config.pm
new file mode 100644
index 0000000..f4e851e
--- /dev/null
+++ b/sb_config.pm
@@ -0,0 +1,30 @@
+#!/usr/bin/env perl
+
+package sb_config;
+
+use strict;
+use warnings;
+use Config::Tiny;
+
+sub parse_config
+{
+ my @scalar_configs = ('nick', 'username', 'ircname', 'server', 'password');
+ my @list_configs = ('channels', 'ignore', 'admins');
+ my $file = $_[0];
+ my %built_config;
+ my $config = Config::Tiny->read($file);
+
+ # FIXME catch undefined/missing config options
+ foreach my $option (@scalar_configs) {
+ $built_config{$option} = $config->{_}->{$option};
+ }
+
+ foreach my $option (@list_configs) {
+ my $vals = $config->{_}->{$option};
+ $vals =~ s/^\s+|\s+$//g;
+ @built_config{$option} = [split /\s*,\s*/, $vals];
+ }
+
+ return %built_config;
+}
+1;