Esempio n. 1
0
func main() {
	iniflags.Parse()

	api := slack.New(*token)

	//var channel_id string
	channel_id := getChannelId(*channel, api)

	var include, exclude *regexp.Regexp
	var err error
	if *includes != "" {
		include, err = regexp.Compile(*includes)
		if err != nil {
			fmt.Println("ERROR: Failed to compile `line_includes` regex.")
			fmt.Println(err)
			api.PostMessage(channel_id, "==> slackd failed to compile `line_includes` regex.", slack.NewPostMessageParameters())
			api.PostMessage(channel_id, err.Error(), slack.NewPostMessageParameters())
			os.Exit(2)
		}
	}
	if *excludes != "" {
		exclude, err = regexp.Compile(*excludes)
		if err != nil {
			fmt.Println("ERROR: Failed to compile `line_excludes` regex.")
			fmt.Println(err)
			api.PostMessage(channel_id, "==> slackd failed to compile `line_excludes` regex.", slack.NewPostMessageParameters())
			api.PostMessage(channel_id, err.Error(), slack.NewPostMessageParameters())
			os.Exit(2)
		}
	}

	log, err := tail.TailFile(*file, tail.Config{Follow: true, ReOpen: *reopen, Poll: true})
	if err != nil {
		fmt.Println("ERROR: Could not tail the specified log.")
		fmt.Println(err)
		api.PostMessage(channel_id, "==> slackd could not tail the specified log.", slack.NewPostMessageParameters())
		api.PostMessage(channel_id, err.Error(), slack.NewPostMessageParameters())
		os.Exit(2)
	}
	for line := range log.Lines {
		if (include != nil && include.MatchString(line.Text)) || (exclude != nil && !exclude.MatchString(line.Text)) {
			api.PostMessage(
				channel_id,
				fmt.Sprintf("```%s```", line.Text),
				slack.NewPostMessageParameters())
		}
	}
}
Esempio n. 2
0
func postToSlack(username string, channel string, message string, attachments string) {
	param := slack.NewPostMessageParameters()
	param.Username = username

	dec := json.NewDecoder(strings.NewReader(attachments))
	_ = dec.Decode(&param.Attachments)
	fmt.Printf("%v\n", param.Attachments)

	_, _, err := ctx.slack.PostMessage(channel, message, param)
	if err != nil {
		log.WithFields(log.Fields{
			"username":    username,
			"channel":     channel,
			"message":     message,
			"attachments": attachments,
		}).Error(err.Error())
		return
	}
	log.WithFields(log.Fields{
		"username":    username,
		"channel":     channel,
		"message":     message,
		"attachments": attachments,
	}).Info("posted")
}
Esempio n. 3
0
func (rt ReconTask) performTask(task ActionItemConfig, stringContext map[string]interface{}) {
	rt.log.Debug("Task Config - %v", task.Config)
	switch task.Type {
	case "sendToSlack":
		message := EvaluateTemplate(task.Config["message"].(string), stringContext)
		slackClient := slack.New(task.Config["slackKey"].(string))
		slackClient.PostMessage(task.Config["slackTo"].(string), message, slack.NewPostMessageParameters())
	case "executeMysql":
		query := EvaluateTemplate(task.Config["query"].(string), stringContext)
		params := task.Config["params"].([]interface{})
		paramValues := make([]interface{}, 0)
		for _, param := range params {
			paramValue := EvaluateTemplate(param.(string), stringContext)
			paramValues = append(paramValues, paramValue)
		}
		endPoint, err := NewMysqlDataProvider(task.Config["mysqlConfig"].(map[string]interface{}))
		if err != nil {
			rt.log.Error("Failed to connect to mysql - %v", err)
		}
		stmt, err := endPoint.db.Prepare(query)
		if err != nil {
			rt.log.Error("Failed to prepare statement- %v", err)
		}
		defer stmt.Close()
		rt.log.Info("Executing [%s] with params [%v]", query, paramValues)
		result, err := stmt.Exec(paramValues...)
		if err != nil {
			rt.log.Error("Failed to Execute query - %v", err)
		}
		count, _ := result.RowsAffected()
		if count < 1 {
			rt.log.Info("0 rows affected, might want to check - %v", stringContext)
		}
	}
}
Esempio n. 4
0
// Publish Publishes messages to slack
func (x Slack) Publish(publishMsgs <-chan models.Message, connector models.Connector) {
	api := slack.New(connector.Key)
	for {
		message := <-publishMsgs
		msg := ""
		params := slack.NewPostMessageParameters()
		params.Username = connector.BotName
		params.IconEmoji = connector.Image
		if message.Out.Detail != "" {
			color := slackColorMe(message.Out.Status)
			attachment := slack.Attachment{
				Title:      message.Out.Text,
				TitleLink:  message.Out.Link,
				Text:       message.Out.Detail,
				Color:      color,
				MarkdownIn: []string{"text"},
			}
			params.Attachments = []slack.Attachment{attachment}
		} else {
			msg = message.Out.Text
		}
		for _, target := range strings.Split(message.Out.Target, ",") {
			if target == "*" {
				target = message.In.Target
			}
			if target != "" && target != "*" {
				api.PostMessage(target, msg, params)
			}
		}
	}
}
Esempio n. 5
0
// expect some byte and write to slack
func (s *Slack) Write(o []byte) (n int, err error) {
	outBuf := bytes.Buffer{}
	outBuf.Write(o)

	//s.rtm.SendMessage(
	//s.rtm.NewOutgoingMessage(
	//outBuf.String(),
	//s.channel,
	//),
	//)
	params := slack.NewPostMessageParameters()
	params.Username = "******"
	params.AsUser = true

	params.Attachments = []slack.Attachment{
		{
			//AuthorName: authorName,
			//AuthorIcon: authorIcon,
			Text: fmt.Sprintf("%s\n\u2014\n", outBuf.String()), // \u200B for space
			//ThumbURL: thumbURL,
			//Fields: []AttachmentField{
			//AttachmentField{
			//Title: "",
			//Value: fmt.Sprintf("*<%s|%s>*\n%s", post.ShortUrl, post.Title, description),
			//Short: false,
			//},
			//},
			MarkdownIn: []string{"text"},
		}}

	s.api.PostMessage(s.channel, "", params)
	return len(o), nil
}
Esempio n. 6
0
func sendMessage(sendWg *sync.WaitGroup, config *model.Config, api *slack.Client,
	msg *model.ChatMessage) {

	params := slack.NewPostMessageParameters()
	params.Attachments = msg.Attachments
	params.Username = config.SlackUser
	params.IconURL = config.SlackIcon
	params.LinkNames = 1
	params.AsUser = false

	channel := msg.Channel
	if channel == "" {
		// For now just print everything to the main channel. When we have RTM
		// support up and running we might also want the ability to write back
		// to a user DM channel.
		channel = config.SlackDefaultChannel
	}

	logOut.Debugf("Posting to channel %s %s %+v", channel, msg.Text, params)
	_, _, err := api.PostMessage(channel, msg.Text, params)
	if err != nil {
		logOut.Errorf("Error writing chat message: %s\n", err.Error())
	}
	sendWg.Done()
}
Esempio n. 7
0
// DefaultMessageParameters returns a default PostMessageParameters for vropsbot
func DefaultMessageParameters() (params slack.PostMessageParameters) {
	params = slack.NewPostMessageParameters()
	params.AsUser = true
	params.EscapeText = false

	return
}
Esempio n. 8
0
func (c *HelpCommand) Run(m *slack.MessageEvent, args ...string) {
	params := slack.NewPostMessageParameters()
	params.Attachments = []slack.Attachment{slack.Attachment{
		Color:  "good",
		Fields: []slack.AttachmentField{},
	}}

	service := c.Service.(*SlackService)
	if len(args) == 0 {
		for name := range service.Commands {
			params.Attachments[0].Fields = append(params.Attachments[0].Fields, slack.AttachmentField{
				Title: service.Commands[name].GetName(),
				Value: service.Commands[name].GetDescription(),
			})
		}
	} else if command, ok := service.Commands[args[0]]; ok {
		params.Attachments[0].Fields = append(params.Attachments[0].Fields, slack.AttachmentField{
			Title: command.GetName(),
			Value: command.GetDescription(),
		})
	} else {
		c.SendMessagef(m.Channel, "Команда %s не найдена", args[0])
		return
	}

	c.SendPostMessage(m.Channel, "Мои команды", params)
}
Esempio n. 9
0
func (s Slack) newPostMessageParams() slack.PostMessageParameters {
	params := slack.NewPostMessageParameters()
	if s.userName != "" {
		params.Username = s.userName
	}
	if s.iconURL != "" {
		params.IconURL = s.iconURL
	}
	return params
}
Esempio n. 10
0
func main() {
	if cli.file != "" {
		log.Printf("Loading config from %s\n", cli.file)
		f, err := os.Open(cli.file)
		if err != nil {
			log.Fatal(err)
		}
		defer f.Close()
		err = json.NewDecoder(f).Decode(&settings)
		if err != nil {
			log.Fatal(err)
		}
	} else {
		log.Fatal("You need to pass a json file to -config")
	}

	// override whats in the settings with whats on the cli
	if cli.token != "" {
		log.Printf("Slack token passed via CLI: %s\n", cli.token)
		settings.Token = cli.token
	}
	if settings.Botname == "" || cli.botname != "" {
		settings.Botname = cli.botname
	}

	if settings.Token == "" {
		log.Fatal("You need to give me an API token!")
	}

	collins := c.New(settings.Collins.Username, settings.Collins.Password, settings.Collins.Host)

	// set up posting params
	postParams = slack.NewPostMessageParameters()
	//postParams.Username = settings.Botname
	//postParams.LinkNames = 1
	// we will perform proper formatting per https://api.slack.com/docs/formatting, do make the server do no processing
	postParams.Parse = "none"

	api := slack.New(settings.Token)
	api.SetDebug(cli.debug)
	authresp, err := api.AuthTest()
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("Authed with Slack successfully as %s (%s)\n", authresp.User, authresp.UserId)

	log.Printf("Creating new handler context with message handlers:\n")
	for _, v := range messagehandlers {
		log.Printf("  %s\n", v)
	}
	handlerContext = handlers.New(collins, authresp, api, messagehandlers)
	log.Printf("Starting up message handler")
	handlerContext.Run()

}
Esempio n. 11
0
func statusToSlack(api *slack.Client, my_name string, channel string, msg string) {
	params := slack.NewPostMessageParameters()
	params.Username = my_name
	params.IconEmoji = ":exclamation:"
	attachment := slack.Attachment{}
	attachment.Color = "#ffaa00"
	attachment.Title = "Alarm Status Update"
	attachment.Text = msg
	params.Attachments = []slack.Attachment{attachment}
	api.PostMessage(channel, "", params)
}
Esempio n. 12
0
func logToSlack(api *slack.Client, my_name string, channel string, msg string, fields []slack.AttachmentField) {
	params := slack.NewPostMessageParameters()
	params.Username = my_name
	params.IconEmoji = ":page_with_curl:"
	attachment := slack.Attachment{}
	attachment.Color = "#ffaa00"
	attachment.Title = "Log Entry"
	attachment.Text = msg
	attachment.Fields = fields
	params.Attachments = []slack.Attachment{attachment}
	api.PostMessage(channel, "", params)
}
Esempio n. 13
0
func motionToSlack(api *slack.Client, my_name string, channel string, image string, count int) {
	_, err := http.Get(image)
	chk(err)

	params := slack.NewPostMessageParameters()
	params.Username = my_name
	params.IconEmoji = ":rotating_light:"
	attachment := slack.Attachment{}
	attachment.Color = "#ff0000"
	attachment.Title = "Motion detected"
	attachment.Text = fmt.Sprintf("Motion events detected: %d", count)
	attachment.ImageURL = image
	params.Attachments = []slack.Attachment{attachment}
	api.PostMessage(channel, "", params)
}
Esempio n. 14
0
func lightsToSlack(api *slack.Client, my_name string, channel string, image string, level int) {
	_, err := http.Get(image)
	chk(err)

	params := slack.NewPostMessageParameters()
	params.Username = my_name
	params.IconEmoji = ":bulb:"
	attachment := slack.Attachment{}
	attachment.Color = "#00ff00"
	attachment.Title = "Lights detected"
	attachment.Text = fmt.Sprintf("Light level detected: %d", level)
	attachment.ImageURL = image
	params.Attachments = []slack.Attachment{attachment}
	api.PostMessage(channel, "", params)
}
Esempio n. 15
0
func (b *Bslack) Send(msg config.Message) error {
	flog.Debugf("Receiving %#v", msg)
	if msg.Account == b.Account {
		return nil
	}
	nick := msg.Username
	message := msg.Text
	channel := msg.Channel
	if b.Config.PrefixMessagesWithNick {
		message = nick + " " + message
	}
	if !b.Config.UseAPI {
		matterMessage := matterhook.OMessage{IconURL: b.Config.IconURL}
		matterMessage.Channel = channel
		matterMessage.UserName = nick
		matterMessage.Type = ""
		matterMessage.Text = message
		err := b.mh.Send(matterMessage)
		if err != nil {
			flog.Info(err)
			return err
		}
		return nil
	}
	schannel, err := b.getChannelByName(channel)
	if err != nil {
		return err
	}
	np := slack.NewPostMessageParameters()
	if b.Config.PrefixMessagesWithNick == true {
		np.AsUser = true
	}
	np.Username = nick
	np.IconURL = config.GetIconURL(&msg, b.Config)
	if msg.Avatar != "" {
		np.IconURL = msg.Avatar
	}
	b.sc.PostMessage(schannel.ID, message, np)

	/*
	   newmsg := b.rtm.NewOutgoingMessage(message, schannel.ID)
	   b.rtm.SendMessage(newmsg)
	*/

	return nil
}
Esempio n. 16
0
func (n *slackNotifier) Notify(text string) error {
	channel, err := n.findChannel(n.channelName)
	if err != nil {
		return err
	}

	message := slack.NewPostMessageParameters()
	message.Text = text
	message.Username = n.name

	n.client.PostMessage(channel.Id, message.Text, message)
	if err != nil {
		return err
	}

	return nil
}
Esempio n. 17
0
func (w *workerImpl) Work() {
	channel, err := w.findChannel(w.channelName)
	if err != nil {
		workers.Log(w, err)
		return
	}

	message := slack.NewPostMessageParameters()
	message.Text = "test"
	message.Username = w.name

	w.client.PostMessage(channel.Id, message.Text, message)
	if err != nil {
		workers.Log(w, err)
		return
	}
}
Esempio n. 18
0
func Help(c *Context, m *slack.MessageEvent) (bool, error) {
	if c.isBotMention(m) && strings.Contains(m.Msg.Text, "help") {
		log.Printf("Got help message\n")
		p := slack.NewPostMessageParameters()

		//TODO sort this nonsense, cause the help output ordering keeps changing...
		helpfallbackslice := make([]string, len(helpinfo))
		actionFields := make([]string, len(helpinfo))
		descriptionFields := make([]string, len(helpinfo))
		i := 0
		for k, v := range helpinfo {
			helpfallbackslice[i] = fmt.Sprintf("%s - %s", k, v)
			actionFields[i] = k
			descriptionFields[i] = v
			i = i + 1
		}
		/* this looks lame
		helpattachmentfields := []slack.AttachmentField{
			slack.AttachmentField{
				Title: "Action",
				Value: strings.Join(actionFields, "\n"),
				Short: true,
			},
			slack.AttachmentField{
				Title: "Description",
				Value: strings.Join(descriptionFields, "\n"),
				Short: true,
			},
		}
		*/

		p.Attachments = []slack.Attachment{
			slack.Attachment{
				Title:    fmt.Sprintf("%s help", c.Self.User),
				Fallback: strings.Join(helpfallbackslice, "\n"),
				Text:     strings.Join(helpfallbackslice, "\n"),
				Color:    "warning",
				//Fields:   helpattachmentfields,
			},
		}
		_, _, err := c.Slack.PostMessage(m.ChannelId, "", p)
		return true, err
	} else {
		return false, nil
	}
}
Esempio n. 19
0
func (s *SlackLink) sendSlackMessages() {
	defer s.wg.Done()

	for msg := range s.slackOut {
		params := slack.NewPostMessageParameters()

		params.Markdown = !msg.DisableMarkdown

		if msg.As != nil {
			params.AsUser = false
			params.Username = msg.As.Name
			params.IconURL = "https://minotar.net/avatar/" + url.QueryEscape(strings.ToLower(msg.As.Name)) + "/48.png"
		} else {
			params.AsUser = true
		}

		s.slack.PostMessage(msg.To, msg.Message, params)
	}
}
Esempio n. 20
0
func AssetTag(c *Context, m *slack.MessageEvent) (bool, error) {
	// dont process if this came from a bot (like ourselves). avoids looping
	if isBotMessage(m) {
		return false, nil
	}
	// handle messages with any asset tags present - we will turn them into collins links
	tags := extractAssetTags(m.Msg.Text)
	if len(tags) > 0 {
		assets := c.lookupAssetsFromTags(tags)
		// send a message back to that channel with the links to the assets
		p := slack.NewPostMessageParameters()
		p.Attachments = make([]slack.Attachment, len(assets))
		for i, asset := range assets {
			p.Attachments[i] = c.slackAssetAttachment(asset)
		}
		_, _, err := c.Slack.PostMessage(m.ChannelId, "", p)
		return true, err
	}
	return false, nil
}
Esempio n. 21
0
func AssetHostname(c *Context, m *slack.MessageEvent) (bool, error) {
	// handle messages with any hostnames present - if assets, link them
	if isBotMessage(m) {
		return false, nil
	}
	hosts := extractHostnames(m.Msg.Text)
	if len(hosts) > 0 {
		assets := []collins.Asset{}
		for _, host := range hosts {
			//TODO!
			log.Printf("Found host %s in message: %s\n", host, m.Msg.Text)
			a, err := c.Collins.Find(map[string]string{}, map[string]string{"hostname": host})
			if err != nil || a == nil {
				log.Printf("Error trying to find host %s: %s\n", host, err.Error())
				continue
			}
			if len(a) > 1 {
				log.Printf("Multiple assets found matching hostname %s: %+v\n", a)
			} else if len(a) == 0 {
				log.Printf("Nothing found for hostname %s\n", host)
			} else {
				assets = append(assets, a[0])
			}
		}
		if len(assets) > 0 {
			log.Printf("Found assets: %+v\n", assets)
			p := slack.NewPostMessageParameters()
			//old style list assets
			//p.Attachments = []slack.Attachment{*slackAssetsAttachment(assets)}
			p.Attachments = make([]slack.Attachment, len(assets))
			for i, asset := range assets {
				p.Attachments[i] = c.slackAssetAttachment(asset)
			}
			_, _, err := c.Slack.PostMessage(m.ChannelId, "", p)
			return true, err
		}
	}
	return false, nil
}
Esempio n. 22
0
func doYoutubeMessage(liveStreamItem youtubeLiveStreamsResponseItem) {
	messageParams := slack.NewPostMessageParameters()
	messageParams.AsUser = true
	messageParams.Parse = "full"
	messageParams.LinkNames = 1
	messageParams.UnfurlMedia = true
	messageParams.UnfurlLinks = true
	messageParams.EscapeText = false
	var channelTitle = liveStreamItem.Snippet.ChannelTitle
	if channelTitle == "" {
		channelTitle = youtubeStreamDetails[liveStreamItem.Snippet.ChannelID].Snippet.Title
	}
	if channelTitle == "" {
		channelTitle = "Someone Forgot To Set A Channel Title"
	}
	messageParams.Attachments = append(messageParams.Attachments, slack.Attachment{
		Title: fmt.Sprintf(
			"Watch %s play %s",
			channelTitle,
			liveStreamItem.Snippet.Title,
		),
		TitleLink: fmt.Sprintf(youtubeLinkURL, liveStreamItem.ID.VideoId),
		ThumbURL:  liveStreamItem.Snippet.Thumbnails.Default.URL,
	})
	_, _, err := slackClient.PostMessage(
		slackCFG.Channel,
		fmt.Sprintf(
			"*%s* has begun streaming *%s*\n\n%s",
			channelTitle,
			liveStreamItem.Snippet.Title,
			liveStreamItem.Snippet.Description,
		),
		messageParams,
	)
	if err != nil {
		log.Printf("[yt] error sending message to channel: %s", err.Error())
	}
}
Esempio n. 23
0
func (s *SlackBot) HandleJoin(e Event) {
	time.Sleep(600 * time.Millisecond)
	phrases := []string{
		"Wynwood-Tech",
		"the best internet group since sliced bread",
		"the dark abyss",
		"Jamrock",
		"the interwebz",
		"the beginning of the rest of your life",
	}

	msgParams := slack.NewPostMessageParameters()
	msgParams.AsUser = true
	msgParams.LinkNames = 1
	msgString := fmt.Sprintf(
		"Hey @%v, welcome to %s! Make sure you update your avatar.",
		e.User.Name,
		phrases[rand.Intn(len(phrases))],
	)
	s.RTM.PostMessage("#general", msgString, msgParams)
	msgString = "I am Evil Bot here to serve and entertain. My commands are largely Easter-eggs... but you can always ask for !top5."
	s.RTM.PostMessage("#general", msgString, msgParams)
}
Esempio n. 24
0
func main() {
	log.SetPrefix("TWEELACK ")

	viper.SetConfigName("config")
	viper.AddConfigPath(".")
	viper.AddConfigPath("$HOME/.tweelack")

	err := viper.ReadInConfig()
	if err != nil {
		log.Fatalln(err)
	}

	twitterConsumerKey := viper.GetString("twitter.consumer.key")
	if len(twitterConsumerKey) == 0 {
		log.Fatalln("Twitter consumer key required")
	}
	twitterConsumerSecret := viper.GetString("twitter.consumer.secret")
	if len(twitterConsumerSecret) == 0 {
		log.Fatalln("Twitter consumer secret required")
	}
	twitterTokenValue := viper.GetString("twitter.token.value")
	if len(twitterTokenValue) == 0 {
		log.Fatalln("Twitter token value required")
	}
	twitterTokenSecret := viper.GetString("twitter.token.secret")
	if len(twitterTokenSecret) == 0 {
		log.Fatalln("Twitter token secret required")
	}
	if TwitterHandle = viper.GetString("twitter.handle"); len(TwitterHandle) == 0 {
		log.Fatalln("Twitter handle required")
	}
	if TweetCount = viper.GetInt("twitter.count"); TweetCount == 0 {
		TweetCount = 1
	}
	if TwitterTimeout = viper.GetDuration("twitter.timeout"); TwitterTimeout == 0 {
		TwitterTimeout = 1
	}
	TwitterHashtag = viper.GetString("twitter.hashtag")

	slackToken := viper.GetString("slack.token")
	if len(slackToken) == 0 {
		log.Fatalln("Slack token required")
	}

	if SlackChannel = viper.GetString("slack.channel"); len(SlackChannel) == 0 {
		SlackChannel = "general"
	}

	if Purpose = viper.GetString("slack.purpose"); len(Purpose) == 0 {
		Purpose = "post"
	}

	SlackMessageParameters = slack.NewPostMessageParameters()
	SlackMessageParameters.AsUser = viper.GetBool("slack.parameters.as_user")
	SlackMessageParameters.Username = viper.GetString("slack.parameters.username")
	SlackMessageParameters.IconURL = viper.GetString("slack.parameters.icon.url")
	SlackMessageParameters.IconEmoji = viper.GetString("slack.parameters.icon.emoji")

	anaconda.SetConsumerKey(twitterConsumerKey)
	anaconda.SetConsumerSecret(twitterConsumerSecret)
	TwitterApi = anaconda.NewTwitterApi(twitterTokenValue, twitterTokenSecret)
	SlackApi = slack.New(slackToken)

	UrlValues = url.Values{}
	UrlValues.Set("screen_name", TwitterHandle)
	UrlValues.Set("exclude_replies", "true")
	UrlValues.Set("include_rts", "false")

	if channels, err := SlackApi.GetChannels(true); err == nil {
		for _, channel := range channels {
			if channel.Name == SlackChannel {
				SlackChannel = channel.ID
				break
			}
		}
	}

	PostToSlack(FetchTweets())
}
Esempio n. 25
0
func (r *Response) MParams() slack.PostMessageParameters {
	msgParams := slack.NewPostMessageParameters()
	msgParams.AsUser = true
	msgParams.LinkNames = 1
	return msgParams
}
Esempio n. 26
0
func (c *LogCommand) Run(m *sl.MessageEvent, args ...string) {
	loggers := system.LoggerHookInstance.GetRecords()

	if len(args) == 0 {
		params := sl.NewPostMessageParameters()
		params.Attachments = []sl.Attachment{sl.Attachment{
			Color:  "good",
			Fields: []sl.AttachmentField{},
		}}

		for name := range loggers {
			params.Attachments[0].Fields = append(params.Attachments[0].Fields, sl.AttachmentField{
				Title: name,
			})
		}

		c.SendPostMessage(m.Channel, "Available components", params)
		return
	}

	showItemsCount := system.MaxItems
	if len(args) == 2 {
		var err error
		if showItemsCount, err = strconv.Atoi(args[1]); err != nil {
			c.SendMessage(m.Channel, "Specified number of records to display is not a number")
			return
		}
	}

	component, ok := loggers[args[0]]
	if !ok {
		c.SendMessagef(m.Channel, "Component *%s* does't exists", args[0])
		return
	}

	if len(component) == 0 {
		c.SendMessagef(m.Channel, "Log empty for *%s* component", args[0])
		return
	}

	skip := -1
	if showItemsCount < len(component) {
		skip = len(component) - showItemsCount
	} else {
		showItemsCount = len(component)
	}

	var (
		color      string
		index      int64
		attachment sl.Attachment
	)

	params := sl.NewPostMessageParameters()
	params.Attachments = make([]sl.Attachment, showItemsCount)

	for i, c := range component {
		if i < skip {
			continue
		}

		switch c.Level {
		case logrus.DebugLevel:
			color = "#999999"
		case logrus.InfoLevel:
			color = "#5bc0de"
		case logrus.WarnLevel:
			color = "warning"
		case logrus.ErrorLevel:
			color = "danger"
		case logrus.FatalLevel:
			color = "danger"
		case logrus.PanicLevel:
			color = "danger"
		default:
			color = "good"
		}

		attachment = sl.Attachment{
			Color:  color,
			Title:  c.Time.Format(time.RFC1123Z),
			Text:   c.Message,
			Fields: []sl.AttachmentField{},
		}

		for field, value := range component[i].Data {
			if field == "component" {
				continue
			}

			attachment.Fields = append(attachment.Fields, sl.AttachmentField{
				Title: field,
				Value: fmt.Sprintf("%v", value),
				Short: true,
			})
		}

		params.Attachments[index] = attachment
		index = index + 1
	}

	c.SendPostMessage(m.Channel, fmt.Sprintf("Show last *%d* entries for *%s* component", showItemsCount, args[0]), params)
}
Esempio n. 27
0
func (s *SlackSession) handleMessage(User string, Channel string, msg *slack.Msg) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()

	// Check user type; ignore bots
	{
		if msg.SubType == "bot_message" {
			return
		}
		var is_bot bool
		if err = tx.QueryRow("select user_is_bot from users where user_id = $1 and team_id = $2",
			User, s.TeamID).Scan(&is_bot); err != nil {
			s.log.WithError(err).Warn("Failed to read row")
			goto fail
		}
		if is_bot {
			s.log.Debug("Ignoring message; from bot")
			return
		}
	}

	if match := rxProposal.FindStringSubmatch(msg.Text); match != nil {
		s.log.WithField("matchgroups", fmt.Sprintf("%#v", match)).Info("Saw proposal")
		topic := match[1]
		comment := match[2]

		_, err = tx.Exec(
			"INSERT INTO topics (team_id, topic_channel, topic_name, topic_comment) "+
				"VALUES ($1, $2, $3, nullif($4,''))",
			s.TeamID, Channel, topic, comment)
		if err != nil {
			// TODO: report error in channel
			s.log.WithError(err).Info("Failed to insert proposal")
			goto fail
		}
		pmp := slack.NewPostMessageParameters()
		pmp.AsUser = true
		//pmp.Username = s.rtm.GetInfo().User.Name
		_, _, err = s.rtm.PostMessage(Channel, fmt.Sprintf("Voting is now open on %s", topic), pmp)
		if err != nil {
			log.WithError(err).Info("Failed to post voting open message")
		}

	} else if match := rxVote.FindStringSubmatch(msg.Text); match != nil {
		var value decimal.Decimal
		topic := match[2]
		log := s.log.WithFields(log.Fields{
			"topic":    topic,
			"user":     User,
			"channel":  msg.Channel,
			"user_msg": msg.Text,
		})
		if value, err = decimal.NewFromString(match[1]); err != nil {
			log.WithError(err).Info("Failed to parse vote value")
			return
		}
		comment := match[3]

		_, err = tx.Exec(
			"INSERT INTO votes (team_id, topic_name, user_id, vote_value, vote_comment) "+
				"VALUES ($1, $2, $3, $4, nullif($5, '')) "+
				"ON CONFLICT (topic_name, team_id, user_id) "+
				"DO UPDATE SET (vote_value, vote_comment) = ($4, nullif($5, ''))",
			s.TeamID, topic, User, value, comment)
		if err != nil {
			log.WithError(err).Info("Failed to insert vote")
		}
		log.WithField("matchgroups", fmt.Sprintf("%#v", match)).Info("Saw vote")
	} else if match := s.rxAtMessage.FindStringSubmatch(msg.Text); match != nil {
		args, err := shlex.Split(match[1], true)
		pmp := slack.NewPostMessageParameters()
		pmp.AsUser = true
		pmp.EscapeText = false
		user_pfx := fmt.Sprintf("<@%s>: ", msg.User)
		if err != nil || len(args) < 1 {
			s.rtm.PostMessage(Channel, user_pfx+" Syntax error: %s"+err.Error(), pmp)
			return
		}
		switch strings.ToLower(args[0]) {
		case "howdy":
			s.rtm.PostMessage(Channel, user_pfx+" Howdy neighbor!", pmp)
		case "status":
			if len(args) < 2 {
				topics := []map[string]interface{}{}
				rows, err := tx.Query(
					"SELECT topic_name, COALESCE(topic_comment, ''), COUNT(user_id), SUM(vote_value) "+
						"FROM topics NATURAL LEFT JOIN (votes NATURAL JOIN users) "+
						"WHERE topic_open AND team_id = $1 AND topic_channel = $2 "+
						"GROUP BY topic_name, topic_channel, team_id, topic_comment",
					s.TeamID, Channel)
				if err != nil {
					log.WithError(err).Error("Failed to query topics")
					return
				}
				for rows.Next() {
					var (
						name, comment string
						count         int
						sum           decimal.Decimal
					)
					rows.Scan(&name, &comment, &count, &sum)
					topics = append(topics, map[string]interface{}{
						"name":    name,
						"comment": comment,
						"nvotes":  count,
						"total":   sum,
					})
				}
				buffer := &bytes.Buffer{}
				topicSummary.Execute(buffer, topics)
				s.rtm.PostMessage(Channel, buffer.String(), pmp)
			}

		default:
			s.rtm.PostMessage(Channel, fmt.Sprintf("%s You seem confused; you said `%#v`", user_pfx, args), pmp)
		}
	}
	tx.Commit()
	return
fail:
}

/* Sample message
var foo = &slack.MessageEvent{Msg: slack.Msg{
	Type:      "message",
	Channel:   "C0KGNAP7A",
	User:      "******",
	Text:      "More testage",
	Timestamp: "1454444512.000011",
	IsStarred: false, PinnedTo: []string(nil),
	Attachments: []slack.Attachment(nil), Edited: (*slack.Edited)(nil),
	SubType: "", Hidden: false,
	DeletedTimestamp: "",
	EventTimestamp:   "", BotID: "", Username: "", Icons: (*slack.Icon)(nil),
	Inviter: "", Topic: "", Purpose: "", Name: "", OldName: "", Members: []string(nil),
	File: (*slack.File)(nil), Upload: false, Comment: (*slack.Comment)(nil),
	ItemType: "", ReplyTo: 0, Team: "T06RWKEF3"}}
*/

func (s *SlackSession) updateUser(user slack.User) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()
	if _, err = tx.Exec(
		"INSERT INTO users (team_id, user_id, user_name, user_is_bot) VALUES ($3, $2, $1, $4) "+
			"ON CONFLICT (team_id, user_id) DO UPDATE SET (user_name, user_is_bot) = ($1, $4)",
		user.Name, user.ID, s.TeamID, user.IsBot); err != nil {

		goto fail
	}
	if err = tx.Commit(); err != nil {
		goto fail
	}
	return

fail:
	if err != nil {
		s.log.WithError(err).WithField("user", user.ID).Error("Failed to refresh user in db")
	}

}

func (s *SlackSession) updateTeam(team *slack.Team) {
	tx, err := s.Db.Begin()
	if err != nil {
		goto fail
	}
	defer tx.Rollback()
	if _, err = tx.Exec("UPDATE teams SET (team_name) = ($1) WHERE team_id = $2", team.Name, team.ID); err != nil {
		goto fail
	}
	if err = tx.Commit(); err != nil {
		goto fail
	}
	return

fail:
	if err != nil {
		s.log.WithError(err).Error("Failed to refresh team in db")
	}

}
Esempio n. 28
0
func mindTwitch() {
	log.Println("[tw] Starting up")
	if buf, err := ioutil.ReadFile(twitchConfigFile); err != nil {
		log.Fatal(err)
	} else {
		if err := json.Unmarshal(buf, &twitchCFG); err != nil {
			log.Fatal(err)
		}
	}
	client, err := twch.NewClient(twitchCFG.Key, nil)
	if err != nil {
		log.Fatal(err)
	}

	var active = map[string]int{}
	var lastActive = map[string]time.Time{}

	var twitchTicker = time.Tick(time.Second)
	for {
		streamers := map[string]bool{}
		nextRun := time.Now().Add(1 * time.Minute)
		for _, c := range twitchCFG.Channels {
			<-twitchTicker
			found := false
			if s, _, err := client.Streams.GetStream(c); err == nil {
				if s.ID != nil {
					details, _ := json.MarshalIndent(s, "\t", "\t")
					detailsString := string(details)
					streamers[c] = true
					sid := *s.ID
					if oid, ok := active[c]; ok {
						if oid != sid {
							found = true
							log.Printf(
								"[tw] Found changed stream for %s id: %d -> %d\n%s",
								c, oid, *s.ID, detailsString,
							)
						} else {
							lastActive[c] = time.Now()
							log.Printf(
								"[tw] Continued twitch stream for %s id: %d\n",
								c, *s.ID,
							)
						}
					} else {
						found = true
						log.Printf(
							"[tw] Found twitch stream for %s id: %d\n%s",
							c, *s.ID, detailsString,
						)
					}
					if found {
						active[c] = sid
						lastSeen := time.Now().Add(0 - (24 * time.Hour))
						if ls, ok := lastActive[c]; ok {
							lastSeen = ls
						}
						lastActive[c] = time.Now()
						if time.Now().Sub(lastSeen) < (15 * time.Minute) {
							log.Printf(
								"[tw] Skipping twitch %s because of recent activity %s ago",
								c,
								time.Now().Sub(lastSeen).String(),
							)
							continue
						}
						displayName := c
						if s.Channel.DisplayName != nil {
							displayName = *s.Channel.DisplayName
						}
						game := "something"
						if s.Game != nil {
							game = *s.Game
						}
						messageParams := slack.NewPostMessageParameters()
						messageParams.AsUser = true
						messageParams.Parse = "full"
						messageParams.LinkNames = 1
						messageParams.UnfurlMedia = true
						messageParams.UnfurlLinks = true
						messageParams.EscapeText = false
						messageParams.Attachments = append(messageParams.Attachments, slack.Attachment{
							Title:     fmt.Sprintf("Watch %s play %s", displayName, game),
							TitleLink: *s.Channel.URL,
							ThumbURL:  *s.Preview.Small,
						})
						_, _, err := slackClient.PostMessage(
							slackCFG.Channel,
							fmt.Sprintf("*%s* has begun streaming *%s* at %s", *s.Channel.Name, game, *s.Channel.URL),
							messageParams,
						)
						if err != nil {
							log.Printf("[tw] Error sending slack message: %s", err.Error())
						}
					}
				} else {
					log.Printf("[tw] Found no twitch stream for %s", c)
				}
			} else {
				log.Printf("[tw] Error checking twitch stream: %s", err.Error())
			}
		}
		for k := range active {
			if _, ok := streamers[k]; !ok {
				log.Printf("[tw] Removing twitch stream: %s", k)
				delete(active, k)
			}
		}
		for k := range lastActive {
			if time.Now().Sub(lastActive[k]) > (30 * time.Minute) {
				log.Printf("[tw] Removing last activity marker for twitch stream: %s", k)
				delete(lastActive, k)
			}
		}
		sleepFor := nextRun.Sub(time.Now())
		if sleepFor < (15 * time.Second) {
			sleepFor = 15 * time.Second
		}
		time.Sleep(sleepFor)
	}
}
Esempio n. 29
0
func main() {
	var info slack.Info
	quothPattern := regexp.MustCompile(`^(?i:quoth(?:\s+(\S+))?)`)
	deletePattern := regexp.MustCompile(`^(?i:forget ([A-Za-z0-9]{24}))`)
	bracketRemovalPattern := regexp.MustCompile(`<(.*?)>`)

	rand.Seed(time.Now().UnixNano())
	// Read config.toml
	config, err := toml.LoadFile("config.toml")
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error opening config file. Did you remember to `cp config.toml.example config.toml`?\n", err.Error())
		os.Exit(1)
	}

	apiToken := config.Get("slack-quoter.api_token").(string)
	channelKey := config.Get("slack-quoter.channel_key").(string)
	mongoDBServer := config.Get("slack-quoter.mongodb_server").(string)

	session, err := mgo.Dial(mongoDBServer)
	if err != nil {
		panic(err)
	}
	defer session.Close()
	col := session.DB("slack").C("quotes")

	api := slack.New(apiToken)
	api.SetDebug(true)

	postMessageParams := slack.NewPostMessageParameters()
	postMessageParams.AsUser = true
	postMessageParams.UnfurlLinks = true

	rtm := api.NewRTM()
	go rtm.ManageConnection()

Loop:
	for {
		select {
		case msg := <-rtm.IncomingEvents:
			fmt.Print("Event Received: ")
			switch ev := msg.Data.(type) {
			case *slack.HelloEvent:
				// Ignore hello

			case *slack.ConnectedEvent:
				info = *(ev.Info)
				fmt.Println("Connection counter:", ev.ConnectionCount)
				// Replace #general with your Channel ID

			case *slack.MessageEvent:
				var quote MessageWithID
				if ev.Channel != channelKey {
					continue
				}

				if matches := quothPattern.FindStringSubmatch(ev.Text); matches != nil {
					// Ignore bot users and ourselves.
					requester := info.GetUserByID(ev.User)
					if requester != nil && (requester.IsBot || info.User.ID == ev.User) {
						continue
					}
					var user *slack.User
					if matches[1] != "" {
						user = getUserForName(matches[1], info)
					}
					var query *mgo.Query
					if user != nil {
						query = col.Find(bson.M{"user": user.ID})
					} else {
						query = col.Find(nil)
					}
					count, err := query.Count()
					if err != nil {
						fmt.Println("Error gettings count: ", err)
						continue
					}
					if count == 0 {
						rtm.SendMessage(rtm.NewOutgoingMessage("No quotes. Consider better posting.", channelKey))
						continue
					}
					query.Skip(rand.Intn(count)).One(&quote)

					// We have a random quote now. Print to the channel.
					if user == nil {
						user = info.GetUserByID(quote.User)
					}
					var name string
					if user != nil {
						name = user.Name
					} else {
						name = "UNKNOWN"
					}

					quoteText := bracketRemovalPattern.ReplaceAllString(quote.Text, "$1")
					api.PostMessage(channelKey, fmt.Sprintf("Quoth %s:\t\t\t\t\t\t(%s)\n%s", name, quote.ID.Hex(), quoteText), postMessageParams)
				} else if matches := deletePattern.FindStringSubmatch(ev.Text); matches != nil {
					err := col.RemoveId(bson.ObjectIdHex(matches[1]))
					if err == mgo.ErrNotFound {
						rtm.SendMessage(rtm.NewOutgoingMessage(fmt.Sprintf("What %s? No %ss here.", matches[1], matches[1]), channelKey))
					} else {
						rtm.SendMessage(rtm.NewOutgoingMessage("Beleted "+matches[1]+".", channelKey))
					}
				}

			case *slack.PresenceChangeEvent:
				fmt.Printf("Presence Change: %v\n", ev)

			case *slack.LatencyReport:
				fmt.Printf("Current latency: %v\n", ev.Value)

			case *slack.RTMError:
				fmt.Printf("Error: %s\n", ev.Error())

			case *slack.InvalidAuthEvent:
				fmt.Printf("Invalid credentials")
				break Loop

			case *slack.StarAddedEvent:
				if ev.Item.Type != "message" {
					continue
				}
				col.Upsert(ev.Item.Message.Msg, ev.Item.Message.Msg)

			default:
				// Ignore other events..
				// fmt.Printf("Unexpected: %v\n", msg.Data)
			}
		}
	}
}