Skip to content

Instantly share code, notes, and snippets.

@tpruvot
Last active October 18, 2016 22:33
Show Gist options
  • Save tpruvot/45326d5d24cfc6d4e10389349c9dd108 to your computer and use it in GitHub Desktop.
Save tpruvot/45326d5d24cfc6d4e10389349c9dd108 to your computer and use it in GitHub Desktop.
Rewrite Slack (and gitter) user messages, user names are displayed almost like other users
# Name: slack_users.pl
# Version: 2.3
# Author: https://gist.github.com/tpruvot/
# Date: 2016-10-18
# Description: Change the display of Slack channel messages, display them like normal users
# Version History
# 1.0 2016-04-16 Initial Version
# 1.1 2016-04-17 Keep message type (highlight/action)
# 1.3 2016-04-17 Nick autocompletion + keep users case
# 1.5 2016-04-17 Merge normal channel user list for autocomplete if input doesnt start with @
# 1.6 2016-04-18 Config file (txt), Index chan/slacknick list by nickname, chan lc..
# 2.0 2016-05-04 Add gitter support and enhance nick completion in sentences
# 2.2 2016-05-13 Trim inputbox on nick completion
# 2.3 2016-10-18 Handle leading brackets in user names
use strict;
use warnings;
use Xchat qw (:all);
register('Slack Users', '2.3', 'Display Slack/Gitter messages like normal ones', \&slack_unload);
# sample list of Slack bridge usernames with their channel
my %slack_chan_list = (
'slack-' => '#cryptofr',
'slack-1' => '#cryptofr',
'decred-slack' => '#decred',
'decred-slack2' => '#decred',
'zcrelaybot' => '#zcash',
);
my %gitter_chan_list = (
'decred-gitter' => '#decred',
);
# Also allow to load the list from a txt file
# nick1=#chan1
# nick2=#chan2
my $configdir = get_info('configdir');
my $addons_path = "$configdir/addons";
$addons_path =~ s/\\/\//g;
my $conf;
$conf = "$addons_path/slack_users.txt";
if (-e $conf && open my $handle, '<', $conf) {
while (my $line = <$handle>) {
chomp $line;
my ($nick, $chan) = split '=', $line;
if (length $chan) {
$slack_chan_list{trim($nick)} = lc trim($chan);
}
}
close $handle;
}
$conf = "$addons_path/gitter_users.txt";
if (-e $conf && open my $handle, '<', $conf) {
while (my $line = <$handle>) {
chomp $line;
my ($nick, $chan) = split '=', $line;
if (length $chan) {
$gitter_chan_list{trim($nick)} = lc trim($chan);
}
}
close $handle;
}
my @hooks = ('Channel Message', 'Channel Msg Hilight');
my %hfd = ();
$hfd{"Key Press"} = hook_print("Key Press", \&slack_nick_completion);
for my $hook (@hooks) {
my $options = { data => $hook };
$hfd{$hook} = hook_print($hook, \&print_messages, $options);
}
# cache for Slack users nick completion
my %slack_nicks = ();
sub trim {
my $line = $_[0];
$line =~ s/^\s+//;
$line =~ s/\s+$//;
return $line;
}
sub slack_trim_nick {
my $nick = $_[0];
$nick =~ s/^[\<\[]//;
$nick =~ s/^Slack\///i;
return $nick;
}
sub gitter_trim_nick {
my $nick = $_[0];
$nick =~ s/^\(//;
$nick =~ s/_twitter$//;
return $nick;
}
sub trim_msg {
my $line = $_[0];
$line =~ s/^ //;
return $line;
}
sub print_messages {
my ($nick, $line) = @{$_[0]};
my $from = strip_code($_[0][0]);
my $chan = lc get_info('channel');
my $hook = $_[1];
if (defined $slack_chan_list{$from} && $chan eq $slack_chan_list{$from}) {
my $sep = substr($line, 0, 1);
my $end = '>';
if ($sep eq '[') {
$end = ']';
}
my @words = split($end, $line);
my $slack_nick = shift @words;
my $text = join($end, @words);
$slack_nick = slack_trim_nick($slack_nick);
$slack_nicks{$slack_nick} = $chan;
emit_print($hook, "\@$slack_nick", trim_msg($text));
return EAT_ALL; # EAT_HEXCHAT
}
if (defined $gitter_chan_list{$from} && $chan eq $gitter_chan_list{$from}) {
my @words = split('\)', $line);
my $gitter_nick = shift @words;
my $text = join(')', @words);
$gitter_nick = gitter_trim_nick($gitter_nick);
$slack_nicks{$gitter_nick} = $chan;
emit_print($hook, "\@$gitter_nick", trim_msg($text));
return EAT_ALL; # EAT_HEXCHAT
}
return EAT_NONE;
}
sub slack_nick_completion {
my $key = $_[0][0];
my $input = get_info('inputbox');
if (!$input || (length trim($input)) == 0) {
return EAT_NONE;
}
my @words = split(' ', $input);
my $inputc = lc pop @words;
$inputc =~ s/^\@//;
if ($key == 65289) { # TAB
my %nicks = %slack_nicks;
my $chan = lc get_info('channel');
my $matches = '';
my $users = 0;
if ($inputc eq $input) {
# merge nick list with normal channel users
my @chanusers = get_list('users');
for (@chanusers) {
my $nick = $_->{nick};
$nicks{$nick} = $chan ;
}
}
for my $nick (sort {lc $a cmp lc $b} keys %nicks) {
if ($chan eq $nicks{$nick} && index(lc $nick, $inputc) == 0) {
$matches = trim("$matches $nick");
$users = $users + 1;
}
}
if ($users > 1) {
emit_print('Channel Message', "", $matches);
return EAT_ALL;
}
if ($users == 1) {
my $text = join(' ', @words);
$text = trim("$text \@$matches");
my $pos = length $text;
command("settext $text");
command("setcursor $pos");
return EAT_ALL;
}
}
return EAT_NONE;
}
sub slack_unload {
for my $fd (values %hfd) {
unhook($fd);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment