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 }