func getClients(conn *ts3.Conn) (res []Client, err error) { // Get client information from the virtual server. r, errMsg := conn.Cmd("clientlist") if err := handleError(&errMsg); err != nil { return nil, err } clients := strings.Split(r, "|") for i := range clients { cliParams := mappingParams(clients[i]) if cliParams["client_type"] == "0" { clid, err := strconv.Atoi(cliParams["clid"]) if err != nil { return nil, err } cid, err := strconv.Atoi(cliParams["cid"]) if err != nil { return nil, err } res = append(res, *NewClient(clid, cid, ts3.Unquote(cliParams["client_nickname"]))) } } return }
func main() { var ( username string password string serverID string webhookURL string output string debug bool ) flag.StringVar(&username, "u", "", "TS3 server query username") flag.StringVar(&password, "p", "", "TS3 server query password") flag.StringVar(&serverID, "id", "", "Server ID") flag.StringVar(&webhookURL, "url", "", "WebHookURL") flag.StringVar(&output, "o", "clients.json", "Output file") flag.BoolVar(&debug, "d", false, "Debug") flag.Parse() if username == "" || password == "" || serverID == "" || webhookURL == "" { panic(fmt.Errorf("Not enough options")) } conn, err := ts3.Dial(":10011", true) if err != nil { panic(err) } defer conn.Close() // Login to the server. err = initConn(conn, username, password) if err != nil { panic(err) } // Select a server. err = connectToServer(conn, serverID) if err != nil { panic(err) } // Get client list. newState, err := getClients(conn) if err != nil { panic(err) } // Get channel information. channels := make(map[int]string) for i := range newState { find := false for k, v := range channels { if newState[i].CID == k { newState[i].ChannelName = v find = true break } } if !find { channelInfo, err := getChannelInfo(conn, newState[i].CID) if err != nil { panic(err) } channelName := ts3.Unquote(channelInfo["channel_name"]) channels[newState[i].CID] = channelName newState[i].ChannelName = channelName } } // If output file is not exist, store state and exit. if _, err := os.Stat(output); err != nil { if err := storeClients(newState, output); err != nil { panic(err) } os.Exit(0) } // Getting old state from output file. oldState, err := loadClients(output) if err != nil { panic(err) } // Prepare to notify new clients. var newClients []Client for i := range newState { if isExist, old := findClient(&newState[i], oldState); isExist && !old.IsNotified { newClients = append(newClients, newState[i]) newState[i].IsNotified = true } else if isExist && old.CID != newState[i].CID { newClients = append(newClients, newState[i]) newState[i].IsNotified = true } else if isExist && old.IsNotified { newState[i].IsNotified = true } } // Notify logged in clients. if len(newClients) != 0 { if debug { // Debug channelMap := makeChannelMap(newClients) text := buildText(channelMap, true) fmt.Println(text) } else { if err := notifyNewClients(webhookURL, newClients); err != nil { panic(err) } } } // Prepare to notify leaved clients. var leavedClients []Client for i := range oldState { if oldState[i].IsNotified && !matchClient(&oldState[i], newState) { leavedClients = append(leavedClients, oldState[i]) } } if len(leavedClients) != 0 { if debug { // Debug channelMap := makeChannelMap(leavedClients) text := buildText(channelMap, false) fmt.Println(text) } else { // Notify leaved clients. if err := notifyLeavedClients(webhookURL, leavedClients); err != nil { panic(err) } } } // Store new state. err = storeClients(newState, output) if err != nil { panic(err) } }