-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathslack_fetch_list
executable file
·99 lines (85 loc) · 4.43 KB
/
slack_fetch_list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env bash
set -x
# Fetch list of various types of objects from Slack API
# Copyright (C) 2015 Kolbe Kegel <[email protected]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# this script gets a list of channels or users. if you source the script from an interactive shell,
# it'll create exported environment variables. this facilitates a sort of caching that makes
# repeated invocation of scripts like slack_channel_history much faster. you can specify multiple
# types of "objects", but that's really only useful if you are sourcing the script. if you execute
# the script with multiple arguments, you'll have to look for a blank line in the output to switch
# from parsing one of the objects to the next.
#
# you must define and export SLACK_API_TOKEN in your shell's environment. get a token here: https://api.slack.com/web
# you must have jq installed: http://stedolan.github.io/jq/
abort() {
printf "[ERROR]: %s. Aborting.\n" "$1" >&2
[[ $- = *i* ]] || exit 1
return 1
}
type jq &>/dev/null || abort "you don't appear to have the jq tool: http://stedolan.github.io/jq/"
[[ $1 ]] || abort "you must specify an object type ('channels' or 'users')"
for arg; do
case $arg in
chan*|conv*) object=conversations; filter='.channels[] | .name+":"+.id' ;;
u*) object=users; filter='.members[] | .id+":"+.name+":"+.profile.email+":"+.profile.display_name+":"+.profile.real_name' ;;
g*) object=groups; filter='.groups[] | .name+":"+.id' ;;
*) abort "unknown object type '$1'";;
esac
slack_api_cmd(){
local cursor= temp=
while true; do
temp=$( curl -H "" --silent "https://slack.com/api/$object.list?token=${SLACK_API_TOKEN:?}&cursor=$cursor" ) || return
if jq -e '.error == "ratelimited"' <<<"$temp" >/dev/null; then sleep 1; continue; fi
cursor=$( jq -r .response_metadata.next_cursor <<<"$temp" )
jq -r -e 'if .ok==true then '"$filter"' else error(.error) end' 2>&1 <<<"$temp" || return
if [[ $cursor = null ]] || [[ -z $cursor ]]; then break; fi
done
# maybe a future version of jq will provide some other mechanism for this, but
# i needed to force jq to exit with a non-zero exit code if the fetch from the API failed
}
if ! slack_api_output=$(slack_api_cmd); then
abort "couldn't fetch $object list ($slack_api_output)"
fi
if [[ $- = *i* ]]; then
# if the shell is interactive, that means this file is being "sourced",
# so we set a variable in the user's shell and export it. that basically
# makes a persistent cache of the object we fetched, which makes
# invocations of things like slack_channel_history *much* faster, since
# they do not have to fetch user and channel lists every time they run
declare -x "slack_${object}_list=$slack_api_output"
# this is an associative array version, which only works in bash 4+
if (( BASH_VERSINFO[0] >= 4 )); then
varname=slack_${object}
unset "$varname"
declare -A "$varname"
while IFS=: read -r k v; do
printf -v "$varname[$k]" %s "$v"
done <<<"$slack_api_output"
fi
# here's another solution:
#printf -v "slack_${object}_list" %s "$slack_api_output"
#export "slack_${object}_list"
# and if none of those work, you should read http://mywiki.wooledge.org/BashFAQ/006
else
# if the shell is *not* interactive, this file is being executed, so we'll just dump
# the results to stdout and the caller can parse them as they see fit.
printf "%s\n" "$slack_api_output"
fi
unset slack_api_output
(($#>1)) && printf '\n'
true # or failure of that argc check will cause script to exit with failure!
done