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

     1  package standup
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"strings"
     7  	"time"
     8  
     9  	log "github.com/Sirupsen/logrus"
    10  	"github.com/matthieudolci/hatcher/common"
    11  	"github.com/matthieudolci/hatcher/database"
    12  	"github.com/slack-go/slack"
    13  )
    14  
    15  func AskStandupYesterday(s *common.Slack, ev *slack.MessageEvent) error {
    16  
    17  	t := time.Now().Local().Format("2006-01-02")
    18  	t2 := time.Now().Local().Format("15:04:05")
    19  	date := fmt.Sprint(t)
    20  	times := fmt.Sprint(t2)
    21  
    22  	timer := time.NewTimer(10 * time.Minute)
    23  	ticker := time.NewTicker(3 * time.Second)
    24  
    25  	text := ev.Text
    26  	text = strings.TrimSpace(text)
    27  	text = strings.ToLower(text)
    28  
    29  	acceptedStandup := map[string]bool{
    30  		"standup": true,
    31  	}
    32  
    33  	if acceptedStandup[text] {
    34  
    35  		uuid := common.CreatesUUID()
    36  		log.WithFields(log.Fields{
    37  			"uuid": uuid,
    38  		}).Info("Standup uuid generated")
    39  
    40  		attachment := slack.Attachment{
    41  			Text:       "What did you do yesterday?",
    42  			Color:      "#2896b7",
    43  			CallbackID: fmt.Sprintf("Yesterday_%s", ev.User),
    44  		}
    45  
    46  		params := slack.MsgOptionAttachments(attachment)
    47  
    48  		_, timestamp, err := s.Client.PostMessage(ev.Channel, params)
    49  		if err != nil {
    50  			log.WithError(err).Error("Failed to post yesterday standup question")
    51  		}
    52  		log.WithFields(log.Fields{
    53  			"userid":    ev.User,
    54  			"timestamp": timestamp,
    55  		}).Info("Timestamp of the Standup Yesterday message")
    56  
    57  		go postStandupResults(s, ev.User, date, times, uuid)
    58  
    59  	loop:
    60  		for {
    61  			select {
    62  			case <-timer.C:
    63  				err = postStandupCancelTimeout(s, ev.Channel)
    64  				if err != nil {
    65  					log.WithError(err).Error("Could not cancel standup")
    66  				}
    67  				log.Info("Standup Canceled")
    68  				break loop
    69  			case <-ticker.C:
    70  				params2 := &slack.GetConversationHistoryParameters{
    71  					Limit:     1,
    72  					Oldest:    timestamp,
    73  					ChannelID: ev.Channel,
    74  				}
    75  
    76  				history, err := s.Client.GetConversationHistory(params2)
    77  				if err != nil {
    78  					log.WithFields(log.Fields{
    79  						"timestamp": timestamp,
    80  					}).WithError(err).Error("Could not get the IM history of the message")
    81  					continue
    82  				}
    83  				log.WithFields(log.Fields{
    84  					"timestamp": timestamp,
    85  				}).Debug("Getting IM history of the message")
    86  
    87  				message := history.Messages
    88  
    89  				if len(message) == 0 {
    90  
    91  				}
    92  				if len(message) > 0 {
    93  					text := history.Messages[0].Msg.Text
    94  					userid := history.Messages[0].Msg.User
    95  					stamp := history.Messages[0].Msg.Timestamp
    96  					switch text {
    97  					case "cancel":
    98  						err = postStandupCancel(s, ev.Channel)
    99  						if err != nil {
   100  							log.WithError(err).Error("Could not cancel standup")
   101  						}
   102  						log.Info("Standup Canceled")
   103  
   104  						break loop
   105  					default:
   106  						err = yesterdayRegister(text, stamp, date, times, userid, uuid)
   107  						if err != nil {
   108  							log.WithError(err).Error("Could not start yesterdayRegister")
   109  						}
   110  						log.Info("Starting yesterdayRegister")
   111  
   112  						err = askStandupToday(s, ev.Channel, ev.User, date, times, uuid)
   113  						if err != nil {
   114  							log.WithError(err).Error("Could not start askStandupToday")
   115  						}
   116  						log.Info("Starting askStandupToday")
   117  
   118  						break loop
   119  					}
   120  				}
   121  			}
   122  		}
   123  	}
   124  	return nil
   125  }
   126  
   127  func AskStandupYesterdayScheduled(s *common.Slack, userid string) error {
   128  
   129  	t := time.Now().Local().Format("2006-01-02")
   130  	t2 := time.Now().Local().Format("15:04:05")
   131  	date := fmt.Sprint(t)
   132  	times := fmt.Sprint(t2)
   133  
   134  	timer := time.NewTimer(10 * time.Minute)
   135  	ticker := time.NewTicker(3 * time.Second)
   136  
   137  	uuid := common.CreatesUUID()
   138  	log.WithFields(log.Fields{
   139  		"uuid": uuid,
   140  	}).Info("Standup uuid generated")
   141  
   142  	params := &slack.OpenConversationParameters{
   143  		Users: []string{userid},
   144  	}
   145  
   146  	channelid, _, _, err := s.Client.OpenConversation(params)
   147  	if err != nil {
   148  		log.WithError(err).Error("OpenIMChannel could not get channel id")
   149  	}
   150  
   151  	attachment := slack.Attachment{
   152  		Text:       "What did you do yesterday?",
   153  		Color:      "#2896b7",
   154  		CallbackID: fmt.Sprintf("standupYesterday_%s", userid),
   155  	}
   156  
   157  	params2 := slack.MsgOptionAttachments(attachment)
   158  	_, timestamp, err := s.Client.PostMessage(channelid.ID, params2)
   159  	if err != nil {
   160  		log.WithError(err).Error("Failed to post yesterday standup question")
   161  	}
   162  	log.WithFields(log.Fields{
   163  		"timestamp": timestamp,
   164  	}).Info("Timestamp of the standupYesterday message")
   165  
   166  	go postStandupResults(s, userid, date, times, uuid)
   167  
   168  loop:
   169  	for {
   170  		select {
   171  		case <-timer.C:
   172  			err = postStandupCancelTimeout(s, channelid.ID)
   173  			if err != nil {
   174  				log.WithError(err).Error("Could not cancel standup")
   175  			}
   176  			log.Info("Standup Canceled")
   177  
   178  			break loop
   179  		case <-ticker.C:
   180  			params2 := &slack.GetConversationHistoryParameters{
   181  				Limit:     1,
   182  				Oldest:    timestamp,
   183  				ChannelID: channelid.ID,
   184  			}
   185  
   186  			history, err := s.Client.GetConversationHistory(params2)
   187  			if err != nil {
   188  				log.WithFields(log.Fields{
   189  					"timestamp": timestamp,
   190  				}).WithError(err).Error("Could not get the IM history of the message")
   191  				continue
   192  			}
   193  			log.WithFields(log.Fields{
   194  				"timestamp": timestamp,
   195  			}).Debug("Getting IM history of the message with timestamp")
   196  
   197  			message := history.Messages
   198  
   199  			if len(message) == 0 {
   200  
   201  			}
   202  			if len(message) > 0 {
   203  				text := history.Messages[0].Msg.Text
   204  				userid := history.Messages[0].Msg.User
   205  				stamp := history.Messages[0].Msg.Timestamp
   206  				switch text {
   207  				case "cancel":
   208  					err = postStandupCancel(s, channelid.ID)
   209  					if err != nil {
   210  						log.WithError(err).Error("Could not cancel standup")
   211  					}
   212  					log.Info("Standup Canceled")
   213  
   214  					break loop
   215  				default:
   216  					err = yesterdayRegister(text, stamp, date, times, userid, uuid)
   217  					if err != nil {
   218  						log.WithError(err).Error("Could not start yesterdayRegister")
   219  					}
   220  					log.Info("Starting yesterdayRegister")
   221  
   222  					err = askStandupToday(s, channelid.ID, userid, date, times, uuid)
   223  					if err != nil {
   224  						log.WithError(err).Error("Could not start askStandupToday")
   225  					}
   226  					log.Info("Starting askStandupToday")
   227  					break loop
   228  				}
   229  			}
   230  		}
   231  	}
   232  	return nil
   233  }
   234  
   235  func yesterdayRegister(response, timestamp, date, time, userid, uuid string) error {
   236  
   237  	log.Info("Starting import in database of standupYesterday result")
   238  
   239  	var id string
   240  
   241  	sqlWrite := `
   242  	INSERT INTO 
   243  		hatcher.standupyesterday 
   244  		(response, timestamp, date, time, userid, uuid)
   245  	VALUES ($1, $2, $3, $4, $5, $6)
   246  	RETURNING id;
   247  	`
   248  
   249  	err := database.DB.QueryRow(
   250  		sqlWrite,
   251  		response,
   252  		timestamp,
   253  		date,
   254  		time,
   255  		userid,
   256  		uuid).Scan(&id)
   257  	if err != nil {
   258  		log.WithError(err).Error("Couldn't insert in the database the result of AskStandupYesterday")
   259  	}
   260  	log.Info("AskStandupYesterday result written in database")
   261  	return nil
   262  }
   263  
   264  func askStandupToday(s *common.Slack, channelid, userid, date, times, uuid string) error {
   265  
   266  	attachment := slack.Attachment{
   267  		Text:       "What are you doing today?",
   268  		Color:      "#41aa3f",
   269  		CallbackID: "standupToday",
   270  	}
   271  
   272  	params := slack.MsgOptionAttachments(attachment)
   273  	_, timestamp, err := s.Client.PostMessage(channelid, params)
   274  	if err != nil {
   275  		log.WithError(err).Error("Failed to post today standup question")
   276  	}
   277  	log.Info("Posting today standup question")
   278  
   279  	timer := time.NewTimer(10 * time.Minute)
   280  	ticker := time.NewTicker(3 * time.Second)
   281  
   282  loop:
   283  	for {
   284  		select {
   285  		case <-timer.C:
   286  			err = postStandupCancelTimeout(s, channelid)
   287  			if err != nil {
   288  				log.WithError(err).Error("Could not cancel standup")
   289  			}
   290  			log.Info("Standup Canceled")
   291  			break loop
   292  		case <-ticker.C:
   293  			params2 := &slack.GetConversationHistoryParameters{
   294  				Limit:     1,
   295  				Oldest:    timestamp,
   296  				ChannelID: channelid,
   297  			}
   298  
   299  			history, err := s.Client.GetConversationHistory(params2)
   300  			if err != nil {
   301  				log.WithFields(log.Fields{
   302  					"timestamp": timestamp,
   303  				}).WithError(err).Error("Could not get the IM history of the message")
   304  				continue
   305  			}
   306  			log.WithFields(log.Fields{
   307  				"timestamp": timestamp,
   308  			}).Debug("Getting IM history of the message")
   309  
   310  			message := history.Messages
   311  
   312  			if len(message) == 0 {
   313  
   314  			}
   315  			if len(message) > 0 {
   316  				text := history.Messages[0].Msg.Text
   317  				userid := history.Messages[0].Msg.User
   318  				stamp := history.Messages[0].Msg.Timestamp
   319  				switch text {
   320  				case "cancel":
   321  					err = postStandupCancel(s, channelid)
   322  					if err != nil {
   323  						log.WithError(err).Error("Could not cancel standup")
   324  					}
   325  					log.Info("Canceled standup")
   326  
   327  					break loop
   328  				default:
   329  					err := TodayRegister(text, stamp, date, times, userid, uuid)
   330  					if err != nil {
   331  						log.WithError(err).Error("Could not start TodayRegister")
   332  					}
   333  					log.Info("Starting TodayRegister")
   334  
   335  					err = askStandupBlocker(s, channelid, userid, date, times, uuid)
   336  					if err != nil {
   337  						log.WithError(err).Error("Could not start askStandupBlocker")
   338  					}
   339  					log.Info("Started askStandupBlocker")
   340  
   341  					break loop
   342  				}
   343  			}
   344  		}
   345  	}
   346  	return nil
   347  }
   348  
   349  func TodayRegister(response, timestamp, date, time, userid, uuid string) error {
   350  
   351  	log.Info("Starting import in database of AskStandupToday result")
   352  
   353  	var id string
   354  
   355  	sqlWrite := `
   356  	INSERT INTO 
   357  		hatcher.standuptoday 
   358  		(response, timestamp, date, time, userid, uuid)
   359  	VALUES ($1, $2, $3, $4, $5, $6)
   360  	RETURNING id;
   361  	`
   362  
   363  	err := database.DB.QueryRow(
   364  		sqlWrite,
   365  		response,
   366  		timestamp,
   367  		date,
   368  		time,
   369  		userid,
   370  		uuid).Scan(&id)
   371  	if err != nil {
   372  		log.WithError(err).Error("Couldn't insert in the database the result of AskStandupToday")
   373  	}
   374  	log.Info("AskStandupToday result written in database")
   375  
   376  	return nil
   377  }
   378  
   379  func askStandupBlocker(s *common.Slack, channelid, userid, date, times, uuid string) error {
   380  
   381  	attachment := slack.Attachment{
   382  		Text:       "Do you have any blockers?",
   383  		Color:      "#f91b1b",
   384  		CallbackID: "standupBlocker",
   385  	}
   386  
   387  	params := slack.MsgOptionAttachments(attachment)
   388  
   389  	_, timestamp, err := s.Client.PostMessage(channelid, params)
   390  	if err != nil {
   391  		log.WithError(err).Error("Failed to post blocker standup question")
   392  	}
   393  	log.Info("Posted blocker standup question")
   394  
   395  	timer := time.NewTimer(10 * time.Minute)
   396  	ticker := time.NewTicker(3 * time.Second)
   397  
   398  loop:
   399  	for {
   400  		select {
   401  		case <-timer.C:
   402  			err = postStandupCancelTimeout(s, channelid)
   403  			if err != nil {
   404  				log.WithError(err).Error("Could not cancel standup")
   405  			}
   406  			log.Info("Standup Canceled")
   407  
   408  			break loop
   409  		case <-ticker.C:
   410  			params2 := &slack.GetConversationHistoryParameters{
   411  				Limit:     1,
   412  				Oldest:    timestamp,
   413  				ChannelID: channelid,
   414  			}
   415  
   416  			history, err := s.Client.GetConversationHistory(params2)
   417  			if err != nil {
   418  				log.WithFields(log.Fields{
   419  					"timestamp": timestamp,
   420  				}).WithError(err).Error("Could not get the IM history of the message")
   421  				continue
   422  			}
   423  			log.WithFields(log.Fields{
   424  				"timestamp": timestamp,
   425  			}).Debug("Getting IM history of the message")
   426  
   427  			message := history.Messages
   428  
   429  			if len(message) == 0 {
   430  
   431  			}
   432  			if len(message) > 0 {
   433  				text := history.Messages[0].Msg.Text
   434  				userid := history.Messages[0].Msg.User
   435  				stamp := history.Messages[0].Msg.Timestamp
   436  				switch text {
   437  				case "cancel":
   438  					err := postStandupCancel(s, channelid)
   439  					if err != nil {
   440  						log.WithError(err).Error("Could not cancel standup")
   441  					}
   442  					log.Info("Standup canceled")
   443  
   444  					break loop
   445  				default:
   446  					err := BlockerRegister(text, stamp, date, times, userid, uuid)
   447  					if err != nil {
   448  						log.WithError(err).Error("Could not start BlockerRegister")
   449  					}
   450  					log.Info("Started BlockerRegister")
   451  
   452  					err = postStandupDone(s, channelid, userid, date, times, uuid)
   453  					if err != nil {
   454  						log.WithError(err).Error("Could not start postStandupDone")
   455  					}
   456  					log.Info("Started postStandupDone")
   457  
   458  					break loop
   459  				}
   460  			}
   461  		}
   462  	}
   463  	return nil
   464  }
   465  
   466  func BlockerRegister(response, timestamp, date, time, userid, uuid string) error {
   467  
   468  	log.Info("Starting import in database of AskStandupBlocker result")
   469  
   470  	var id string
   471  
   472  	sqlWrite := `
   473  	INSERT INTO 
   474  		hatcher.standupblocker
   475  		(response, timestamp, date, time, userid, uuid)
   476  	VALUES ($1, $2, $3, $4, $5, $6)
   477  	RETURNING id;
   478  	`
   479  
   480  	err := database.DB.QueryRow(
   481  		sqlWrite,
   482  		response,
   483  		timestamp,
   484  		date,
   485  		time,
   486  		userid,
   487  		uuid).Scan(&id)
   488  	if err != nil {
   489  		log.WithError(err).Error("Couldn't insert in the database the result of AskStandupBlocker")
   490  	}
   491  	log.Info("AskStandupBlocker result written in database")
   492  
   493  	return nil
   494  }
   495  
   496  func postStandupCancel(s *common.Slack, channelid string) error {
   497  
   498  	attachment := slack.Attachment{
   499  		Text:       "Standup canceled!",
   500  		Color:      "#f91b1b",
   501  		CallbackID: "standupCancel",
   502  	}
   503  
   504  	params := slack.MsgOptionAttachments(attachment)
   505  
   506  	_, _, err := s.Client.PostMessage(channelid, params)
   507  	if err != nil {
   508  		log.WithError(err).Error("Failed to post standup canceled message")
   509  	}
   510  	log.Info("Posted standup canceled message")
   511  
   512  	return nil
   513  }
   514  
   515  func postStandupCancelTimeout(s *common.Slack, channelid string) error {
   516  
   517  	attachment := slack.Attachment{
   518  		Text:       "The standup was canceled for timeout.\nYou can start a new standup by sending `standup`",
   519  		Color:      "#f91b1b",
   520  		CallbackID: "standupCancelTimeout",
   521  	}
   522  
   523  	params := slack.MsgOptionAttachments(attachment)
   524  
   525  	_, _, err := s.Client.PostMessage(channelid, params)
   526  	if err != nil {
   527  		log.WithError(err).Error("Failed to post standup canceled timeout message")
   528  	}
   529  	log.Info("Posted standup canceled timeout message")
   530  
   531  	return nil
   532  }
   533  
   534  func postStandupDone(s *common.Slack, channelid, userid, date, time, uuid string) error {
   535  
   536  	attachment := slack.Attachment{
   537  		Text:       "Standup Done! Your results will be posted in 10 mins\nEditing your answers will edit the results in the standup channel.\nThanks and see you tomorrow :smiley:",
   538  		Color:      "#2896b7",
   539  		CallbackID: "standupDone",
   540  	}
   541  
   542  	params := slack.MsgOptionAttachments(attachment)
   543  
   544  	_, _, err := s.Client.PostMessage(channelid, params)
   545  	if err != nil {
   546  		log.WithError(err).Error("Failed to post standup done message")
   547  	}
   548  	log.Info("Posted standup done message")
   549  
   550  	return nil
   551  }
   552  
   553  func getResultsYesterday(userid, date, standupChannel, uuid string) (responseYesterday string) {
   554  
   555  	var response string
   556  
   557  	rows, err := database.DB.Query("SELECT response FROM hatcher.standupyesterday WHERE userid = $1 and date = $2 and uuid = $3;", userid, date, uuid)
   558  	if err != nil {
   559  		if err == sql.ErrNoRows {
   560  			log.WithError(err).Error("There is no results")
   561  		}
   562  	}
   563  	defer rows.Close()
   564  	for rows.Next() {
   565  		err = rows.Scan(&response)
   566  		if err != nil {
   567  			log.WithError(err).Error("During the scan")
   568  		}
   569  	}
   570  	return response
   571  }
   572  
   573  func getResultsToday(userid, date, standupChannel, uuid string) (responseToday string) {
   574  
   575  	var response string
   576  
   577  	rows, err := database.DB.Query("SELECT response FROM hatcher.standuptoday WHERE userid = $1 and date = $2 and uuid = $3;", userid, date, uuid)
   578  	if err != nil {
   579  		if err == sql.ErrNoRows {
   580  			log.WithError(err).Error("There is no results")
   581  		}
   582  	}
   583  	defer rows.Close()
   584  	for rows.Next() {
   585  		err = rows.Scan(&response)
   586  		if err != nil {
   587  			log.WithError(err).Error("During the scan")
   588  		}
   589  	}
   590  	return response
   591  }
   592  
   593  func getResultsBlocker(userid, date, standupChannel, uuid string) (responseBlocker string) {
   594  
   595  	var response string
   596  
   597  	rows, err := database.DB.Query("SELECT response FROM hatcher.standupblocker WHERE userid = $1 and date = $2 and uuid = $3;", userid, date, uuid)
   598  	if err != nil {
   599  		if err == sql.ErrNoRows {
   600  			log.WithError(err).Error("There is no results")
   601  		}
   602  	}
   603  	defer rows.Close()
   604  	for rows.Next() {
   605  
   606  		err = rows.Scan(&response)
   607  		if err != nil {
   608  			log.WithError(err).Error("During the scan")
   609  		}
   610  	}
   611  	return response
   612  }
   613  
   614  func CheckIfYesterdayMessageEdited(s *common.Slack, ev *slack.MessageEvent) error {
   615  
   616  	timestamp := ev.SubMessage.Timestamp
   617  	text := ev.SubMessage.Text
   618  	userid := ev.SubMessage.User
   619  
   620  	if common.RowExists("SELECT exists (SELECT timestamp FROM hatcher.standupyesterday WHERE timestamp=$1)", timestamp) {
   621  		err := common.QueryRow("UPDATE hatcher.standupyesterday SET response=$2 WHERE timestamp=$1", timestamp, text)
   622  		if err != nil {
   623  			log.WithError(err).Error("Could not edit the yesterday standup row")
   624  		}
   625  		log.WithFields(log.Fields{
   626  			"timestamp": timestamp,
   627  		}).Info("The yesterday standup row was edited")
   628  
   629  		var standupUUID string
   630  
   631  		standupUUID, err = common.QueryUUID("SELECT uuid FROM hatcher.standupyesterday WHERE timestamp=$1", timestamp)
   632  		if err != nil {
   633  			log.WithError(err).Error("Could get the standup uuid")
   634  		}
   635  		log.WithFields(log.Fields{
   636  			"uuid":      standupUUID,
   637  			"timestamp": timestamp,
   638  		}).Info("The standup uuid was retrieve")
   639  
   640  		err = updateStandupResults(s, userid, standupUUID)
   641  		if err != nil {
   642  			log.WithError(err).Error("Could not start the standup update for yesterday notes")
   643  		}
   644  
   645  	} else {
   646  		log.Println("The row doesn't exist")
   647  	}
   648  	return nil
   649  }
   650  
   651  func CheckIfTodayMessageEdited(s *common.Slack, ev *slack.MessageEvent) error {
   652  
   653  	timestamp := ev.SubMessage.Timestamp
   654  	text := ev.SubMessage.Text
   655  	userid := ev.SubMessage.User
   656  
   657  	if common.RowExists("SELECT exists (SELECT timestamp FROM hatcher.standuptoday WHERE timestamp=$1)", timestamp) {
   658  		err := common.QueryRow("UPDATE hatcher.standuptoday SET response=$2 WHERE timestamp=$1", timestamp, text)
   659  		if err != nil {
   660  			log.WithError(err).Error("Could not edit the today standup row")
   661  		}
   662  		log.WithFields(log.Fields{
   663  			"timestamp": timestamp,
   664  		}).Info("The today standup row was edited")
   665  
   666  		var standupUUID string
   667  
   668  		standupUUID, err = common.QueryUUID("SELECT uuid FROM hatcher.standuptoday WHERE timestamp=$1", timestamp)
   669  		if err != nil {
   670  			log.WithError(err).Error("Could get the standup uuid")
   671  		}
   672  		log.WithFields(log.Fields{
   673  			"uuid":      standupUUID,
   674  			"timestamp": timestamp,
   675  		}).Info("The standup uuid was retrieve")
   676  
   677  		err = updateStandupResults(s, userid, standupUUID)
   678  		if err != nil {
   679  			log.WithError(err).Error("Could not start the standup update for Today notes")
   680  		}
   681  
   682  	} else {
   683  		log.Println("The row doesn't exist")
   684  	}
   685  	return nil
   686  }
   687  
   688  func CheckIfBlockerMessageEdited(s *common.Slack, ev *slack.MessageEvent) error {
   689  
   690  	timestamp := ev.SubMessage.Timestamp
   691  	text := ev.SubMessage.Text
   692  	userid := ev.SubMessage.User
   693  
   694  	if common.RowExists("SELECT exists (SELECT timestamp FROM hatcher.standupblocker WHERE timestamp=$1)", timestamp) {
   695  		err := common.QueryRow("UPDATE hatcher.standupblocker SET response=$2 WHERE timestamp=$1", timestamp, text)
   696  		if err != nil {
   697  			log.WithError(err).Error("Could not edit the blocker standup row")
   698  		}
   699  		log.WithFields(log.Fields{
   700  			"timestamp": timestamp,
   701  		}).Info("The blocker standup row was edited")
   702  
   703  		var standupUUID string
   704  
   705  		standupUUID, err = common.QueryUUID("SELECT uuid FROM hatcher.standupblocker WHERE timestamp=$1", timestamp)
   706  		if err != nil {
   707  			log.WithError(err).Error("Could get the standup uuid")
   708  		}
   709  		log.WithFields(log.Fields{
   710  			"uuid":      standupUUID,
   711  			"timestamp": timestamp,
   712  		}).Info("The standup uuid was retrieve")
   713  
   714  		err = updateStandupResults(s, userid, standupUUID)
   715  		if err != nil {
   716  			log.WithError(err).Error("Could not start the standup update for blocker")
   717  		}
   718  
   719  	} else {
   720  		log.Println("The row doesn't exist")
   721  	}
   722  	return nil
   723  }
   724  
   725  func postStandupResults(s *common.Slack, userid, date, times, uuid string) {
   726  
   727  	timer := time.NewTimer(10 * time.Minute)
   728  
   729  	<-timer.C
   730  
   731  	if common.RowExists("SELECT exists (SELECT * FROM hatcher.standupblocker WHERE uuid=$1)", uuid) {
   732  		rows, err := database.DB.Query("SELECT displayname, standup_channel FROM hatcher.users WHERE userid = $1;", userid)
   733  		if err != nil {
   734  			if err == sql.ErrNoRows {
   735  				log.WithError(err).Error("There is no results")
   736  			}
   737  		}
   738  		defer rows.Close()
   739  		for rows.Next() {
   740  
   741  			var displayname string
   742  			var standupChannel string
   743  
   744  			responseYesterday := getResultsYesterday(userid, date, standupChannel, uuid)
   745  			responseToday := getResultsToday(userid, date, standupChannel, uuid)
   746  			responseBlocker := getResultsBlocker(userid, date, standupChannel, uuid)
   747  
   748  			err = rows.Scan(&displayname, &standupChannel)
   749  			if err != nil {
   750  				log.WithError(err).Error("During the scan")
   751  			}
   752  
   753  			attachment := slack.Attachment{
   754  				Title:      "What did you do yesterday?",
   755  				Text:       responseYesterday,
   756  				Color:      "#2896b7",
   757  				CallbackID: fmt.Sprintf("resultsStandupYesterday_%s", userid),
   758  			}
   759  
   760  			attachment2 := slack.Attachment{
   761  				Title:      "What are you doing today?",
   762  				Color:      "#41aa3f",
   763  				Text:       responseToday,
   764  				CallbackID: fmt.Sprintf("resultsStandupToday_%s", userid),
   765  			}
   766  
   767  			attachment3 := slack.Attachment{
   768  				Title:      "Do you have any blockers?",
   769  				Color:      "#f91b1b",
   770  				Text:       responseBlocker,
   771  				CallbackID: fmt.Sprintf("resultsStandupBlocker_%s", userid),
   772  			}
   773  
   774  			params := slack.MsgOptionAttachments(attachment, attachment2, attachment3)
   775  
   776  			text := fmt.Sprintf("%s posted a daily standup note", displayname)
   777  			_, respTimestamp, err := s.Client.PostMessage(
   778  				standupChannel,
   779  				slack.MsgOptionText(text, false),
   780  				params)
   781  			if err != nil {
   782  				log.WithError(err).Error("Failed to post standup results")
   783  			}
   784  			log.WithFields(log.Fields{
   785  				"timestamp": respTimestamp,
   786  			}).Info("Standup results posted")
   787  
   788  			err = common.QueryRow("INSERT INTO hatcher.standupresults (timestamp, date, time, uuid) VALUES ($1, $2, $3, $4)", respTimestamp, date, times, uuid)
   789  			if err != nil {
   790  				log.WithError(err).Error("Could not edit the standup result timestamp row")
   791  			}
   792  			log.WithFields(log.Fields{
   793  				"timestamp": respTimestamp,
   794  			}).Info("The standup result timestamp row was edited")
   795  		}
   796  	}
   797  }
   798  
   799  func updateStandupResults(s *common.Slack, userid, uuid string) error {
   800  
   801  	rows, err := database.DB.Query("SELECT userid, displayname, standup_channel FROM hatcher.users WHERE userid = $1;", userid)
   802  	if err != nil {
   803  		if err == sql.ErrNoRows {
   804  			log.WithError(err).Error("There is no results")
   805  		}
   806  	}
   807  
   808  	defer rows.Close()
   809  	for rows.Next() {
   810  
   811  		var displayname string
   812  		var standupChannel string
   813  		var timestamp string
   814  		var date string
   815  
   816  		err := database.DB.QueryRow("SELECT timestamp, date FROM hatcher.standupresults WHERE uuid=$1", uuid).Scan(&timestamp, &date)
   817  		if err != nil && err != sql.ErrNoRows {
   818  			log.WithError(err).Error("Impossible to get the standup result uuid")
   819  		}
   820  
   821  		responseYesterday := getResultsYesterday(userid, date, standupChannel, uuid)
   822  		responseToday := getResultsToday(userid, date, standupChannel, uuid)
   823  		responseBlocker := getResultsBlocker(userid, date, standupChannel, uuid)
   824  
   825  		err = rows.Scan(&userid, &displayname, &standupChannel)
   826  		if err != nil {
   827  			log.WithError(err).Error("During the scan")
   828  		}
   829  
   830  		attachment := slack.Attachment{
   831  			Title:      "What did you do yesterday?",
   832  			Color:      "#2896b7",
   833  			Text:       responseYesterday,
   834  			CallbackID: fmt.Sprintf("resultsStandupYesterday_%s", userid),
   835  		}
   836  
   837  		attachment2 := slack.Attachment{
   838  			Title:      "What are you doing today?",
   839  			Color:      "#41aa3f",
   840  			Text:       responseToday,
   841  			CallbackID: fmt.Sprintf("resultsStandupToday_%s", userid),
   842  		}
   843  
   844  		attachment3 := slack.Attachment{
   845  			Title:      "Do you have any blockers?",
   846  			Color:      "#f91b1b",
   847  			Text:       responseBlocker,
   848  			CallbackID: fmt.Sprintf("resultsStandupBlocker_%s", userid),
   849  		}
   850  
   851  		text := fmt.Sprintf("%s posted a daily standup note", displayname)
   852  		_, _, _, err = s.Client.SendMessage(
   853  			standupChannel,
   854  			slack.MsgOptionText(text, false),
   855  			slack.MsgOptionUpdate(timestamp),
   856  			slack.MsgOptionAttachments(
   857  				attachment,
   858  				attachment2,
   859  				attachment3,
   860  			),
   861  		)
   862  		if err != nil {
   863  			log.WithError(err).Error("Failed to post updated standup results")
   864  		}
   865  		log.Info("Updated standup results posted")
   866  	}
   867  	return nil
   868  }