You are on page 1of 7

#!

/usr/bin/perl
# v2.2
# works.. didn't 100% test it. but it works thus far! ^_^
=pod
This bot is a bot that interacts with users across the IRC protocol. Before you
can run it you need to make sure that you have the proper modules installed.
This bot uses these modules:
- Net::IRC
- Term::ANSIColor
- Weather::Underground
- HTML::Parser
- HTML::Tagset
- LWP::UserAgent
- Net::Ping
- LWP::Simple
- Digest::MD5
- Digest::SHA
- Sys::Hostname
To check if you have these installed, execute the command: instmodsh in your she
ll.
Most of these are already provided as part of the Core Modules, others you need
to download via CPAN. Follow their directions as to how you should install their
modules.
You can choose whether or not you want a file. For the last argument, if it's bl
ank, it won't log.
This bot has the following capabilities: - Replying to requests in public channe
l
- Help menu in private messages
- Checking the weather
- Checking if a website is up
- Checking if a TCP::Port is up
- Encrypting a message using the MD5 an
d SHA1 algorithm
- The time and date
- Keeping a log of all interactions (pu
blic and private)
* Names are not shown if stuff i
s written as msg, only the command(s) queried in public log the nickname
You can call this file any name you want, it's up to you. The default name is 'b
ot.pl'. The helpmenus and such change according to the filename, it's not hardty
ped.
You can either execute this file via ./ or using the actual perl interpreter.
Perl Interpreter: perl bot.pl
./ : sudo chown yourusername bot.pl; sudo chmod +x bot.pl; ./bot.pl
=cut
use strict;
use vars qw/$VERSION %INFO/;
use Net::IRC;
use Term::ANSIColor qw/:constants/;
use Weather::Underground;
use HTML::Parser;
use HTML::Tagset;
use LWP::UserAgent;
use Net::Ping;
use LWP::Simple;
use Digest::MD5 qw/md5_hex/;
use Digest::SHA qw/sha1_hex/;
use Sys::Hostname;
$VERSION = '2.2';
%INFO = (
author => 'Franc',
name => 'Perl IRC Bot v.2.0',
desc => 'Use this script to have a utility channel bot',
);
$SIG{INT} = \&signalint;
my %ext = (
"-e" => "This is a bot that uses the IRC protocol to respond to queries
such as checking the weather, and more.\n\n__Arguments__\n-u, -- Shows Usage and
Example of this program\n-i, -- Feed bot with the information to connect to ser
ver\n-v, -- Shows version of this program",
"-u" => "Usage: perl $0 -i <BotName> <IRCServer> <IRCChannel> <logfile>\
nExample: perl $0 -i bot1029238 irc.freenode.net \\#ubuntu logfile.txt",
"-v" => "Version 2.2 created by Francois."
);
if($ext{@ARGV[0]}) {
print "$ext{$ARGV[0]}\n";
exit;
}
my $ext = shift;
my $ircb = shift;
my $ircs = shift;
my $ircc = shift;
my $logfile = shift;
my $user = getlogin();
my $pid = getpgrp();
my $host = hostname;
my $date = scalar(localtime);
open (LOGFILE, ">>$logfile");
if($ext eq '-i') {
if((!$ircb) || (!$ircs) || (!$ircc)) {
print "Missing information. Type 'perl $0 -u' for help.\n";
}
elsif( (defined($ircb)) && (defined($ircs)) && (defined($ircc))) {
print "Killbot message> "; chomp(my $killmsg = <STDIN>);
if($killmsg) {
print "'$killmsg' is now the killmsg.\n";
}else{
$killmsg = undef;
}
main($ircb,$ircs,$ircc,$killmsg);
}
}
elsif(!$ARGV[0]) {
print "Type 'perl $0 -e' for a list of arguments.\n";
exit;
}
else {
print "Unknown argument.\n";
exit;
}
sub main($$) {
my($ircb,$ircs,$ircc,$killmsg) = @_;
my $irc = new Net::IRC;
my $date = scalar(localtime);
my $TIMESTAMP = "[" . scalar(localtime) . "] ";
my $conn = $irc->newconn (
Nick => $ircb,
Ircname => "$ircb",
Server => $ircs
) or die conndied();
sub conndied {
print BOLD, RED "Problem occured. Exiting program.", RESET; print "\n";
exit;
}
sub signalint {
print STDERR "\nKilled the bot.\n";
exit;
}
sub on_connect {
my $self = shift;
$self->join("$ircc");
system "clear";
print "BotPID : $pid\n";
print "BotName : $ircb\n";
print "IRCServer : $ircs\n";
print "IRCChannel: $ircc\n";
if(!$killmsg) {
print "BotKillMsg: {none}\n";
} elsif(defined($killmsg)) {
print "BotKillMsg: \'$killmsg\'\n";
}

if(!$logfile) {
print "Log File : {not logging}\n\n";
close(LOGFILE);
} elsif(defined($logfile)) {
print "Log File : \'$logfile\'\n\n";
}
}
sub on_msg {
my ($conn, $event) = @_;
my $PRIVINPUT = $event->{args}[0];
my $nick = $event->{nick};
my %privmsgs = (
"help" => "md5 help, ip help, website help, weather hel
p, sha help, info",
"info" => "Created by Francois, Perl 5. Bot version 2.2
",
"md5 help" => "\[Detail: MD5 encrypt message\] \[Syntax: .b
ot md5 'yourmessage'\]",
"ip help" => "\[Details: Status on IP + PORT.\] \[Syntax:
.bot ip ipaddress portnumber\]",
"website help" => "\[Details: Check if a website is up\] \[Syntax: .bot
website websiteurl\]",
"weather help" => "\[Details: Check weather.\] \[Syntax: .bot weather c
ityname countryname\]",
"sha help" => "\[Details: SHA1 encrypt message] \[Syntax: .
bot sha 'yourmessage'\]"
);
my %logmsgs = (
"help" => "\[$nick\] Checked for help",
"info" => "\[$nick\] Checked bot information",
"md5 help" => "\[$nick\] Checked for MD5 help",
"ip help" => "\[$nick\] Checked ip help",
"website help" => "\[$nick\] Checked website help",
"weather help" => "\[$nick\] Checked weather help",
"sha help" => "\[$nick\] Checked for SHA help"
);
if(defined($privmsgs{$PRIVINPUT})) {
$conn->privmsg($event->{nick}, "$privmsgs{$PRIVINPUT}");
print "[" . scalar(localtime) . "] " . "\[$nick\] $logmsgs{$PRIVINPUT}.\
n";
print LOGFILE "[" . scalar(localtime) . "] " . "\[$nick\] $logmsgs{$PRIV
INPUT}.\n";

}elsif($PRIVINPUT eq $killmsg) {
killmsg($conn,$event,$PRIVINPUT,$nick);
} else {
my $message = $event->{args}[0];
print "[" . scalar(localtime) . "] " . "Private:
Typed \'$message\' (Doesn't exist).\n";
print LOGFILE "Private: Typed something that doe
sn't exist.. ('$message').\n";
$conn->privmsg($event->{nick}, "Command does\'t
exist. type 'help'");
}
}
sub on_join {
my ($self, $event) = @_;
my ($channel) = ($event->to)[0];
my $nick = $event->{nick};
if($nick eq "$ircb") {
$self->privmsg($ircc, "Bot connection established: $date");
} else {
$self->privmsg($ircc, "\[$nick\] Type '/msg $ircb help' to use m
e.");
}
}
sub on_public {
my ($conn,$event) = @_;
my $message = $event->{args}[0];
my $nick = $event->{nick};
if($message =~ /^\.bot md5 (.+)/) {
print "[" . scalar(localtime) . "] " . "Public: Checked md5.\n
";
print LOGFILE "Public: Checked md5.\n";
my $md5 = $1;
my $d = md5_hex($1);
$conn->privmsg($event->{to}[0], "\[$nick\] $d $1");
}
elsif($message =~ /^\.bot version/) {
print "[" . scalar(localtime) . "] " . "\[$nick\] Pub
lic: Checked Version.\n";
print LOGFILE "\[$nick\] Public: Checked Version.\n";
$conn->privmsg($event->{to}[0], "\[$nick\] Versi
on: 2.2");
}
elsif($message =~ /^\.bot weather (.+)/) {
print "[" . scalar(localtime) . "] " . "\[$nick\] Pub
lic: Checked Weather, $1\n";
print LOGFILE "\[$nick\] Public: Checked Weather, $1\
n";
my $weather = Weather::Underground->new ( place
=> "$1", );
my $ref = $weather->get_weather();
if($ref) {
my $loc = "$ref->[0]->{place}";
my $upd = "$ref->[0]->{updated}";
my $csc = "$ref->[0]->{conditions}";
my $h = "$ref->[0]->{humidity}\%";
my $temp = "$ref->[0]->{temperature_fahr
enheit}F $ref->[0]->{temperature_celsius}C";
my $wind = "$ref->[0]->{wind_direction}
$ref->[0]->{wind_kilometersperhour}KPH $ref->[0]->{wind_milesperhour}MPH";
$conn->privmsg($event->{to}[0], "\[$nick\] \[
$loc\] \[Sky: $csc\] \[Humidity: $h\]\[Temperature: $temp\] \[Wind: $wind\]");
}
else {
$conn->privmsg($event->{to}[0], "\[$nick\] Coul
d not find weather for that city, sorry.");
}
}
elsif($message =~ /^\.bot website (.+)/) {
print "[" . scalar(localtime) . "] " . "\[$nick\] Pub
lic: Checked website $1\n";
print LOGFILE "\[$nick\] Public: Checked website $1\n
";
if(get($1)) {
$conn->privmsg($event->{to}[0], "\[$nick\] We
bsite ('$1') got reached.\n");
} else {
$conn->privmsg($event->{to}[0], "\[$nick\]
Website ('$1') could not be reached.\n");
}
}
elsif($message =~ /^\.bot tcp (.+) (.+)/) {
print "[" . scalar(localtime) . "] " . "\[$nick\] P
ublic: Checked TCP $1::$2\n";
print LOGFILE "\[$nick\] Public: Checked TCP $1::$2\
n";
my $p = Net::Ping->new("tcp", 2);
$p->port_number($2);
if($p->ping($1)) {
$conn->privmsg($event->{to}[0], "\[$nick
\] IP '$1' on port '$2' can be reached.");
} else {
$conn->privmsg($event->{to}[0], "\[$
nick\] IP '$1' on port '$2' cannot be reached.");
}
}
elsif($message =~ /^\.bot help$/) {
print "[" . scalar(localtime) . "] " .
"\[$nick\] Public: Checked for help.\n";
print LOGFILE "\[$nick\] Public: Checked
for help.\n";
$conn->privmsg($event->{to}[0], "\[$nick
\] Message me 'help' for help.");
}
elsif($message =~ /^\.bot (date|time)/) {
print "[" . scalar(localtime) . "] " .
"\[$nick\] Public: Checked date/time.\n";
print LOGFILE "\[$nick\] Public: Checked
for date/time.\n";
$conn->privmsg($event->{to}[0], "\[$nick
\] $date");
}
elsif($message =~ /^\.bot sha (.+)$/) {
my $sha = sha1_hex($1);
print "[" . scalar(localtime) . "] " .
"\[$nick\] Public: Checked SHA.\n";
print LOGFILE "\[$nick\] Public: Checked
for SHA.\n";
$conn->privmsg($event->{to}[0], "\[$nick
\] $sha $1");
}
}
$conn->add_handler('join', \&on_join);
$conn->add_global_handler('376', \&on_connect);
$conn->add_handler('msg', \&on_msg);
$conn->add_handler('public', \&on_public);
$irc->start();
}
sub killmsg {
my ($conn,$event,$PRIVINPUT,$nick) = @_;
my ($self, $event) = @_;
$nick = $event->{nick};
print "[" . scalar(localtime) . "] " . "\[$nick\] Bot ki
lled.\n";
print LOGFILE "\[$nick\] Bot killed.\n";
$self->privmsg($ircc, "Bot connection killed: " . scalar
(localtime));
exit;
}

You might also like