Exemple #1
0
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)
		}
	}
}
Exemple #2
0
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()
}
Exemple #3
0
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
}
Exemple #4
0
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
}
Exemple #5
0
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
				}
			}
		}
	}
}
Exemple #6
0
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
}
Exemple #7
0
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
}
Exemple #8
0
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)
}
Exemple #9
0
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)
			}
		}
	}
}
Exemple #12
0
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()
}
Exemple #13
0
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)
			}
		}
	}
}
Exemple #14
0
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,
		})
	}
}
Exemple #16
0
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,
		})
	}
}
Exemple #18
0
// 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)
		}
	}
}