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  }