github.com/matthieudolci/hatcher@v0.2.8/bot/listen.go (about) 1 package bot 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "strings" 8 9 "github.com/matthieudolci/hatcher/common" 10 "github.com/matthieudolci/hatcher/help" 11 "github.com/matthieudolci/hatcher/setup" 12 "github.com/matthieudolci/hatcher/standup" 13 14 log "github.com/Sirupsen/logrus" 15 "github.com/slack-go/slack" 16 ) 17 18 // New returns a new instance of the Slack struct, primary for our slackbot 19 func New() (*common.Slack, error) { 20 token := os.Getenv("SLACK_TOKEN") 21 if len(token) == 0 { 22 return nil, fmt.Errorf("Could not discover API token") 23 } 24 25 return &common.Slack{Client: slack.New(token), Token: token, Name: "hatcher"}, nil 26 } 27 28 // Run is the primary service to generate and kick off the slackbot listener 29 // This portion receives all incoming Real Time Messages notices from the workspace 30 // as registered by the API token 31 func Run(ctx context.Context, s *common.Slack) error { 32 authTest, err := s.Client.AuthTest() 33 if err != nil { 34 return fmt.Errorf("Did not authenticate: %+v", err) 35 } 36 37 s.User = authTest.User 38 s.UserID = authTest.UserID 39 40 log.WithFields(log.Fields{ 41 "username": s.User, 42 "userid": s.UserID, 43 }).Info("Bot is now registered") 44 45 go run(ctx, s) 46 return nil 47 48 } 49 50 func run(ctx context.Context, s *common.Slack) { 51 // slack.SetLogger() 52 // s.Client.SetDebug(true) 53 54 rtm := s.Client.NewRTM() 55 go rtm.ManageConnection() 56 57 log.Info("Now listening for incoming messages...") 58 59 for msg := range rtm.IncomingEvents { 60 switch x := msg.Data.(type) { 61 case *slack.MessageEvent: 62 if x.SubType == "message_changed" { 63 err := standup.CheckIfYesterdayMessageEdited(s, x) 64 if err != nil { 65 log.WithFields(log.Fields{ 66 "userid": x.User, 67 }).WithError(err).Error("Checking if yesterday standup was edited") 68 } 69 err = standup.CheckIfTodayMessageEdited(s, x) 70 if err != nil { 71 log.WithFields(log.Fields{ 72 "userid": x.User, 73 }).WithError(err).Error("Checking if yesterday standup was edited") 74 } 75 err = standup.CheckIfBlockerMessageEdited(s, x) 76 if err != nil { 77 log.WithFields(log.Fields{ 78 "userid": x.User, 79 }).WithError(err).Error("Checking if yesterday standup was edited") 80 } 81 } 82 } 83 switch ev := msg.Data.(type) { 84 case *slack.MessageEvent: 85 if len(ev.User) == 0 { 86 continue 87 } 88 89 // check if we have a DM, or standard channel post 90 direct := strings.HasPrefix(ev.Msg.Channel, "D") 91 inchannel := strings.Contains(ev.Msg.Text, "@"+s.UserID) 92 93 if !direct && !inchannel { 94 // msg not for us! 95 continue 96 } 97 98 user, err := s.Client.GetUserInfo(ev.User) 99 if err != nil { 100 log.WithFields(log.Fields{ 101 "userid": ev.User, 102 }).Printf("Could not grab user information.") 103 continue 104 } 105 106 log.WithFields(log.Fields{ 107 "username": user.Profile.RealName, 108 "userid": ev.User, 109 }).Info("Received message") 110 111 err = setup.AskSetup(s, ev) 112 if err != nil { 113 log.WithFields(log.Fields{ 114 "username": user.Profile.RealName, 115 "userid": ev.User, 116 }).WithError(err).Error("Posting setup reply to user") 117 } 118 119 err = setup.AskRemove(s, ev) 120 if err != nil { 121 log.WithFields(log.Fields{ 122 "username": user.Profile.RealName, 123 "userid": ev.User, 124 }).WithError(err).Error("Posting remove reply to user") 125 } 126 127 err = standup.AskStandupYesterday(s, ev) 128 if err != nil { 129 log.WithFields(log.Fields{ 130 "username": user.Profile.RealName, 131 "userid": ev.User, 132 }).WithError(err).Error("Posting yesterday standup note question to user") 133 } 134 135 err = help.AskHelp(s, ev) 136 if err != nil { 137 log.WithFields(log.Fields{ 138 "username": user.Profile.RealName, 139 "userid": ev.User, 140 }).WithError(err).Error("Posting help message") 141 } 142 143 case *slack.RTMError: 144 log.Errorf("%s", ev.Error()) 145 } 146 } 147 }