package main import ( "encoding/json" "fmt" "log" "os" "strconv" "strings" owm "github.com/briandowns/openweathermap" "github.com/go-redis/redis" "github.com/yanzay/tbot/v2" ) var opt, err = redis.ParseURL(os.Getenv("REDIS_URL")) var client = redis.NewClient(&redis.Options{ Addr: opt.Addr, Password: opt.Password, DB: opt.DB, }) type OWM struct { City string `json:"city"` } func (a *application) startHandler(m *tbot.Message) { msg := "\n*Привет!* Для начала напиши город в чат.\nДалее введи необходимую *команду*:\n" + "Команда */today* - прогноз на сегодня.\nКоманда */week* - прогноз на 5 дней." a.client.SendMessage(m.Chat.ID, msg, tbot.OptParseModeMarkdown) } // Handle the msg command here func (a *application) msgHandler(m *tbot.Message) { citycodes := map[string]string{ "абакан": "QYPM", "алматы": "P8OF", "анадырь": "SSWT", "архангельск": "SRLE", "астана": "QJNY", "астрахань": "PQM0", "ашхабад": "OCMV", "баку": "OQM6", "барнаул": "QWOZ", "белгород": "QGL2", "биробиджан": "Q5T3", "бишкек": "P5O8", "благовещенск": "QESN", "брянск": "QWKV", "вильнюс": "R4K4", "владивосток": "P7T0", "владикавказ": "P6LQ", "владимир": "RDLD", "волгоград": "Q4LP", "вологда": "RVLC", "воронеж": "QMLA", "горно-алтайск": "QOP6", "грозный": "P8LT", "душанбе": "OFNQ", "екатеринбург": "RHN2", "ереван": "OPLQ", "иваново": "RILF", "ижевск": "RHMG", "иркутск": "QQQP", "йошкар-ола": "RGM0", "казань": "RBM3", "калининград": "R4JQ", "калуга": "R3L1", "кемерово": "R8P6", "киев": "QFKK", "киров": "RSM5", "кишинёв": "PUKF", "кострома": "RNLF", "краснодар": "PIL9", "красноярск": "RCPR", "курган": "R9NG", "курск": "QML1", "кызыл": "QMPV", "липецк": "QSLB", "магадан": "RXUK", "майкоп": "PGLC", "махачкала": "P6LY", "минеральныеводы": "PDLL", "минск": "R0KB", "москва": "RAL5", "мурманск": "TIKR", "набережные челны": "RAMD", "назрань": "P7LQ", "нальчик": "P9LN", "нижний новгород": "RELO", "новгород": "RRKM", "новосибирск": "R6OX", "омск": "R6O4", "оренбург": "QNML", "орёл": "QUL0", "пенза": "QVLR", "пермь": "ROMP", "петрозаводск": "SBKV", "петропавловск-камчатский": "QUV8", "псков": "RNKD", "рига": "RIK0", "ростов-на-дону": "PVLB", "рязань": "R4LB", "салехард": "T3NK", "самара": "QVM6", "санкт-петербург": "S0KJ", "саранск": "R1LS", "саратов": "QLLU", "симферополь": "PIKU", "смоленск": "R5KO", "сочи": "PALB", "ставрополь": "PILI", "станциявосток": "53QX", "станциямирный": "73PR", "сыктывкар": "SAM8", "таллин": "RXK2", "тамбов": "QSLG", "ташкент": "OWNS", "тбилиси": "OYLQ", "тверь": "REL0", "тольятти": "QXM4", "томск": "RFP3", "тула": "R1L5", "тюмень": "RJNH", "улан-удэ": "QNQZ", "ульяновск": "R2M1", "уфа": "R4MO", "хабаровск": "Q3T9", "ханты-мансийск": "S6NR", "чебоксары": "RDLY", "челябинск": "R7N4", "череповец": "RVL6", "черкесск": "PDLI", "чита": "QORH", "элиста": "PQLP", "южно-сахалинск": "PUTW", "якутск": "SCST", "ярославль": "RMLC"} a.client.SendChatAction(m.Chat.ID, tbot.ActionTyping) msg, datecheck, cityname, desc, url, urldate := "", 0, "", "", "", "" if m.Text == "/week" || m.Text == "/today" { city, err := client.Get(m.Chat.ID).Result() if err == redis.Nil { msg = "Сначала выбери город!\nКоманда /start в помощь." } else { w, err := owm.NewForecast("5", "C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output if err != nil { log.Fatalln(err) } city = strings.TrimLeft(city, `{"city":"`) city = strings.TrimRight(city, `"}`) w.DailyByName(city, 0) if val, ok := w.ForecastWeatherJson.(*owm.Forecast5WeatherData); ok { if len(val.List) != 0 { if m.Text == "/week" { cityname = val.City.Country + " " + val.City.Name + " Прогноз на неделю" } else { cityname = val.City.Country + " " + val.City.Name + " Прогноз на сегодня" } cst := strings.Split(fmt.Sprintf("%s", val.List[0]), " ") cdt := strings.Split(cst[len(cst)-4], "-") cdate := fmt.Sprintf("%s-%s-%s", cdt[2], cdt[1], cdt[0]) urldate = fmt.Sprintf("%s%s%s", cdt[0], cdt[1], cdt[2]) for i := 0; i < len(val.List)-1; i++ { fl := strings.Split(fmt.Sprintf("%.2f", val.List[i:(i+1)]), " ") st := strings.Split(fmt.Sprintf("%s", val.List[i:(i+1)]), " ") dt := strings.Split(st[len(st)-4], "-") date := fmt.Sprintf("%s-%s-%s", dt[2], dt[1], dt[0]) desc = strings.Title(strings.ToLower(st[11])) if len(st) == 26 { desc = desc + " " + st[12] + " " + st[13] } if len(st) == 25 { desc = desc + " " + st[12] } if m.Text == "/week" && date != cdate { if ((st[len(st)-3] == "09:00:00" || st[len(st)-3] == "15:00:00") && datecheck < 3) || (st[len(st)-3] == "15:00:00" && datecheck == 3)|| (st[len(st)-3] == "12:00:00" && datecheck == 10){ if st[len(st)-3] == "09:00:00" || datecheck == 0 || datecheck == 10 { datecheck++ msg = msg + "\n\n> Прогноз на " + date } if st[len(st)-3] == "15:00:00" && datecheck == 3 { datecheck = 10 } msg = msg + fmt.Sprintf("\n\n%s - %s\nТемпература: %s°\nОщущается: %s°\nВетер: %s м/c\n%s.", st[len(st)-3], fadvice(fl[4]), strings.TrimLeft(fl[1], "{"), fl[4], strings.TrimLeft(fl[14], "{"), desc) } } else if m.Text == "/today" && date == cdate { msg = msg + fmt.Sprintf("\n\n%s - %s\nТемпература: %s°\nОщущается: %s°\nВетер: %s м/c\n%s.", st[len(st)-3], fadvice(fl[4]), strings.TrimLeft(fl[1], "{"), fl[4], strings.TrimLeft(fl[14], "{"), desc) } } if m.Text == "/today" { w, err := owm.NewCurrent("C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output if err != nil { log.Fatalln(err) } w.CurrentByName(city) arr := strings.Split(fmt.Sprintf("", w.Weather), " ") for i := 3; i < len(arr)-1; i++ { if i == 3 { desc = strings.Title(strings.ToLower(arr[i])) } else { desc = desc + " " + arr[i] } } msg = fmt.Sprintf("%s\n\nСейчас - %s\nТемпература: %.2f°\nОщущается как: %.2f°\nСкорость ветра: %.2f м/c\n%s.", cityname, fadvice(fmt.Sprintf("%.2f", w.Main.FeelsLike)), w.Main.Temp, w.Main.FeelsLike, w.Wind.Speed, desc) + msg if citycodes[strings.ToLower(city)] != "" { urldate = citycodes[strings.ToLower(city)] + "_" + urldate } url = "https://tesis.lebedev.ru/upload_test/files/kp_" + urldate + ".png?bg=1" } else { msg = cityname + msg url = "https://tesis.lebedev.ru/upload_test/files/fc_" + urldate + ".png?bg=1" } } } else { msg = fmt.Sprintf("%v", len(val.List)) } } } else { m.Text = strings.TrimRight(m.Text, " .!") w, err := owm.NewCurrent("C", "ru", os.Getenv("OWM_API_KEY")) // fahrenheit (imperial) with Russian output if err != nil { log.Fatalln(err) } w.CurrentByName(m.Text) if w.Cod != 200 { msg = "Город не найден!" } else { json, err := json.Marshal(OWM{City: m.Text}) if err != nil { fmt.Println(err) } err = client.Set(m.Chat.ID, json, 0).Err() if err != nil { fmt.Println(err) } msg = "Город изменён - " + w.Name + " " + w.Sys.Country + "." } } if url == "" { a.client.SendMessage(m.Chat.ID, msg, tbot.OptParseModeMarkdown) } else { a.client.SendPhoto(m.Chat.ID, url, tbot.OptCaption(msg)) } } func fadvice(stemp string) (advice string) { if temp, err := strconv.ParseFloat(stemp, 32); err == nil { switch { case temp <= -50.00: advice = "Сиди дома" case temp <= -40.00: advice = "Одежда для высотных восхождений" case temp <= -30.00: advice = "Термобельё + свитер + пуховик + шарф + перчатки" case temp <= -20.00: advice = "Термобельё + лонгслив + пуховик" case temp <= -10.00: advice = "Лёгкая куртка + свитер" case temp <= 00.00: advice = "Лонгслив + лёгкая куртка" case temp >= 50.00: advice = "Сиди дома" case temp >= 40.00: advice = "Одежда не нужна" case temp >= 30.00: advice = "Шорты + футболка" case temp >= 20.00: advice = "Лонгслив" case temp >= 10.00: advice = "Свитер" case temp >= 00.00: advice = "Лонгслив + ветровка" } } return }