Skip to content

Instantly share code, notes, and snippets.

@2shortplanks
Created May 1, 2015 15:46
Show Gist options
  • Select an option

  • Save 2shortplanks/f025062e7e44d786a444 to your computer and use it in GitHub Desktop.

Select an option

Save 2shortplanks/f025062e7e44d786a444 to your computer and use it in GitHub Desktop.
monitor_hipchat
#!/usr/bin/env perl
########################################################################
# Do actions (e.g. notify me) when someone says something in HipChat
########################################################################
use 5.0016;
use strict;
use warnings;
########################################################################
# Requirements:
#
# This uses https://github.com/alloy/terminal-notifier to do notifications and
# expects it to be installed in /Applications
#
# This requires you to turn on all logging in HipChat
# Help -> Log Additional Chat Data
#
# This also uses the "File::HomeDir", "Path::Class", "XML::Easy" and
# "File::Tail::Dir" non core modules
########################################################################
use File::HomeDir;
use File::Tail::Dir;
use Path::Class qw(dir file);
use POSIX qw(strftime);
use XML::Easy::Text qw(xml10_read_element);
my $ignore_before = strftime(q!%Y/%m/%d %H:%M:%S!,localtime());
########################################################################
# override this function to define what we're with each line
########################################################################
sub process_body {
my $string = shift;
print STDERR $string;
### team city builds ###
if ($string =~ /^run tests::/) {
my ($branch, $state, $status) = $string =~ m^
[<]strong[>]
( (?: (?![<]/strong[>]).)+ )
[<]/strong[>]
^gx;
return unless $branch =~ m!^markf/!;
my ($url) = $string =~ m/<a href="([^"]+)/;
my $message = "$branch has $state with status $status";
notify_tc( $message, $url );
return;
}
}
########################################################################
my $dir = dir(File::HomeDir->my_home,'Library','Logs','HipChat');
my $tailer = File::Tail::Dir->new(
directories => [$dir->stringify],
processor => sub {
my (undef, $lines) = @_;
process_line($_) foreach @{ $lines };
}
);
$tailer->watch_files();
########################################################################
sub process_line {
my $line = shift;
return unless $line =~ s!\A(\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}:\d{2})\d RECV: !!aa;
my $when = $1;
chomp $line;
# ignore everything that happened before we started listening
return if $ignore_before gt $when;
my $xml = eval { xml10_read_element($line) } or die;
# yeah, I know I'm ignoring namespaces. Sue me
return unless $xml->type_name eq "message";
my @elements = @{ $xml->content_twine };
while (@elements) {
shift @elements;
return unless @elements;
my $maybe_body = shift @elements;
if ($maybe_body->type_name eq "body") {
process_body($maybe_body->content_twine->[0]);
return;
}
}
return;
}
########################################################################
sub notify {
my @args;
while (@_) {
push @args, '-'.shift(), shift();
}
system('/Applications/terminal-notifier.app/Contents/MacOS/terminal-notifier', @args);
}
sub notify_tc {
my $message = shift;
my $url = shift;
notify(
message => $message,
appIcon => 'https://i1.visualstudiogallery.msdn.s-msft.com/92dabd51-d14d-4676-b968-d982bb6c21f7/image/file/84629/1/teamcity_logo.png',
title => 'TeamCity Build',
'open' => $url,
);
}
########################################################################
=for launchd
This is what my launchd script to keep this running looks like. You'll
have to tweak the location of this script and where Perl is installed
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>KeepAlive</key>
<true/>
<key>Label</key>
<string>com.twoshortplanks.watchhipchat</string>
<key>ProcessType</key>
<string>Background</string>
<key>ProgramArguments</key>
<array>
<string>/Users/Mark/perl5/perlbrew/perls/perl-5.18.2/bin/perl</string>
<string>/Users/Mark/bin/monitor_hipchat</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/tmp/local.job.stderr</string>
<key>StandardOutPath</key>
<string>/tmp/local.job.stdout</string>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment