|
package main |
|
|
|
import ( |
|
"encoding/json" |
|
"flag" |
|
"fmt" |
|
"net/http" |
|
"net/url" |
|
"os" |
|
) |
|
|
|
// Channel is slack channel object |
|
type Channel struct { |
|
ID string `json:"id"` |
|
Name string `json:"name"` |
|
IsChannel bool `json:"is_channel"` |
|
Created int64 `json:"created"` |
|
Creator string `json:"creator"` |
|
IsArchived bool `json:"is_archived"` |
|
IsGeneral bool `json:"is_general"` |
|
Members []string `json:"members"` |
|
Topic struct { |
|
Value string `json:"value"` |
|
Creator string `json:"creator"` |
|
LastSet int64 `json:"last_set"` |
|
} `json:"topic"` |
|
Purpose struct { |
|
Value string `json:"value"` |
|
Creator string `json:"creator"` |
|
LastSet int64 `json:"last_set"` |
|
} `json:"purpose"` |
|
IsMember bool `json:"is_member"` |
|
LastRead string `json:"last_read"` |
|
Latest map[string]interface{} `json:"latest"` |
|
UnreadCount int64 `json:"unread_count"` |
|
UnreadCountDisplay int64 `json:"unread_count_display"` |
|
} |
|
|
|
// ChannelResponse is slack channel.info response json struct |
|
type ChannelResponse struct { |
|
OK bool `json:"ok"` |
|
Channel Channel `json:"channel"` |
|
} |
|
|
|
// ChannelListResponse is slack channel.list response object |
|
type ChannelListResponse struct { |
|
OK bool `json:"ok"` |
|
Channels []Channel `json:"channels"` |
|
} |
|
|
|
// User is slack user object |
|
type User struct { |
|
ID string `json:"id"` |
|
Name string `json:"name"` |
|
Deleted bool `json:"deleted"` |
|
Color string `json:"color"` |
|
Profile struct { |
|
FirstName string `json:"first_name"` |
|
LastName string `json:"last_name"` |
|
RealName string `json:"real_name"` |
|
Email string `json:"email"` |
|
Skype string `json:"skype"` |
|
Phone string `json:"phone"` |
|
Image24 string `json:"image_24"` |
|
Image32 string `json:"image_32"` |
|
Image48 string `json:"image_48"` |
|
Image72 string `json:"image_72"` |
|
IMage192 string `json:"image_192"` |
|
} `json:"profile"` |
|
IsAdmin bool `json:"is_admin"` |
|
IsOwner bool `json:"is_owner"` |
|
Has2fa bool `json:"has_2fa"` |
|
HasFiles bool `json:"has_files"` |
|
} |
|
|
|
// UserResponse is slack users.info response object |
|
type UserResponse struct { |
|
OK bool `json:"ok"` |
|
User User `json:"user"` |
|
} |
|
|
|
func main() { |
|
var ( |
|
token string |
|
channel string |
|
) |
|
|
|
flag.StringVar(&token, "token", "", "slack token") |
|
flag.StringVar(&token, "t", "", "slack token (short)") |
|
|
|
flag.StringVar(&channel, "channel", "", "slack channel") |
|
flag.StringVar(&channel, "c", "", "slack channel (short)") |
|
|
|
flag.Parse() |
|
|
|
if token == "" || channel == "" { |
|
fmt.Printf("Usage of %s:\n", os.Args[0]) |
|
flag.PrintDefaults() |
|
return |
|
} |
|
|
|
ch, err := getChannel(token, channel) |
|
if err != nil { |
|
os.Stderr.WriteString(fmt.Sprintf("Get channel error: %v.\n", err)) |
|
return |
|
} |
|
|
|
for _, member := range ch.Members { |
|
if u, err := getUser(token, member); err != nil { |
|
os.Stderr.WriteString(fmt.Sprintf("Get user error: %v.\n", err)) |
|
} else { |
|
fmt.Println(u.Profile.Email) |
|
} |
|
} |
|
} |
|
|
|
func getChannel(token, channel string) (*Channel, error) { |
|
v := url.Values{} |
|
v.Add("token", token) |
|
v.Add("channel", channel) |
|
|
|
res, err := http.Get( |
|
fmt.Sprintf("https://slack.com/api/channels.info?%s", v.Encode()), |
|
) |
|
if err != nil { |
|
return nil, fmt.Errorf("Request channels.info request error: %v.\n", err) |
|
} |
|
|
|
defer res.Body.Close() |
|
|
|
var cr ChannelResponse |
|
if err := json.NewDecoder(res.Body).Decode(&cr); err != nil { |
|
return nil, fmt.Errorf("Request channels.info json decode error: %v.\n", err) |
|
} |
|
if cr.OK { |
|
return &cr.Channel, nil |
|
} |
|
|
|
v = url.Values{} |
|
v.Add("token", token) |
|
res, err = http.Get( |
|
fmt.Sprintf("https://slack.com/api/channels.list?%s", v.Encode()), |
|
) |
|
if err != nil { |
|
return nil, fmt.Errorf("Request channels.list request error: %v.\n", err) |
|
} |
|
|
|
defer res.Body.Close() |
|
|
|
var clr ChannelListResponse |
|
if err := json.NewDecoder(res.Body).Decode(&clr); err != nil { |
|
return nil, fmt.Errorf("Request channels.list json decode error: %v.\n", err) |
|
} |
|
if !clr.OK { |
|
return nil, fmt.Errorf("Request channels.list response not ok.") |
|
} |
|
|
|
for _, c := range clr.Channels { |
|
if c.Name == channel { |
|
return &c, nil |
|
} |
|
} |
|
|
|
return nil, fmt.Errorf("Channel not found.") |
|
} |
|
|
|
func getUser(token, userID string) (*User, error) { |
|
v := url.Values{} |
|
v.Add("token", token) |
|
v.Add("user", userID) |
|
res, err := http.Get( |
|
fmt.Sprintf("https://slack.com/api/users.info?%s", v.Encode()), |
|
) |
|
if err != nil { |
|
return nil, fmt.Errorf("Request users.info error: %v.\n", err) |
|
} |
|
|
|
defer res.Body.Close() |
|
|
|
var ur UserResponse |
|
if err := json.NewDecoder(res.Body).Decode(&ur); err != nil { |
|
return nil, fmt.Errorf("Request users.info json decode error: %v.\n", err) |
|
} |
|
if !ur.OK { |
|
return nil, fmt.Errorf("Request channels.info response not ok.") |
|
} |
|
|
|
return &ur.User, nil |
|
} |