From b40212e4214b41e2265cf42680a7a995c04f6efc Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 07:23:56 -0400 Subject: Make the HTTP request subroutine more generic Allow any Slack API method to be requested instead of just the `users.list` method. This will enable us to use other Slack API methods leveraging the same HTTP code. The `fetch_users_list` subroutine now calls out to `slack_api` in order to retrieve its data. --- slack_profile.pl | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/slack_profile.pl b/slack_profile.pl index a7e5ac6..4812dbf 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -83,15 +83,15 @@ sub users_list_cache { Irssi::get_irssi_dir() . '/scripts/slack_profile-users.list.plstore'; } -sub fetch_users_list { +sub slack_api { my $token = Irssi::settings_get_str('slack_profile_token'); die 'Requires a Slack API token. Generate one from ' . 'https://api.slack.com/docs/oauth-test-tokens. ' . 'Set it with `/set slack_profile_token TOKEN`.' if !$token; - Irssi::print('Fetching users list from Slack. This could take a while...'); + my ($method, $args) = @_; - my $url = URI->new('https://slack.com/api/users.list'); + my $url = URI->new("https://slack.com/api/$method"); $url->query_form(token => $token); my $http = HTTP::Tiny->new( @@ -106,12 +106,11 @@ sub fetch_users_list { my $payload = decode_json($resp->{'content'}); if ($payload->{'ok'}) { - @users_list = @{$payload->{'members'}}; - store \@users_list, users_list_cache; + return $payload; } else { Irssi::print("Error from the Slack API: $payload->{'error'}"); - die 'Unable to retrieve users from the Slack API'; + die 'Unable to retrieve data from the Slack API'; } } else { @@ -120,6 +119,14 @@ sub fetch_users_list { } } +sub fetch_users_list { + Irssi::print('Fetching users list from Slack. This could take a while...'); + + my $resp = slack_api('users.list'); + @users_list = @{$resp->{'members'}}; + store \@users_list, users_list_cache; +} + sub find_user { my ($username) = @_; -- cgit v1.2.3 From 68c7884bd109076b1a7c67bedcf91e36ec50ea6c Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 16:32:24 -0400 Subject: slack_api: Allow API arguments to be passed to the sub When calling the `slack_api` subroutine, an optional `$args` parameter can be passed which is a hash of Slack API arguments. The token gets added to this hash and the whole thing is set to the API URL query string. --- slack_profile.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/slack_profile.pl b/slack_profile.pl index 4812dbf..f7b1c1d 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -90,9 +90,11 @@ sub slack_api { 'Set it with `/set slack_profile_token TOKEN`.' if !$token; my ($method, $args) = @_; + $args ||= {}; + $args->{'token'} = $token; my $url = URI->new("https://slack.com/api/$method"); - $url->query_form(token => $token); + $url->query_form($args); my $http = HTTP::Tiny->new( default_headers => { -- cgit v1.2.3 From dcd362a651f6adfef8ddf38cb1c35bdb9923eca2 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 16:47:00 -0400 Subject: Get & print user profile information from Slack Fetch profile information from the Slack API's `users.profile.get` method. Grab the custom fields from the response and print these as part of the SWHOIS output. Note that this currently only works when a nick argument is passed to the command. This is just an initial version. It should be cleaned up such that getting the custom fields is probably in its own subroutine, and more importantly that fetching the profile fields from the API doesn't stop WHOIS output if the API call fails. After all, most WHOIS information can be gathered from the local cache. --- slack_profile.pl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/slack_profile.pl b/slack_profile.pl index f7b1c1d..e15ac2a 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -129,6 +129,17 @@ sub fetch_users_list { store \@users_list, users_list_cache; } +sub fetch_user_profile { + my ($user) = @_; + + my $resp = slack_api('users.profile.get', { + user => $user->{'id'}, + include_labels => 1 + }); + + return $resp->{'profile'}; +} + sub find_user { my ($username) = @_; @@ -171,6 +182,8 @@ sub print_whois { maybe_print_field('phone', $user->{'profile'}->{'phone'}); maybe_print_field('skype', $user->{'profile'}->{'skype'}); maybe_print_field('tz ', $user->{'tz_label'}); + maybe_print_field('gh ', $user->{'GitHub'}); + maybe_print_field('karma', $user->{'Karma'}); Irssi::print('End of SWHOIS'); } @@ -183,6 +196,13 @@ sub swhois { $username =~ s/^@//; if (my $user = find_user($username)) { + my $profile = fetch_user_profile($user); + foreach my $key (keys %{$profile->{'fields'}}) { + my $label = $profile->{'fields'}->{$key}->{'label'}; + my $value = $profile->{'fields'}->{$key}->{'value'}; + $user->{$label} = $value; + } + print_whois($user); } } -- cgit v1.2.3 From ef0ac1da4b67c679ddf431bf25bf32b2305fd2a1 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 17:34:07 -0400 Subject: swhois: Use a more declarative style when no arguments are given Make the code more DRY by setting `$username` to the current nick if it isn't passed to the command. This way we don't have to run `print_whois` twice. --- slack_profile.pl | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/slack_profile.pl b/slack_profile.pl index e15ac2a..43a3e24 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -191,28 +191,26 @@ sub print_whois { sub swhois { my ($username, $server, $window_item) = @_; - if ($username) { - # If $username starts with @, strip it - $username =~ s/^@//; - - if (my $user = find_user($username)) { - my $profile = fetch_user_profile($user); - foreach my $key (keys %{$profile->{'fields'}}) { - my $label = $profile->{'fields'}->{$key}->{'label'}; - my $value = $profile->{'fields'}->{$key}->{'value'}; - $user->{$label} = $value; - } - - print_whois($user); - } - } - else { + if (!$username) { if (!$server || !$server->{connected}) { Irssi::print("Not connected to server"); return; } - my $user = find_user($server->{'nick'}); + $username = $server->{'nick'}; + } + + # If $username starts with @, strip it + $username =~ s/^@//; + + if (my $user = find_user($username)) { + my $profile = fetch_user_profile($user); + foreach my $key (keys %{$profile->{'fields'}}) { + my $label = $profile->{'fields'}->{$key}->{'label'}; + my $value = $profile->{'fields'}->{$key}->{'value'}; + $user->{$label} = $value; + } + print_whois($user); } } -- cgit v1.2.3 From ccb58bce6a0bef02ebdc238cace78b4a8cd1a0c9 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 19:24:16 -0400 Subject: print_whois: Make field printing more generic Don't rely on specific custom fields. Instead, just attach all of them to the `$user` object that gets passed to `print_whois` and print the lot in a generic way. --- slack_profile.pl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/slack_profile.pl b/slack_profile.pl index 43a3e24..f6eadff 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -182,8 +182,13 @@ sub print_whois { maybe_print_field('phone', $user->{'profile'}->{'phone'}); maybe_print_field('skype', $user->{'profile'}->{'skype'}); maybe_print_field('tz ', $user->{'tz_label'}); - maybe_print_field('gh ', $user->{'GitHub'}); - maybe_print_field('karma', $user->{'Karma'}); + + foreach my $key (keys %{$user->{'fields'}}) { + my $label = $user->{'fields'}->{$key}->{'label'}; + my $value = $user->{'fields'}->{$key}->{'value'}; + + maybe_print_field($label, $value); + } Irssi::print('End of SWHOIS'); } @@ -205,11 +210,7 @@ sub swhois { if (my $user = find_user($username)) { my $profile = fetch_user_profile($user); - foreach my $key (keys %{$profile->{'fields'}}) { - my $label = $profile->{'fields'}->{$key}->{'label'}; - my $value = $profile->{'fields'}->{$key}->{'value'}; - $user->{$label} = $value; - } + $user->{'fields'} = $profile->{'fields'}; print_whois($user); } -- cgit v1.2.3 From d3bce36482e720ae21b2993b6a8933cf82d7b082 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 19:33:45 -0400 Subject: slack_api: Move `die`s outside the subroutine Don't cause the command to break WHOIS output. Previously when we were only using it to call the 'users.list' Slack API method it was fine because the WHOIS output didn't directly depend on fetching the entire users list (since we have a cache). Now that we query the Slack API on each `/swhois` (the 'users.profile.get' method), we don't want to break profile output that can easily come from our cached data by dying. There's still value in displaying profile information without custom fields. We remove the `die` calls from `slack_api` and change them to a single `die` in the `fetch_users_list` method, since if this fails we really do want to stop script execution. In that case, if we don't get the users list back from the API, we can't set it to our in-memory cache nor store it to our cache file. --- slack_profile.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/slack_profile.pl b/slack_profile.pl index f6eadff..6d5b9d2 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -112,19 +112,19 @@ sub slack_api { } else { Irssi::print("Error from the Slack API: $payload->{'error'}"); - die 'Unable to retrieve data from the Slack API'; } } else { Irssi::print("Error calling the Slack API: ($resp->{'status'}) $resp->{'reason'} | $resp->{'content'}"); - die 'Unable to communicate with the Slack API'; } } sub fetch_users_list { Irssi::print('Fetching users list from Slack. This could take a while...'); - my $resp = slack_api('users.list'); + my $resp = slack_api('users.list') or + die 'Unable to retrieve users from the Slack API'; + @users_list = @{$resp->{'members'}}; store \@users_list, users_list_cache; } -- cgit v1.2.3 From 2b5f32064be5d7482b91e214f533970f86a54538 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 20:11:47 -0400 Subject: Update TODO --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 29fbb9d..8a218a0 100644 --- a/TODO +++ b/TODO @@ -12,7 +12,7 @@ v Add in-place help v2: - Get presence information on the requested user -- Get the requested user's GitHub URL and Gigster Karma fields (needs users.profile API) +v Get the requested user's GitHub URL and Gigster Karma fields (needs users.profile API) v3: - Add a command to set/change the current user's profile fields -- cgit v1.2.3 From 2010943f30ccddf5e206e82074a118f296a50075 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 20:12:15 -0400 Subject: Add user presence to WHOIS output Display whether the requested user is online or away. --- slack_profile.pl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/slack_profile.pl b/slack_profile.pl index 6d5b9d2..91a4c7a 100644 --- a/slack_profile.pl +++ b/slack_profile.pl @@ -140,6 +140,16 @@ sub fetch_user_profile { return $resp->{'profile'}; } +sub fetch_user_presence { + my ($user) = @_; + + my $resp = slack_api('users.getPresence', { + user => $user->{'id'} + }); + + return $resp->{'presence'}; +} + sub find_user { my ($username) = @_; @@ -190,6 +200,8 @@ sub print_whois { maybe_print_field($label, $value); } + maybe_print_field('status', $user->{'presence'}); + Irssi::print('End of SWHOIS'); } @@ -212,6 +224,9 @@ sub swhois { my $profile = fetch_user_profile($user); $user->{'fields'} = $profile->{'fields'}; + my $presence = fetch_user_presence($user); + $user->{'presence'} = $presence; + print_whois($user); } } -- cgit v1.2.3 From 1b4e687a6f52c470392a3ff125a6b54080716a70 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 12 Sep 2016 20:12:58 -0400 Subject: Update TODO --- TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO b/TODO index 8a218a0..205c552 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,7 @@ v Add in-place help v2: -- Get presence information on the requested user +v Get presence information on the requested user v Get the requested user's GitHub URL and Gigster Karma fields (needs users.profile API) v3: -- cgit v1.2.3