are you curious if your [corporate] Slack users are logging into Slack using a Slack desktop or mobile app, or if they’re just using the Slack webpage? here’s some example code to call the slack team.accessLogs API to output which of your Slack users are not using a desktop or mobile Slack app.
https://github.com/rickt/golang-slack-tools/blob/master/slackaccessloglooker.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"log" | |
"net/http" | |
"strings" | |
"time" | |
) | |
type SlackAccessLog struct { | |
Status bool `json:"ok"` | |
Logins []SlackAccessLogEntry `json:"logins"` | |
PagingData SlackAccessLogPaging `json:"paging"` | |
} | |
type SlackAccessLogEntry struct { | |
UserID string `json:"user_id"` | |
Username string `json:"username"` | |
DateFirst int64 `json:"date_first"` | |
DateLast int64 `json:"date_last"` | |
Count int `json:"count"` | |
IP string `json:"ip"` | |
UserAgent string `json:"user_agent"` | |
ISP string `json:"isp"` | |
Country string `json:"country"` | |
Region string `json:"region"` | |
} | |
type SlackAccessLogPaging struct { | |
Count int `json:"count"` | |
Total int `json:"total"` | |
Page int `json:"page"` | |
Pages int `json:"pages"` | |
} | |
// helper func to do a case-insensitive search | |
func caseinsensitivecontains(a, b string) bool { | |
return strings.Contains(strings.ToUpper(a), strings.ToUpper(b)) | |
} | |
var ( | |
page int = 1 | |
pages int = 101 | |
token string = "REDACTED" | |
slackurl string = "https://slack.com/api/team.accessLogs" | |
) | |
func main() { | |
var sal SlackAccessLog | |
// 100 pages of JSON max from the team.accessLogs Slack API | |
for page := 1; page < pages; page++ { | |
// build the url | |
url := fmt.Sprintf("%s?token=%s&page=%d", slackurl, token, page) | |
// create the request | |
req, err := http.NewRequest("GET", url, nil) | |
if err != nil { | |
log.Fatal("error: %s", err) | |
} | |
// create the http client | |
client := &http.Client{} | |
// get the response | |
response, err := client.Do(req) | |
if err != nil { | |
log.Fatal("error: %s", err) | |
} | |
defer response.Body.Close() | |
// decode the JSON response into our SlackAccessLog var | |
if err := json.NewDecoder(response.Body).Decode(&sal); err != nil { | |
log.Println(err) | |
} | |
// range through this page of the response and ignore Slack App/Android/iPhone useragents | |
for _, dj := range sal.Logins { | |
if !(caseinsensitivecontains(dj.UserAgent, "Slack_SSB") || caseinsensitivecontains(dj.UserAgent, "Android") || caseinsensitivecontains(dj.UserAgent, "iPhone")) { | |
tm := time.Unix(dj.DateLast, 0) | |
fmt.Printf("%s\t%s\t%s\n", dj.Username, tm, dj.UserAgent) | |
} | |
} | |
} | |
} |