github.com/matthieudolci/hatcher@v0.2.8/setup/setup.go (about)

     1  package setup
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"strings"
     7  
     8  	log "github.com/Sirupsen/logrus"
     9  	"github.com/matthieudolci/hatcher/common"
    10  	"github.com/matthieudolci/hatcher/database"
    11  	"github.com/slack-go/slack"
    12  )
    13  
    14  // AskSetup Asks the first question on the user init process
    15  // At this point the user can still cancel the stup
    16  func AskSetup(s *common.Slack, ev *slack.MessageEvent) error {
    17  
    18  	text := ev.Text
    19  	text = strings.TrimSpace(text)
    20  	text = strings.ToLower(text)
    21  
    22  	acceptedHello := map[string]bool{
    23  		"hello": true,
    24  	}
    25  
    26  	if acceptedHello[text] {
    27  		params := slack.PostMessageParameters{}
    28  		attachment := slack.Attachment{
    29  			Text:       "Do you want to setup/update your user with the bot Hatcher?",
    30  			CallbackID: fmt.Sprintf("setup_%s", ev.User),
    31  			Color:      "#AED6F1",
    32  			Actions: []slack.AttachmentAction{
    33  				{
    34  					Name:  "SetupYes",
    35  					Text:  "Yes",
    36  					Type:  "button",
    37  					Value: "SetupYes",
    38  					Style: "primary",
    39  				},
    40  				{
    41  					Name:  "SetupNo",
    42  					Text:  "No",
    43  					Type:  "button",
    44  					Value: "SetupNo",
    45  					Style: "danger",
    46  				},
    47  			},
    48  		}
    49  
    50  		params.User = ev.User
    51  		params.AsUser = true
    52  
    53  		_, err := s.Client.PostEphemeral(
    54  			ev.Channel,
    55  			ev.User,
    56  			slack.MsgOptionAttachments(attachment),
    57  			slack.MsgOptionPostMessageParameters(params),
    58  		)
    59  		if err != nil {
    60  			log.WithError(err).Error("Could not post askSetup question")
    61  		}
    62  		log.WithFields(log.Fields{
    63  			"userid":  ev.User,
    64  			"channel": ev.Channel,
    65  		}).Info("Message for askSetup posted")
    66  	}
    67  	return nil
    68  }
    69  
    70  // InitBot is the first step of using this bot.
    71  // It will insert the user informations inside the database allowing us
    72  // to use them
    73  func InitBot(userid, email, fullname, displayname string) error {
    74  
    75  	var id string
    76  
    77  	sqlCheckID := `SELECT userid FROM hatcher.users WHERE userid=$1;`
    78  	row := database.DB.QueryRow(sqlCheckID, userid)
    79  	switch err := row.Scan(&id); err {
    80  	// if user doesnt exit creates it in the database
    81  	case sql.ErrNoRows:
    82  		sqlWrite := `
    83  		INSERT INTO hatcher.users (userid, email, full_name, displayname)
    84  		VALUES ($1, $2, $3, $4)
    85  		RETURNING id`
    86  		err = database.DB.QueryRow(sqlWrite, userid, email, fullname, displayname).Scan(&userid)
    87  		if err != nil {
    88  			log.WithFields(log.Fields{
    89  				"username": fullname,
    90  				"userid":   userid,
    91  			}).WithError(err).Error("Could not create user")
    92  		}
    93  		log.WithFields(log.Fields{
    94  			"username": fullname,
    95  			"userid":   userid,
    96  		}).Info("User was created")
    97  
    98  	// If the user exist it will update it
    99  	case nil:
   100  		sqlUpdate := `
   101  		UPDATE hatcher.users
   102  		SET full_name = $2, email = $3, displayname = $4 
   103  		WHERE userid = $1
   104  		RETURNING id;`
   105  		err = database.DB.QueryRow(sqlUpdate, userid, fullname, email, displayname).Scan(&userid)
   106  		if err != nil {
   107  			log.WithFields(log.Fields{
   108  				"username": fullname,
   109  				"userid":   userid,
   110  			}).WithError(err).Error("Couldn't update user in the database")
   111  		}
   112  		log.WithFields(log.Fields{
   113  			"username": fullname,
   114  			"userid":   userid,
   115  		}).Info("User was creaupdatedted")
   116  	default:
   117  	}
   118  	return nil
   119  }
   120  
   121  // AskRemove Asks if we want to remove our user from the bot
   122  // This will delete the user from the datatbase
   123  func AskRemove(s *common.Slack, ev *slack.MessageEvent) error {
   124  	text := ev.Text
   125  	text = strings.TrimSpace(text)
   126  	text = strings.ToLower(text)
   127  
   128  	acceptedRemove := map[string]bool{
   129  		"remove": true,
   130  		"delete": true,
   131  	}
   132  
   133  	if acceptedRemove[text] {
   134  		params := slack.PostMessageParameters{}
   135  		attachment := slack.Attachment{
   136  			Text:       "Do you want to delete your user?",
   137  			CallbackID: fmt.Sprintf("remove_%s", ev.User),
   138  			Color:      "#FF0000",
   139  			Actions: []slack.AttachmentAction{
   140  				{
   141  					Name:  "RemoveYes",
   142  					Text:  "Yes",
   143  					Type:  "button",
   144  					Value: "RemoveYes",
   145  					Style: "primary",
   146  				},
   147  				{
   148  					Name:  "RemoveNo",
   149  					Text:  "No",
   150  					Type:  "button",
   151  					Value: "RemoveNo",
   152  					Style: "danger",
   153  				},
   154  			},
   155  		}
   156  
   157  		params.User = ev.User
   158  		params.AsUser = true
   159  
   160  		_, err := s.Client.PostEphemeral(
   161  			ev.Channel,
   162  			ev.User,
   163  			slack.MsgOptionAttachments(attachment),
   164  			slack.MsgOptionPostMessageParameters(params),
   165  		)
   166  		if err != nil {
   167  			log.WithFields(log.Fields{
   168  				"channel": ev.Channel,
   169  				"userid":  ev.User,
   170  			}).WithError(err).Error("Could not post message for askRemove")
   171  		}
   172  		log.WithFields(log.Fields{
   173  			"channel": ev.Channel,
   174  			"userid":  ev.User,
   175  		}).Info("Message for askRemove posted")
   176  	}
   177  	return nil
   178  }
   179  
   180  // RemoveBot remove the user from the bot/database
   181  func RemoveBot(userid, fullname string) error {
   182  
   183  	sqlDelete := `
   184  		DELETE FROM hatcher.users
   185  		WHERE userid = $1;`
   186  	_, err := database.DB.Exec(sqlDelete, userid)
   187  	if err != nil {
   188  		log.WithFields(log.Fields{
   189  			"userid":   userid,
   190  			"username": fullname,
   191  		}).WithError(err).Error("Couldn't not check if user exist in the database")
   192  	}
   193  	log.WithFields(log.Fields{
   194  		"username": fullname,
   195  		"userid":   userid,
   196  	}).Info("User was deleted")
   197  
   198  	return nil
   199  }
   200  
   201  // AskWhoIsManager Ask who is the user manager
   202  func AskWhoIsManager(s *common.Slack, channelid, userid string) error {
   203  
   204  	params := slack.PostMessageParameters{}
   205  	attachment := slack.Attachment{
   206  		Text:       "Who is your manager?",
   207  		CallbackID: fmt.Sprintf("manager_%s", userid),
   208  		Color:      "#AED6F1",
   209  		Actions: []slack.AttachmentAction{
   210  			{
   211  				Name:       "ManagerChosen",
   212  				Text:       "Type to filter option",
   213  				Type:       "select",
   214  				DataSource: "users",
   215  			},
   216  			{
   217  				Name:  "NoManagerChosen",
   218  				Text:  "No Manager",
   219  				Type:  "button",
   220  				Value: "NoManagerChosen",
   221  				Style: "danger",
   222  			},
   223  		},
   224  	}
   225  
   226  	params.User = userid
   227  	params.AsUser = true
   228  
   229  	_, err := s.Client.PostEphemeral(
   230  		channelid,
   231  		userid,
   232  		slack.MsgOptionAttachments(attachment),
   233  		slack.MsgOptionPostMessageParameters(params),
   234  	)
   235  	if err != nil {
   236  		log.WithFields(log.Fields{
   237  			"userid":  userid,
   238  			"channel": channelid,
   239  		}).WithError(err).Error("Could not post message askWhoIsManager")
   240  	}
   241  	log.WithFields(log.Fields{
   242  		"userid":  userid,
   243  		"channel": channelid,
   244  	}).Info("Message for askWhoIsManager posted")
   245  	return nil
   246  }
   247  
   248  // InitManager Add the person select previously in askWhoIsManager to the user profile
   249  func InitManager(userid, fullname, managerid, managername string) error {
   250  
   251  	sqlUpdate := `
   252  		UPDATE hatcher.users
   253  		SET managerid = $2
   254  		WHERE userid = $1
   255  		RETURNING id;`
   256  	err := database.DB.QueryRow(sqlUpdate, userid, managerid).Scan(&userid)
   257  	if err != nil {
   258  		log.WithFields(log.Fields{
   259  			"userid":    userid,
   260  			"username":  fullname,
   261  			"managerid": managerid,
   262  		}).WithError(err).Error("Couldn't update the manager")
   263  	}
   264  	log.WithFields(log.Fields{
   265  		"username":  fullname,
   266  		"userid":    userid,
   267  		"managerid": managerid,
   268  	}).Info("Manager was added to user")
   269  	return nil
   270  }
   271  
   272  // AskIfManager Asks if the user if a manager
   273  func AskIfManager(s *common.Slack, channelid, userid string) error {
   274  
   275  	params := slack.PostMessageParameters{}
   276  	attachment := slack.Attachment{
   277  		Text:       "Do you manage a team with a daily standup?",
   278  		CallbackID: fmt.Sprintf("ismanager_%s", userid),
   279  		Color:      "#AED6F1",
   280  		Actions: []slack.AttachmentAction{
   281  			{
   282  				Name:  "isManagerYes",
   283  				Text:  "Yes",
   284  				Type:  "button",
   285  				Value: "isManagerYes",
   286  				Style: "primary",
   287  			},
   288  			{
   289  				Name:  "isManagerNo",
   290  				Text:  "No",
   291  				Type:  "button",
   292  				Value: "isManagerNo",
   293  				Style: "danger",
   294  			},
   295  		},
   296  	}
   297  
   298  	params.User = userid
   299  	params.AsUser = true
   300  
   301  	_, err := s.Client.PostEphemeral(
   302  		channelid,
   303  		userid,
   304  		slack.MsgOptionAttachments(attachment),
   305  		slack.MsgOptionPostMessageParameters(params),
   306  	)
   307  	if err != nil {
   308  		log.WithFields(log.Fields{
   309  			"userid":  userid,
   310  			"channel": channelid,
   311  		}).WithError(err).Error("Could not post message for askIfManager")
   312  	}
   313  	log.WithFields(log.Fields{
   314  		"userid":  userid,
   315  		"channel": channelid,
   316  	}).Info("Message for askIfManager posted")
   317  	return nil
   318  }
   319  
   320  // IsManager Setups the user as a manager or not in the database
   321  func IsManager(userid, fullname, ismanager string) error {
   322  
   323  	sqlUpdate := `
   324  		UPDATE hatcher.users
   325  		SET ismanager = $2
   326  		WHERE userid = $1
   327  		RETURNING id;`
   328  	err := database.DB.QueryRow(sqlUpdate, userid, ismanager).Scan(&userid)
   329  	if err != nil {
   330  		log.WithFields(log.Fields{
   331  			"userid":   userid,
   332  			"username": fullname,
   333  		}).WithError(err).Error("Couldn't update if user is a manager")
   334  	}
   335  	if ismanager == "true" {
   336  		log.WithFields(log.Fields{
   337  			"username": fullname,
   338  			"userid":   userid,
   339  		}).Info("Now setup as a manager")
   340  	}
   341  	log.WithFields(log.Fields{
   342  		"username": fullname,
   343  		"userid":   userid,
   344  	}).Info("Is not setup as a manager")
   345  
   346  	return nil
   347  }
   348  
   349  // AskTimeStandup Asks what time the standup should happen
   350  func AskTimeStandup(s *common.Slack, channelid, userid string) error {
   351  
   352  	params := slack.PostMessageParameters{}
   353  	attachment := slack.Attachment{
   354  		Text:       "What time do you want your team standup to happen?",
   355  		CallbackID: fmt.Sprintf("standupTime_%s", userid),
   356  		Color:      "#AED6F1",
   357  		Actions: []slack.AttachmentAction{
   358  			{
   359  				Name: "StandupTime",
   360  				Type: "select",
   361  				Options: []slack.AttachmentActionOption{
   362  					{
   363  						Text:  "09:00",
   364  						Value: "09:00",
   365  					},
   366  					{
   367  						Text:  "09:15",
   368  						Value: "09:15",
   369  					},
   370  					{
   371  						Text:  "09:30",
   372  						Value: "09:30",
   373  					},
   374  					{
   375  						Text:  "09:45",
   376  						Value: "09:45",
   377  					},
   378  					{
   379  						Text:  "10:00",
   380  						Value: "10:00",
   381  					},
   382  					{
   383  						Text:  "10:15",
   384  						Value: "10:15",
   385  					},
   386  					{
   387  						Text:  "10:30",
   388  						Value: "10:30",
   389  					},
   390  					{
   391  						Text:  "10:45",
   392  						Value: "10:45",
   393  					},
   394  				},
   395  			},
   396  		},
   397  	}
   398  
   399  	params.User = userid
   400  	params.AsUser = true
   401  
   402  	_, err := s.Client.PostEphemeral(
   403  		channelid,
   404  		userid,
   405  		slack.MsgOptionAttachments(attachment),
   406  		slack.MsgOptionPostMessageParameters(params),
   407  	)
   408  	if err != nil {
   409  		log.WithFields(log.Fields{
   410  			"userid":  userid,
   411  			"channel": channelid,
   412  		}).WithError(err).Error("Could not post message askTimeStandup")
   413  	}
   414  	log.WithFields(log.Fields{
   415  		"userid":  userid,
   416  		"channel": channelid,
   417  	}).Info("Message askTimeStandup posted")
   418  	return nil
   419  }
   420  
   421  // InsertTimeStandup Insert in the database the result of askTimeStandup
   422  func InsertTimeStandup(userid, fullname, time string) error {
   423  
   424  	sqlUpdate := `
   425  		UPDATE hatcher.users
   426  		SET standup_schedule = $2
   427  		WHERE managerid = $1 OR userid = $1
   428  		RETURNING id;`
   429  	err := database.DB.QueryRow(sqlUpdate, userid, time).Scan(&userid)
   430  	if err != nil {
   431  		log.WithFields(log.Fields{
   432  			"userid":   userid,
   433  			"username": fullname,
   434  		}).WithError(err).Error("Couldn't update the standup time")
   435  	}
   436  	log.WithFields(log.Fields{
   437  		"username": fullname,
   438  		"userid":   userid,
   439  	}).Info("Standup time updated")
   440  
   441  	return nil
   442  }
   443  
   444  // GetStandupTimeFromManager Gets a standup time based on the manager standup time selected
   445  func GetStandupTimeFromManager(managerid string) (timeStandup string) {
   446  
   447  	var time string
   448  
   449  	rows, err := database.DB.Query("SELECT to_char(standup_schedule, 'HH24:MI') FROM hatcher.users WHERE userid = $1", managerid)
   450  	if err != nil {
   451  		if err == sql.ErrNoRows {
   452  			log.WithError(err).Error("There is no results")
   453  		}
   454  	}
   455  	defer rows.Close()
   456  	for rows.Next() {
   457  
   458  		err = rows.Scan(&time)
   459  		if err != nil {
   460  			log.WithError(err).Error("During the scan")
   461  		}
   462  	}
   463  	return time
   464  }
   465  
   466  // GetStandupChannelFromManager Gets a standup channel id based on the manager standup channel id selected
   467  func GetStandupChannelFromManager(managerid string) (channelStandup string) {
   468  
   469  	var channel string
   470  
   471  	rows, err := database.DB.Query("SELECT standup_channel FROM hatcher.users WHERE userid = $1", managerid)
   472  	if err != nil {
   473  		if err == sql.ErrNoRows {
   474  			log.WithError(err).Error("There is no results")
   475  		}
   476  	}
   477  	defer rows.Close()
   478  	for rows.Next() {
   479  
   480  		err = rows.Scan(&channel)
   481  		if err != nil {
   482  			log.WithError(err).Error("During the scan")
   483  		}
   484  	}
   485  	return channel
   486  }
   487  
   488  // UpdateTimeStandup Updates the standup time of a new user based on the time of the manager
   489  func UpdateTimeStandup(managerid, userid, time string) error {
   490  
   491  	var id string
   492  	if time == "NULL" {
   493  		sqlUpdate := `
   494  		UPDATE hatcher.users
   495  		SET standup_schedule = NULL
   496  		WHERE managerid = $1
   497  		RETURNING id;`
   498  		err := database.DB.QueryRow(sqlUpdate, managerid).Scan(&id)
   499  		if err != nil {
   500  			log.WithFields(log.Fields{
   501  				"managerid": managerid,
   502  				"userid":    userid,
   503  			}).WithError(err).Error("Couldn't update the standup time")
   504  		}
   505  		log.WithFields(log.Fields{
   506  			"userid":    userid,
   507  			"managerid": managerid,
   508  		}).Info("Standup time updated")
   509  	} else {
   510  		sqlUpdate := `
   511  		UPDATE hatcher.users
   512  		SET standup_schedule = $2
   513  		WHERE managerid = $1
   514  		RETURNING id;`
   515  		err := database.DB.QueryRow(sqlUpdate, managerid, time).Scan(&id)
   516  		if err != nil {
   517  			log.WithFields(log.Fields{
   518  				"managerid": managerid,
   519  				"userid":    userid,
   520  			}).WithError(err).Error("Couldn't update the standup time")
   521  		}
   522  		log.WithFields(log.Fields{
   523  			"userid":    userid,
   524  			"managerid": managerid,
   525  		}).Info("Standup time updated")
   526  	}
   527  
   528  	return nil
   529  }
   530  
   531  // UpdateChannelStandup Updates the standup channel of a new user based on the channel of the manager
   532  func UpdateChannelStandup(managerid, userid, channel string) error {
   533  
   534  	sqlUpdate := `
   535  		UPDATE hatcher.users
   536  		SET standup_channel = $2
   537  		WHERE managerid = $1
   538  		RETURNING id;`
   539  	err := database.DB.QueryRow(sqlUpdate, managerid, channel).Scan(&managerid)
   540  	if err != nil {
   541  		log.WithFields(log.Fields{
   542  			"managerid": managerid,
   543  			"userid":    userid,
   544  		}).WithError(err).Error("Couldn't update the standup time")
   545  	}
   546  	log.WithFields(log.Fields{
   547  		"userid":    userid,
   548  		"managerid": managerid,
   549  	}).Info("Standup time updated")
   550  	return nil
   551  }
   552  
   553  // AskWhichChannelStandup Asks in which channel to post the standup results
   554  func AskWhichChannelStandup(s *common.Slack, channelid, userid string) error {
   555  
   556  	params := slack.PostMessageParameters{}
   557  	attachment := slack.Attachment{
   558  		Text:       "In which channel do you want to post your standup results?",
   559  		CallbackID: fmt.Sprintf("manager_%s", userid),
   560  		Color:      "#AED6F1",
   561  		Actions: []slack.AttachmentAction{
   562  			{
   563  				Name:       "ChannelStandupChosen",
   564  				Text:       "Type to filter option",
   565  				Type:       "select",
   566  				DataSource: "channels",
   567  			},
   568  		},
   569  	}
   570  
   571  	params.User = userid
   572  	params.AsUser = true
   573  
   574  	_, err := s.Client.PostEphemeral(
   575  		channelid,
   576  		userid,
   577  		slack.MsgOptionAttachments(attachment),
   578  		slack.MsgOptionPostMessageParameters(params),
   579  	)
   580  	if err != nil {
   581  		log.WithFields(log.Fields{
   582  			"userid":  userid,
   583  			"channel": channelid,
   584  		}).WithError(err).Error("Could not post message askWhichChannelStandup")
   585  	}
   586  	log.WithFields(log.Fields{
   587  		"userid":  userid,
   588  		"channel": channelid,
   589  	}).Info("Message for askWhichChannelStandup posted")
   590  	return nil
   591  }
   592  
   593  // InsertChannelStandup Inserts in the database the result of askWhichChannelStandup
   594  func InsertChannelStandup(userid, fullname, channel string) error {
   595  
   596  	sqlUpdate := `
   597  		UPDATE hatcher.users
   598  		SET standup_channel = $2
   599  		WHERE userid = $1 OR managerid = $1
   600  		RETURNING id;`
   601  	err := database.DB.QueryRow(sqlUpdate, userid, channel).Scan(&userid)
   602  	if err != nil {
   603  		log.WithFields(log.Fields{
   604  			"userid":   userid,
   605  			"username": fullname,
   606  		}).WithError(err).Error("Couldn't update the channel for the standup results")
   607  	}
   608  	log.WithFields(log.Fields{
   609  		"username": fullname,
   610  		"userid":   userid,
   611  	}).Info("Channel for standup results updated")
   612  	return nil
   613  }