func PipeSlackToIRC(slackAPI *slack.Slack, ircLink *irc.Connection) { //sender := make(chan slack.OutgoingMessage) receiver := make(chan slack.SlackEvent) wsAPI, err := slackAPI.StartRTM("", "http://example.com") if err != nil { log.Fatalf("StartRTM() error: %s", err) } go wsAPI.HandleIncomingEvents(receiver) go wsAPI.Keepalive(10 * time.Second) for { msg := <-receiver switch msg.Data.(type) { case *slack.MessageEvent: msgEvent := msg.Data.(*slack.MessageEvent) // Ignore bot messages, including our own if msgEvent.BotId != "" { break } fmt.Printf("Message: %s\n", msgEvent) user, err := slackAPI.GetUserInfo(msgEvent.UserId) if err != nil { log.Printf("GetUserInfo(): %s\n", err) break } msg := fmt.Sprintf("(Slack) <%s> %s", user.Profile.RealName, unescapeMessage(msgEvent.Text)) ircLink.Privmsg(IRCChannel, msg) fmt.Println("Slack -> IRC:", msg) } } }
func archiveChannels(api *slack.Slack, c []slack.Channel, reason string) { var wg sync.WaitGroup for _, channel := range c { fmt.Printf("Archiving #%s (%s) due to %s\n", channel.Name, channel.Id, reason) wg.Add(1) go func(c slack.Channel) { defer wg.Done() if err := api.ArchiveChannel(c.Id); err != nil { message := fmt.Sprintf( "Error archiving channel #%s (%s): %s\n", c.Name, c.Id, err) log.Printf(message) // send error message in a DM to onErrorNotify user/channel onErrorNotify := os.Getenv("ARCHIVEBOT_NOTIFY") if onErrorNotify != "" { params := slack.PostMessageParameters{} if _, _, postMessageError := api.PostMessage( onErrorNotify, message, params); postMessageError != nil { postMessageErrorMessage := fmt.Sprintf( "Error posting error message to Slack: %s\n", postMessageError) log.Printf(postMessageErrorMessage) } } } }(channel) } wg.Wait() }
func dumpGroups(api *slack.Slack, dir string, rooms []string) []slack.Group { groups, err := api.GetGroups(false) check(err) if len(rooms) > 0 { groups = FilterGroups(groups, func(group slack.Group) bool { for _, room := range rooms { if room == group.Name { return true } } return false }) } if len(groups) == 0 { var groups []slack.Group return groups } for _, group := range groups { dumpChannel(api, dir, group.Id, group.Name, "group") } return groups }
func fetchChannelHistory(api *slack.Slack, ID string) []slack.Message { historyParams := slack.NewHistoryParameters() historyParams.Count = 1000 // Fetch History history, err := api.GetChannelHistory(ID, historyParams) check(err) messages := history.Messages latest := messages[len(messages)-1].Timestamp for { if history.HasMore != true { break } historyParams.Latest = latest history, err = api.GetChannelHistory(ID, historyParams) check(err) length := len(history.Messages) if length > 0 { latest = history.Messages[length-1].Timestamp messages = append(messages, history.Messages...) } } return messages }
func lastMessageTimestamp(api *slack.Slack, channel slack.Channel) (int64, error) { var latest string for { historyParams := slack.HistoryParameters{Count: 5} if latest != "" { historyParams.Latest = latest } history, err := api.GetChannelHistory(channel.Id, historyParams) if err != nil { return -1, err } if len(history.Messages) == 0 { return -1, nil } for _, msg := range history.Messages { latest = msg.Msg.Timestamp if msg.SubType != "channel_join" && msg.SubType != "channel_leave" { msgStamp := strings.Split(msg.Msg.Timestamp, ".") if timestamp, err := strconv.ParseInt(msgStamp[0], 10, 32); err == nil { return timestamp, nil } } } } }
func dumpChannels(api *slack.Slack, dir string, rooms []string) []slack.Channel { channels, err := api.GetChannels(false) check(err) if len(rooms) > 0 { channels = FilterChannels(channels, func(channel slack.Channel) bool { for _, room := range rooms { if room == channel.Name { return true } } return false }) } if len(channels) == 0 { var channels []slack.Channel return channels } for _, channel := range channels { dumpChannel(api, dir, channel.Id, channel.Name, "channel") } return channels }
func addChannelHistory(s *slack.Slack, db *sql.DB, channel, oldest string) (string, error) { params := slack.NewHistoryParameters() params.Oldest = oldest params.Count = 1000 history, err := s.GetChannelHistory(channel, params) if err != nil { return "", err } for _, msg := range history.Messages { if msg.SubType != "" { continue } fmt.Printf("%s: %s\n", msg.User, msg.Text) ts := timestampToTime(msg.Timestamp) _, err := db.Exec( `INSERT INTO messages(channel_id, user_id, text, timestamp, created_at, updated_at) VALUES(?, ?, ?, ?, NOW(), NOW()) `, channel, msg.User, msg.Text, ts.Format("2006-01-02 15:04:05")) if err != nil { return "", err } } if len(history.Messages) > 0 { return history.Messages[0].Timestamp, nil } return "", nil }
func dumpUsers(api *slack.Slack, dir string) { users, err := api.GetUsers() check(err) data, err := MarshalIndent(users, "", " ") check(err) err = ioutil.WriteFile(path.Join(dir, "users.json"), data, 0644) check(err) }
func SendIRCToSlack(event *irc.Event, slackAPI *slack.Slack) { params := slack.PostMessageParameters{ Username: fmt.Sprintf("(IRC) %s", event.Nick), AsUser: true, } _, _, err := slackAPI.PostMessage(SlackChannel, event.Message(), params) if err != nil { log.Println("SendIRCToSlack:", err) } else { fmt.Println("IRC -> Slack:", event.Message()) } }
func dmPerson(user *slack.User, message string, api *slack.Slack) { if user.Name == "typebot" { return } _, _, chanId, err := api.OpenIMChannel(user.Id) if err != nil { fmt.Println("IM err ", err) } api.PostMessage(chanId, message, slack.PostMessageParameters{ AsUser: true, }) }
func setupRTM(api *slack.Slack) { chSender := make(chan slack.OutgoingMessage) chReceiver := make(chan slack.SlackEvent) wsAPI, err := api.StartRTM("", "http://example.com") if err != nil { fmt.Errorf("%s\n", err) } go wsAPI.HandleIncomingEvents(chReceiver) go wsAPI.Keepalive(20 * time.Second) go func(wsAPI *slack.SlackWS, chSender chan slack.OutgoingMessage) { for { select { case msg := <-chSender: wsAPI.SendMessage(&msg) } } }(wsAPI, chSender) for { select { case msg := <-chReceiver: fmt.Print("Event Received: ") switch msg.Data.(type) { case slack.HelloEvent: // Ignore hello case *slack.MessageEvent: a := msg.Data.(*slack.MessageEvent) fmt.Printf("Message: %v\n", a) fmt.Printf("ChanID:", a.ChannelId) if strings.Contains(a.Text, "U085QG8D7") { createFormForEverybody(a, api) } case *slack.PresenceChangeEvent: a := msg.Data.(*slack.PresenceChangeEvent) fmt.Printf("Presence Change: %v\n", a) case slack.LatencyReport: a := msg.Data.(slack.LatencyReport) fmt.Printf("Current latency: %v\n", a.Value) case *slack.SlackWSError: error := msg.Data.(*slack.SlackWSError) fmt.Printf("Error: %d - %s\n", error.Code, error.Msg) default: fmt.Printf("Unexpected: %v\n", msg.Data) } } } }
func archiveChannels(api *slack.Slack, c []slack.Channel, reason string) { var wg sync.WaitGroup for _, channel := range c { fmt.Printf("Archiving #%s (%s) due to %s\n", channel.Name, channel.Id, reason) wg.Add(1) go func(c slack.Channel) { defer wg.Done() if err := api.ArchiveChannel(c.Id); err != nil { log.Printf("Error archiving #%s (%s): %s\n", c.Name, c.Id, err) } }(channel) } wg.Wait() }
func startStream(c *slack.Slack, flows []string, responders []*MessageResponder) { chSender := make(chan slack.OutgoingMessage) chReceiver := make(chan slack.SlackEvent) wsAPI, err := c.StartRTM("", "https://slack.com/api") if err != nil { fmt.Errorf("%s\n", err) } go wsAPI.HandleIncomingEvents(chReceiver) go wsAPI.Keepalive(20 * time.Second) go func(wsAPI *slack.WS, chSender chan slack.OutgoingMessage) { for { select { case msg := <-chSender: wsAPI.SendMessage(&msg) } } }(wsAPI, chSender) for { select { case msg := <-chReceiver: fmt.Print("Event Received: ") switch msg.Data.(type) { case slack.HelloEvent: // Ignore hello case *slack.MessageEvent: a := msg.Data.(*slack.MessageEvent) handleMessage(c, a, responders) fmt.Printf("Message: %v\n", a) case *slack.PresenceChangeEvent: a := msg.Data.(*slack.PresenceChangeEvent) fmt.Printf("Presence Change: %v\n", a) case slack.LatencyReport: a := msg.Data.(slack.LatencyReport) fmt.Printf("Current latency: %v\n", a.Value) case *slack.WSError: error := msg.Data.(*slack.WSError) fmt.Printf("Error: %d - %s\n", error.Code, error.Msg) default: fmt.Printf("Unexpected: %v\n", msg.Data) } } } }
func updateChannels(s *slack.Slack, db *sql.DB) error { channels, err := s.GetChannels(false) if err != nil { return err } for _, c := range channels { fmt.Printf("%s : %s\n", c.Name, c.ID) _, err := db.Exec( `INSERT INTO channels(id, name, created_at, updated_at) VALUES(?, ?, NOW(), NOW()) ON DUPLICATE KEY UPDATE name = VALUES(name), updated_at = NOW() `, c.ID, c.Name) if err != nil { return err } } return nil }
func createFormForEverybody(formMessage *slack.MessageEvent, api *slack.Slack) { users, err := api.GetUsers() if err != nil { fmt.Println("Channel err ", err) } for _, user := range users { //create user form DONE //send dm to fill out form DONE formResp := createFormForUser(formMessage, user.Id) if user.Name == "typebot" || user.Id == "U085QG8D7" { continue } _, _, chanId, err := api.OpenIMChannel(user.Id) if err != nil { fmt.Println("IM err ", err) } fmt.Println("formResp ", formResp) formDM := fmt.Sprintf("A form has been created, go fill it out! %v", formResp.Links[1].Href) api.PostMessage(chanId, formDM, slack.PostMessageParameters{ AsUser: true, }) } }
func updateUsers(s *slack.Slack, db *sql.DB) error { users, err := s.GetUsers() if err != nil { return err } for _, u := range users { fmt.Printf("%s : %s\n", u.Name, u.ID) _, err := db.Exec( `INSERT INTO users(id, name, icon_url, created_at, updated_at) VALUES(?, ?, ?, NOW(), NOW()) ON DUPLICATE KEY UPDATE name = VALUES(name), icon_url = VALUES(icon_url), updated_at = NOW() `, u.ID, u.Name, u.Profile.Image72) if err != nil { return nil } } return nil }
func dmAll(message string, api *slack.Slack) { users, err := api.GetUsers() if err != nil { fmt.Println("Channel err ", err) } for _, user := range users { if user.Name == "typebot" { continue } _, _, chanId, err := api.OpenIMChannel(user.Id) if err != nil { fmt.Println("IM err ", err) } api.PostMessage(chanId, message, slack.PostMessageParameters{ AsUser: true, }) } }
// handleMessage receives an event and passes it to the MessageResponders func handleMessage(c *slack.Slack, e *slack.MessageEvent, responders []*MessageResponder) { if e.Username == "cbot" { return } content, args, err := parseMessageContent(e) if err != nil { log.Printf("Error parsing message: %v", err) return } if len(content) == 0 { return } // determine if this is a direct message (prefixed with bots name) direct := len(args) > 0 && args[0] == *prefix // handle 'help' command if direct && (len(args) == 1 || (len(args) > 1 && args[1] == "help")) { helpTxt := bytes.NewBufferString("I understand:\n") for _, r := range responders { if r.Name[0] == '_' { continue } helpTxt.WriteString(fmt.Sprintf(" %s %s\n", *prefix, r.Name)) } params := slack.PostMessageParameters{Username: *prefix} if _, _, err := c.PostMessage(e.Channel, helpTxt.String(), params); err != nil { log.Println(err) } return } directHandled := !direct user, err := c.GetUserInfo(e.Msg.User) os.Setenv("CURRENT_FLOW", e.Channel) os.Setenv("CURRENT_USER_AVATAR", user.Profile.ImageOriginal) os.Setenv("CURRENT_USER_EMAIL", user.Profile.Email) os.Setenv("CURRENT_USER_NICK", user.Name) os.Setenv("CURRENT_USER_NAME", user.Profile.RealName) os.Setenv("CURRENT_USER_ID", string(user.ID)) for _, responder := range responders { caught, err := responder.Handle(direct, content, args[1:], func(response string) error { // handle the output of the command by replying to the message params := slack.PostMessageParameters{Username: *prefix} _, _, error := c.PostMessage(e.Channel, response, params) return error }) if err != nil { log.Println(err) continue } if caught && direct { directHandled = true } } // handle case when a direct message wasn't handled if !directHandled { log.Printf("Unhandled direct message: %s", content) resp := "Sorry, didn't recognize that command. Try 'cbot help'" params := slack.PostMessageParameters{Username: *prefix} if _, _, err := c.PostMessage(e.Channel, resp, params); err != nil { log.Println(err) } } }