package wizard import ( "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/db/model" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/iface" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/store" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/handler/util" "gitea.neur0tx.site/Neur0toxine/vegapokerbot/internal/locale" "github.com/mymmrac/telego" tu "github.com/mymmrac/telego/telegoutil" "net/http" "net/url" "strings" "time" ) type RedmineSetup struct { iface.Base Redmine *store.RedmineSetup } func NewRedmineSetup(app iface.App, userID, chatID int64, config *store.RedmineSetup) *RedmineSetup { return &RedmineSetup{ Base: iface.NewBase(app, userID, chatID), Redmine: config, } } func (h *RedmineSetup) Handle(wh telego.Update) error { if wh.Message.Chat.Type != telego.ChatTypePrivate { return nil } if h.Redmine == nil { return nil } loc := h.Localizer(wh.Message.From.LanguageCode) if h.Redmine.URL == "" { return h.handleURLStep(wh.Message.Text, loc) } if h.Redmine.Key == "" { return h.handleKeyStep(wh.Message.Text, loc) } if h.Redmine.SPFieldName == "" && h.Redmine.WaitingForSPField { return h.handleSPFieldStep(wh.Message.Text, loc) } return nil } func (h *RedmineSetup) handleURLStep(text string, loc locale.Localizer) error { h.Redmine.URL = h.processURL(text) if h.Redmine.URL == "" { _, err := h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Message("please_send_redmine_url"), ParseMode: telego.ModeMarkdown, }) return err } _, err := h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Template("please_send_redmine_key", map[string]interface{}{"Origin": h.Redmine.URL}), ParseMode: telego.ModeMarkdown, }) return err } func (h *RedmineSetup) handleKeyStep(text string, loc locale.Localizer) error { h.Redmine.Key = strings.TrimSpace(text) if h.Redmine.Key == "" { _, err := h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Template("please_send_redmine_key", map[string]interface{}{"Origin": h.Redmine.URL}), ParseMode: telego.ModeMarkdown, }) return err } if !h.verifyRedmine() { _, err := h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Message("invalid_redmine_credentials"), ParseMode: telego.ModeMarkdown, ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{ { { Text: loc.Message("yes"), CallbackData: util.NewRedmineQuestionPayload(h.UserID, h.Redmine.Chat, true).String(), }, { Text: loc.Message("no"), CallbackData: util.NewRedmineQuestionPayload(h.UserID, h.Redmine.Chat, false).String(), }, }, }}, }) return err } chat, err := h.App.DB().ForChat().ByTelegramID(h.Redmine.Chat) if err != nil { _ = util.SendInternalError(h.App.TG(), h.ChatID, loc) return err } if chat == nil || chat.ID == 0 { _ = util.SendInternalError(h.App.TG(), h.ChatID, loc) return nil } integration := &model.Integration{ Type: model.RedmineIntegration, ChatID: chat.ID, } integration.StoreRedmine(h.Redmine) if err := h.App.DB().ForIntegration().Save(integration); err != nil { _ = util.SendInternalError(h.App.TG(), h.ChatID, loc) return err } _, _ = h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Template("redmine_was_connected", map[string]interface{}{"Name": h.App.TGProfile().Username}), ParseMode: telego.ModeMarkdown, }) _, err = h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Message("should_send_estimated_hours_redmine"), ParseMode: telego.ModeMarkdown, ReplyMarkup: &telego.InlineKeyboardMarkup{InlineKeyboard: [][]telego.InlineKeyboardButton{ { { Text: loc.Message("yes"), CallbackData: util.NewRedmineHoursQuestionPayload(h.UserID, h.Redmine.Chat, true).String(), }, { Text: loc.Message("no"), CallbackData: util.NewRedmineHoursQuestionPayload(h.UserID, h.Redmine.Chat, false).String(), }, }, }}, }) return err } func (h *RedmineSetup) handleSPFieldStep(text string, loc locale.Localizer) error { h.Redmine.SPFieldName = strings.TrimSpace(text) if h.Redmine.SPFieldName == "" { _, err := h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Message("specify_result_field"), ParseMode: telego.ModeMarkdown, }) return err } h.Redmine.WaitingForSPField = false chat, err := h.App.DB().ForChat().ByTelegramIDWithIntegrations(h.Redmine.Chat) if err != nil { return err } for _, integration := range chat.Integrations { if integration.Type == model.RedmineIntegration { rs := integration.LoadRedmine() rs.SPFieldName = h.Redmine.SPFieldName integration.StoreRedmine(rs) if err := h.App.DB().ForIntegration().Save(&integration); err != nil { return err } break } } _, _ = h.App.TG().SendMessage(&telego.SendMessageParams{ ChatID: tu.ID(h.ChatID), Text: loc.Template("redmine_poker_will_be_configured", map[string]interface{}{"Name": h.Redmine.SPFieldName}), ParseMode: telego.ModeMarkdown, }) store.RedmineSetups.Delete(h.ChatID) return util.SendSetupDone(h.App.TG(), h.App.TGProfile().Username, h.ChatID, loc) } func (h *RedmineSetup) processURL(input string) string { uri, err := url.Parse(strings.TrimSpace(input)) if err != nil { return "" } return uri.Scheme + "://" + uri.Host } func (h *RedmineSetup) verifyRedmine() bool { req, err := http.NewRequest(http.MethodGet, h.Redmine.URL+"/issues.json", nil) if err != nil { return false } req.Header.Set("X-Redmine-Api-Key", h.Redmine.Key) client := &http.Client{Timeout: 5 * time.Second} resp, err := client.Do(req) if err != nil { return false } return resp.StatusCode == http.StatusOK }