├── .gitignore ├── LICENSE ├── conf └── settings.go ├── main.go └── src ├── Database.go └── TelegramBot.go /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Nikita Ivanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /conf/settings.go: -------------------------------------------------------------------------------- 1 | package conf 2 | 3 | const ( 4 | // Telegram bot settings 5 | TELEGRAM_BOT_API_KEY = "paste your key here" 6 | TELEGRAM_BOT_UPDATE_OFFSET = 0 7 | TELEGRAM_BOT_UPDATE_TIMEOUT = 64 8 | // MongoDB settings 9 | MONGODB_CONNECTION_URL = "localhost" 10 | MONGODB_DATABASE_NAME = "regbot" 11 | MONGODB_COLLECTION_USERS = "users" 12 | ) 13 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "RegistrationBotTutorial/src" 5 | ) 6 | 7 | var telegramBot src.TelegramBot 8 | 9 | func main() { 10 | src.Connection.Init() 11 | telegramBot.Init() 12 | telegramBot.Start() 13 | } 14 | -------------------------------------------------------------------------------- /src/Database.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "gopkg.in/mgo.v2" 5 | "RegistrationBotTutorial/conf" 6 | "log" 7 | "gopkg.in/mgo.v2/bson" 8 | ) 9 | 10 | var Connection DatabaseConnection 11 | 12 | type User struct { 13 | Chat_ID int64 14 | Phone_Number string 15 | } 16 | 17 | type DatabaseConnection struct { 18 | Session *mgo.Session // Соединение с сервером 19 | DB *mgo.Database // Соединение с базой данных 20 | } 21 | 22 | // Инициализация соединения с БД 23 | func (connection *DatabaseConnection) Init() { 24 | session, err := mgo.Dial(conf.MONGODB_CONNECTION_URL) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | connection.Session = session 29 | db := session.DB(conf.MONGODB_DATABASE_NAME) 30 | connection.DB = db 31 | } 32 | 33 | // Проверка на существование пользователя 34 | func (connection *DatabaseConnection) Find(chatID int64) (bool, error) { 35 | collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) 36 | count, err := collection.Find(bson.M{"chat_id": chatID}).Count() 37 | if err != nil || count == 0 { 38 | return false, err 39 | } else { 40 | return true, err 41 | } 42 | } 43 | 44 | // Получение пользователя 45 | func (connection *DatabaseConnection) GetUser(chatID int64) (User, error) { 46 | var result User 47 | find, err := connection.Find(chatID) 48 | if err != nil { 49 | return result, err 50 | } 51 | if find { 52 | collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) 53 | err = collection.Find(bson.M{"chat_id": chatID}).One(&result) 54 | return result, err 55 | } else { 56 | return result, mgo.ErrNotFound 57 | } 58 | } 59 | 60 | // Создание пользователя 61 | func (connection *DatabaseConnection) CreateUser(user User) error { 62 | collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) 63 | err := collection.Insert(user) 64 | return err 65 | } 66 | 67 | // Обновление номера мобильного телефона 68 | func (connection *DatabaseConnection) UpdateUser(user User) error { 69 | collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) 70 | err := collection.Update(bson.M{"chat_id": user.Chat_ID}, &user) 71 | return err 72 | } 73 | -------------------------------------------------------------------------------- /src/TelegramBot.go: -------------------------------------------------------------------------------- 1 | package src 2 | 3 | import ( 4 | "github.com/go-telegram-bot-api/telegram-bot-api" 5 | "log" 6 | "RegistrationBotTutorial/conf" 7 | ) 8 | 9 | type TelegramBot struct { 10 | API *tgbotapi.BotAPI // API телеграмма 11 | Updates tgbotapi.UpdatesChannel // Канал обновлений 12 | ActiveContactRequests []int64 // ID чатов, от которых мы ожидаем номер 13 | } 14 | 15 | // Инициализация бота 16 | func (telegramBot *TelegramBot) Init() { 17 | botAPI, err := tgbotapi.NewBotAPI(conf.TELEGRAM_BOT_API_KEY) // Инициализация API 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | telegramBot.API = botAPI 22 | botUpdate := tgbotapi.NewUpdate(conf.TELEGRAM_BOT_UPDATE_OFFSET) // Инициализация канала обновлений 23 | botUpdate.Timeout = conf.TELEGRAM_BOT_UPDATE_TIMEOUT 24 | botUpdates, err := telegramBot.API.GetUpdatesChan(botUpdate) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | telegramBot.Updates = botUpdates 29 | } 30 | 31 | // Основной цикл бота 32 | func (telegramBot *TelegramBot) Start() { 33 | for update := range telegramBot.Updates { 34 | if update.Message != nil { 35 | // Если сообщение есть и его длина больше 0 -> начинаем обработку 36 | telegramBot.analyzeUpdate(update) 37 | } 38 | } 39 | } 40 | 41 | func (telegramBot *TelegramBot) addContactRequestID(chatID int64) { 42 | telegramBot.ActiveContactRequests = append(telegramBot.ActiveContactRequests, chatID) 43 | } 44 | 45 | func (telegramBot *TelegramBot) findContactRequestID(chatID int64) bool { 46 | for _, v := range telegramBot.ActiveContactRequests { 47 | if v == chatID { 48 | return true 49 | } 50 | } 51 | return false 52 | } 53 | 54 | func (telegramBot *TelegramBot) deleteContactRequestID(chatID int64) { 55 | for i, v := range telegramBot.ActiveContactRequests { 56 | if v == chatID { 57 | copy(telegramBot.ActiveContactRequests[i:], telegramBot.ActiveContactRequests[i + 1:]) 58 | telegramBot.ActiveContactRequests[len(telegramBot.ActiveContactRequests) - 1] = 0 59 | telegramBot.ActiveContactRequests = telegramBot.ActiveContactRequests[:len(telegramBot.ActiveContactRequests) - 1] 60 | } 61 | } 62 | } 63 | 64 | // Начало обработки сообщения 65 | func (telegramBot *TelegramBot) analyzeUpdate(update tgbotapi.Update) { 66 | chatID := update.Message.Chat.ID 67 | if telegramBot.findUser(chatID) { 68 | telegramBot.analyzeUser(update) 69 | } else { 70 | telegramBot.createUser(User{chatID, ""}) 71 | telegramBot.requestContact(chatID) 72 | } 73 | } 74 | 75 | // Есть ли пользователь в БД? 76 | func (telegramBot *TelegramBot) findUser(chatID int64) bool { 77 | find, err := Connection.Find(chatID) 78 | if err != nil { 79 | msg := tgbotapi.NewMessage(chatID, "Произошла ошибка! Бот может работать неправильно!") 80 | telegramBot.API.Send(msg) 81 | } 82 | return find 83 | } 84 | 85 | // Создать нового пользователя 86 | func (telegramBot *TelegramBot) createUser(user User) { 87 | err := Connection.CreateUser(user) 88 | if err != nil { 89 | msg := tgbotapi.NewMessage(user.Chat_ID, "Произошла ошибка! Бот может работать неправильно!") 90 | telegramBot.API.Send(msg) 91 | } 92 | } 93 | 94 | func (telegramBot *TelegramBot) analyzeUser(update tgbotapi.Update) { 95 | chatID := update.Message.Chat.ID 96 | user, err := Connection.GetUser(chatID) // Вытаскиваем данные из БД для проверки номера 97 | if err != nil { 98 | msg := tgbotapi.NewMessage(chatID, "Произошла ошибка! Бот может работать неправильно!") 99 | telegramBot.API.Send(msg) 100 | return 101 | } 102 | if len(user.Phone_Number) > 0 { 103 | msg := tgbotapi.NewMessage(chatID, "Ваш номер: " + user.Phone_Number) // Если номер у нас уже есть, то пишем его 104 | telegramBot.API.Send(msg) 105 | return 106 | } else { 107 | // Если номера нет, то проверяем ждём ли мы контакт от этого ChatID 108 | if telegramBot.findContactRequestID(chatID) { 109 | telegramBot.checkRequestContactReply(update) // Если да -> проверяем 110 | return 111 | } else { 112 | telegramBot.requestContact(chatID) // Если нет -> запрашиваем его 113 | return 114 | } 115 | } 116 | } 117 | 118 | // Запросить номер телефона 119 | func (telegramBot *TelegramBot) requestContact(chatID int64) { 120 | requestContactMessage := tgbotapi.NewMessage(chatID, "Согласны ли вы предоставить ваш номер телефона для регистрации в системе?") 121 | acceptButton := tgbotapi.NewKeyboardButtonContact("Да") 122 | declineButton := tgbotapi.NewKeyboardButton("Нет") 123 | requestContactReplyKeyboard := tgbotapi.NewReplyKeyboard([]tgbotapi.KeyboardButton{acceptButton, declineButton}) 124 | requestContactMessage.ReplyMarkup = requestContactReplyKeyboard 125 | telegramBot.API.Send(requestContactMessage) 126 | telegramBot.addContactRequestID(chatID) 127 | } 128 | 129 | // Проверка принятого контакта 130 | func (telegramBot *TelegramBot) checkRequestContactReply(update tgbotapi.Update) { 131 | if update.Message.Contact != nil { // Проверяем, содержит ли сообщение контакт 132 | if update.Message.Contact.UserID == update.Message.From.ID { // Проверяем действительно ли это контакт отправителя 133 | telegramBot.updateUser(User{update.Message.Chat.ID, update.Message.Contact.PhoneNumber}, update.Message.Chat.ID) // Обновляем номер 134 | telegramBot.deleteContactRequestID(update.Message.Chat.ID) // Удаляем ChatID из списка ожидания 135 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Спасибо!") 136 | msg.ReplyMarkup = tgbotapi.NewRemoveKeyboard(false) // Убираем клавиатуру 137 | telegramBot.API.Send(msg) 138 | } else { 139 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Номер телефона, который вы предоставили, принадлежит не вам!") 140 | telegramBot.API.Send(msg) 141 | telegramBot.requestContact(update.Message.Chat.ID) 142 | } 143 | } else { 144 | msg := tgbotapi.NewMessage(update.Message.Chat.ID, "Если вы не предоставите ваш номер телефона, вы не сможете пользоваться системой!") 145 | telegramBot.API.Send(msg) 146 | telegramBot.requestContact(update.Message.Chat.ID) 147 | } 148 | } 149 | 150 | // Обновление номера мобильного телефона пользователя 151 | func (telegramBot *TelegramBot) updateUser(user User, chatID int64) { 152 | err := Connection.UpdateUser(user) 153 | if err != nil { 154 | msg := tgbotapi.NewMessage(chatID, "Произошла ошибка! Бот может работать неправильно!") 155 | telegramBot.API.Send(msg) 156 | return 157 | } 158 | } 159 | --------------------------------------------------------------------------------