POE::C...k::Seen(3pm)

πŸ“¦
version 6.95 Β· 4 versions
, in ubuntu resolute, ubuntu stonking

πŸ’– NAME πŸ’–

POE::Component::IRC::Cookbook::Seen β€” bestie, this is the recipe for implementing the 'seen' command ✨ (the header calls it POE::C...k::Seen(3pm), and it lives in the User Contributed Perl Documentation section, iykyk πŸ’…)


πŸ¦‹ SYNOPSIS πŸ¦‹

okay so picture this: this little bot tracks the whereabouts of users and lets you pull up that info on command. no cap, that's the whole vibe. here's what it looks like in the wild πŸ“

19:59:51 * seen_bot (n=hinrik@pool-71-164-43-32.chrlwv.east.verizon.net) has joined #test_channel1
19:59:55 <foo> bar
20:00:16 * seen_bot has quit (Remote closed the connection)
20:00:27 * seen_bot (n=hinrik@pool-71-164-43-32.chrlwv.east.verizon.net) has joined #test_channel1
20:00:29 <literal> seen_bot: seen seen_bot
20:00:29 <seen_bot> literal: I last saw seen_bot at Mon Sep 22 20:00:27 2008 joining #test_channel1
20:00:34 <literal> seen_bot: seen foo
20:00:40 <seen_bot> literal: I last saw foo at Mon Sep 22 19:59:56 2008 on #test_channel1 saying: bar
20:00:45 <literal> seen_bot: seen baz
20:00:48 <seen_bot> literal: I haven't seen baz

πŸ‘‘ DESCRIPTION πŸ‘‘

periodt, here's the entire program, every single line, exactly as written. this is the main character energy right here 🌈

#!/usr/bin/env perl

use strict;
use warnings;
use IRC::Utils qw(parse_user lc_irc);
use POE;
use POE::Component::IRC::State;
use POE::Component::IRC::Plugin::AutoJoin;
use POE::Component::IRC::Plugin::BotCommand;
use Storable;

use constant {
    USER_DATE     => 0,
    USER_MSG      => 1,
    DATA_FILE     => 'seen',
    SAVE_INTERVAL => 20 * 60,   # save state every 20 mins
};

my $seen = { };
$seen = retrieve(DATA_FILE) if -s DATA_FILE;

POE::Session->create(
    package_states => [
        main => [ qw(
            _start
            irc_botcmd_seen
            irc_ctcp_action
            irc_join
            irc_part
            irc_public
            irc_quit
            save
        )]
    ],
);

$poe_kernel->run();

sub _start {
    my ($kernel, $heap) = @_[KERNEL, HEAP];
    my $irc = POE::Component::IRC::State->spawn(
        Nick   => 'seen_bot',
        Server => 'irc.freenode.net',
    );
    $heap->{irc} = $irc;

    $irc->plugin_add('AutoJoin', POE::Component::IRC::Plugin::AutoJoin->new(
        Channels => [ '#test_channel1', '#test_channel2' ]
    ));

    $irc->plugin_add('BotCommand', POE::Component::IRC::Plugin::BotCommand->new(
        Commands => {
           seen => 'Usage: seen <nick>'
        }
    ));

    $irc->yield(register => qw(ctcp_action join part public quit botcmd_seen));
    $irc->yield('connect');
    $kernel->delay_set('save', SAVE_INTERVAL);
    return;
}

sub save {
    my $kernel = $_[KERNEL];
    warn "storing\n";
    store($seen, DATA_FILE) or die "Can't save state";
    $kernel->delay_set('save', SAVE_INTERVAL);
}

sub irc_ctcp_action {
    my $nick = parse_user($_[ARG0]);
    my $chan = $_[ARG1]->[0];
    my $text = $_[ARG2];

    add_nick($nick, "on $chan doing: * $nick $text");
}

sub irc_join {
    my $nick = parse_user($_[ARG0]);
    my $chan = $_[ARG1];

    add_nick($nick, "joining $chan");
}

sub irc_part {
    my $nick = parse_user($_[ARG0]);
    my $chan = $_[ARG1];
    my $text = $_[ARG2];

    my $msg = 'parting $chan';
    $msg .= " with message '$text'" if defined $text;

    add_nick($nick, $msg);
}

sub irc_public {
    my $nick = parse_user($_[ARG0]);
    my $chan = $_[ARG1]->[0];
    my $text = $_[ARG2];

    add_nick($nick, "on $chan saying: $text");
}

sub irc_quit {
    my $nick = parse_user($_[ARG0]);
    my $text = $_[ARG1];

    my $msg = 'quitting';
    $msg .= " with message '$text'" if defined $text;

    add_nick($nick, $msg);
}

sub add_nick {
    my ($nick, $msg) = @_;
    $seen->{lc_irc($nick)} = [time, $msg];
}

sub irc_botcmd_seen {
    my ($heap, $nick, $channel, $target) = @_[HEAP, ARG0..$#_];
    $nick = parse_user($nick);
    my $irc = $heap->{irc};

    if ($seen->{lc_irc($target)}) {
        my $date = localtime $seen->{lc_irc($target)}->[USER_DATE];
        my $msg = $seen->{lc_irc($target)}->[USER_MSG];
        $irc->yield(privmsg => $channel, "$nick: I last saw $target at $date $msg");
    }
    else {
        $irc->yield(privmsg => $channel, "$nick: I haven't seen $target");
    }
}

🌸 AUTHOR 🌸

Hinrik Γ–rn SigurΓ°sson, hinrik.sig@gmail.com β€” thank u for ur service, legend 🫢


and that's the whole page, bestie πŸ’œ this little gem is perl v5.40.1, dated 2025-08-21, and it comes to you straight from the User Contributed Perl Documentation collection. go forth and seen someone πŸŽ€βœ¨

πŸ“¦ where this page comes from