Example #1
0
func NotificationHandler(tobot chan<- common.BotMsg) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method == "POST" {
			body, err := ioutil.ReadAll(r.Body)
			if err != nil {
				log.Println("--", err)
				w.WriteHeader(422)
				return
			}

			err = r.Body.Close()
			if err != nil {
				log.Println("--", err)
				w.WriteHeader(422)
				return
			}

			var notification ZabbixNotification
			err = json.Unmarshal(body, &notification)

			if err != nil {
				log.Println("--", err)
				w.WriteHeader(422)
				return
			}

			sessions, err := models.GetAuthSessionsByAlias(notification.Alias)
			if err != nil {
				log.Println("--", err)
				w.WriteHeader(423)
				return
			}

			var text string = notification.Message

			if len(notification.Trigger.Url) > 0 {
				text += "\n[Описание](" + notification.Trigger.Url + ")"
			}

			for _, s := range *sessions {
				tobot <- common.BotMsg{ChatId: s.ChatId, Text: text, Mode: "Markdown"}
			}

			w.WriteHeader(http.StatusCreated)
		}
	})
}
Example #2
0
func main() {
	viper.SetConfigName("telebot")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(".")
	viper.AddConfigPath("$HOME/.telebot")

	err := viper.ReadInConfig()

	if err != nil {
		panic(fmt.Errorf("Fatal error config file: %s \n", err))
	}

	api := zabbix.NewAPI(viper.GetString("zabbix.proto") + "://" +
		viper.GetString("zabbix.host") + ":" +
		viper.GetString("zabbix.port") + "/api_jsonrpc.php")
	api.Login(viper.GetString("zabbix.user"), viper.GetString("zabbix.password"))

	StringState = map[int]string{0: "NotAuth", 1: "Token", 2: "Auth"}
	State = map[string]int{"NotAuth": 0, "Token": 1, "Auth": 2}
	Signal = map[string]int{"Login": 0, "Token": 1, "Logout": 2}
	States = [][]int{{1, 0, 0}, {0, 2, 0}, {2, 2, 0}}

	bot, err := tgbotapi.NewBotAPI(viper.GetString("telegram.botkey"))
	log.Println(viper.GetString("telegram.botkey"))
	if err != nil {
		log.Panic(err)
	}

	u := tgbotapi.NewUpdate(0)
	u.Timeout = 60

	updates, err := bot.GetUpdatesChan(u)

	//	from_bot := make(chan common.BotMsg, 0)
	to_bot := make(chan common.BotMsg, 0)
	quit := make(chan int, 0)

	go func() {
		for {
			select {
			case tobot := <-to_bot:
				msg := tgbotapi.NewMessage(tobot.ChatId, tobot.Text)
				if len(tobot.Mode) > 0 {
					msg.ParseMode = tobot.Mode
				}
				log.Println("->", msg.ChatID, msg.Text)
				bot.Send(msg)
			}
		}
	}()

	go func() {
		for {
			select {
			case update := <-updates:
				Message := update.Message
				log.Println("<-", Message.Chat.ID, Message.Text)

				if Message.IsCommand() {
					switch Message.Command() {
					case "/login":
						go func() {
							users, err := api.UsersGetEnabled(zabbix.Params{})
							if err != nil {
								log.Println(err)
								return
							}

							var userids []string
							for _, user := range users {
								userids = append(userids, user.UserId)
							}

							medias, err := api.MediasByUserIds(userids)

							if err != nil {
								log.Println(err)
								return
							}

							for _, media := range medias {
								if Message.CommandArguments() == media.Sendto && (media.MediatypeId == "1" || media.MediatypeId == "5") && media.Active == 0 {
									log.Println("dd", Message.CommandArguments(), media.Sendto)
									var session common.Session
									session.ChatId = Message.Chat.ID
									session.Media = media.Sendto
									var alias string
									for _, u := range users {
										if u.UserId == media.UserId {
											alias = u.Alias
											break
										}
									}
									//session.Alias = Message.Chat.UserName
									session.Alias = alias
									log.Println("--", session.ChatId, "Change state from", StringState[session.State], "to", StringState[States[session.State][Signal["login"]]])
									session.State = States[session.State][Signal["Login"]]
									if session.State == Signal["Token"] {
										session.AuthToken.Gen(32)
										log.Println("--", "Generated token", session.AuthToken.Get())
										if _, err := mail.ParseAddress(media.Sendto); err == nil {
											if err := SendEmail(media.Sendto, session.AuthToken.Get()); err == nil {
												var text string
												if Message.Chat.FirstName != "" && Message.Chat.LastName != "" {
													text = Message.Chat.FirstName + " " + Message.Chat.LastName + " ключ выслан"
												}
												to_bot <- common.BotMsg{Text: text, ChatId: Message.Chat.ID}
											}
										}
									}
									if err := models.AddSession(&session); err != nil {
										log.Println(err)
									}

									break
								}
							}
						}()
					case "/ping":
						if s, err := models.GetSession(Message.Chat.ID); err == nil {
							s.Ping = !s.Ping
							if err := models.UpdateSession(s); err != nil {
								log.Println(err)
							}
							var text string
							if s.Ping {
								text = "Ping On"
							} else {
								text = "Ping Off"
							}
							to_bot <- common.BotMsg{Text: text, ChatId: s.ChatId}
						}
					case "/token":
						session, err := models.GetSession(Message.Chat.ID)
						if err == nil {
							log.Println("dd", session)
							Token := Message.CommandArguments()
							if Token == session.AuthToken.Get() {
								session.State = States[session.State][Signal["Token"]]
								session.AuthToken.Null()
								if err := models.UpdateSession(session); err != nil {
									log.Println(err)
								} else {
									to_bot <- common.BotMsg{Text: StringState[session.State], ChatId: session.ChatId}
								}
							}
						} else {
							log.Println("dd", err)
						}
					case "/who":
						if _, err := models.GetAuthSession(Message.Chat.ID); err == nil {
							if users, err := models.GetAuthSessions(); err == nil {
								var text []string
								for _, u := range *users {
									text = append(text, u.Alias)
								}
								to_bot <- common.BotMsg{ChatId: Message.Chat.ID, Text: strings.Join(text, "\n")}
							}
						}
					case "/logout":
					case "/to":
						_, err := models.GetAuthSession(Message.Chat.ID)
						if err != nil {
							log.Println(err)
							break
						}

						if len(Message.CommandArguments()) == 0 {
							log.Println("--", "Command wtihout arguments")
							break
						}

						alias := strings.Split(Message.CommandArguments(), " ")[0]
						message := strings.Split(Message.CommandArguments(), " ")[1:]

						if len(message) == 0 {
							log.Println("--", "Message is null")
						}

						sessions, err := models.GetSessionsByAlias(alias)
						if err != nil {
							log.Println(err)
							break
						}

						from, _ := models.GetAuthSession(Message.Chat.ID)
						for _, session := range *sessions {
							to_bot <- common.BotMsg{ChatId: session.ChatId, Text: fmt.Sprintf("From: %s\n%s\n", from.Alias, strings.Join(message, " "))}
						}

					case "/status":
						text := "Not Exists"
						if session, err := models.GetSession(Message.Chat.ID); err == nil {
							text = StringState[session.State]
						}
						to_bot <- common.BotMsg{Text: text, ChatId: Message.Chat.ID}
					default:
						log.Println("--", "Unknow command", Message.Command(), Message.CommandArguments())
					}
				} else {
					if s, err := models.GetSession(Message.Chat.ID); err == nil && s.State == State["Auth"] {
						to_bot <- common.BotMsg{Text: Message.Text, ChatId: Message.Chat.ID}
					} else {
						log.Println("--", "Message", Message.Chat.ID, Message.Text)
					}
				}
			}
		}
	}()

	go func() {
		tick := time.Tick(1 * time.Minute)
		for range tick {
			sessions, err := models.GetPingSessions()
			if err == nil {
				for _, s := range *sessions {
					to_bot <- common.BotMsg{ChatId: s.ChatId, Text: "Ping"}
				}
			} else {
				log.Println("dd", err)
			}
		}
	}()

	conn, err := amqp.Dial("amqp://" +
		viper.GetString("rabbitmq.user") + ":" +
		viper.GetString("rabbitmq.password") + "@" +
		viper.GetString("rabbitmq.host") + ":" +
		viper.GetString("rabbitmq.port") + "/" +
		viper.GetString("rabbitmq.path"))

	failOnError(err, "Failed to connect to RabbitMQ")
	defer conn.Close()

	ch, err := conn.Channel()
	failOnError(err, "Failed to open a channel")
	defer ch.Close()

	q, err := ch.QueueDeclare(
		viper.GetString("rabbitmq.queue"), // name
		false, // durable
		false, // delete when usused
		false, // exclusive
		false, // no-wait
		nil,   // arguments
	)
	failOnError(err, "Failed to declare a queue")

	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto-ack
		false,  // exclusive
		false,  // no-local
		false,  // no-wait
		nil,    // args
	)
	failOnError(err, "Failed to register a consumer")

	go func() {
		for d := range msgs {
			var m Message
			err := json.Unmarshal(d.Body, &m)
			log.Printf("Received a message: %s", d.Body)

			if err == nil {
				sessions, err := models.GetAuthSessionsByAlias(m.User)
				if err == nil {
					for _, s := range *sessions {
						to_bot <- common.BotMsg{ChatId: s.ChatId, Text: fmt.Sprintf("*%s*\n%s", m.Subject, m.Body), Mode: "Markdown"}
					}
				} else {
					log.Println("dd", err)
				}
			} else {
				log.Println("unMarshal error")
			}
		}
	}()

	http.Handle(viper.GetString("http.locations.notification"), notification.NotificationHandler(to_bot))
	http.ListenAndServe(viper.GetString("http.ip")+":"+viper.GetString("http.port"), nil)
	<-quit
}