テレグラムボットを使用した登録

現在、ほとんどすべてのサイトに登録があります。 ほとんどの場合、電子メールで実装されますが、SMSでは実装されません。 しかし、電報ボットに登録するとどうなりますか? サイトへのログインとして、確認済みの電話番号を使用できます。ボット自体は、入力するワンタイムコードを送信します。 この記事では、Golang言語でこのようなボットを作成するプロセスについて説明します。



画像

ボットの例



すぐに注意したいのですが、この記事では、ワンタイムコードを使用してサイトにアクセスする実装については説明しません。



すべてのコードはGitHubのリポジトリにあります



UPD 02/07/2018: Telegram Login Widgetを使用して、 Telegramを使用したサイトへのログインを実装できるようになりました



目次:



  1. 必要なソフトウェア
  2. APIキーを取得する
  3. プロジェクト構造
  4. 設定ファイル
  5. ボットとデータベース接続の初期化
  6. メインコード
  7. ボットの打ち上げ


まず、必要なソフトウェアをすべてインストールする必要があります。





次に、将来のボット用のAPIキーを取得します。 これを行うには、ボットBotFatherを作成します。 およそ何が起こるべきか:



画像



プログラミングを開始する前に、プロジェクトの構造を決定する必要があります。次のようにしました。



/project/ /conf/ settings.go /src/ database.go telegramBot.go main.go
      
      





コードの作成を始めましょう! まず、設定ファイル(settings.go):



 const ( TELEGRAM_BOT_API_KEY = "paste your key here" // API ,     BotFather MONGODB_CONNECTION_URL = "localhost" //   MongoDB MONGODB_DATABASE_NAME = "regbot" //    MONGODB_COLLECTION_USERS = "users" //   )
      
      





データベース内のユーザーごとに、チャットID( chat_id )と携帯電話番号( phone_number )が保存されます。 したがって、すぐにユーザー構造を作成します



 type User struct { Chat_ID int64 Phone_Number string }
      
      





DatabaseConnection構造を使用してMongoDBに接続します。



 type DatabaseConnection struct { Session *mgo.Session //    DB *mgo.Database //     }
      
      





ボットをTelegramBot構造として表します。



 type TelegramBot struct { API *tgbotapi.BotAPI // API  Updates tgbotapi.UpdatesChannel //   ActiveContactRequests []int64 // ID ,      }
      
      





MongoDBを使用した接続初期化関数:



 func (connection *DatabaseConnection) Init() { session, err := mgo.Dial(conf.MONGODB_CONNECTION_URL) //    if err != nil { log.Fatal(err) //      } connection.Session = session db := session.DB(conf.MONGODB_DATABASE_NAME) //     connection.DB = db }
      
      





ボット初期化関数:



 func (telegramBot *TelegramBot) Init() { botAPI, err := tgbotapi.NewBotAPI(conf.TELEGRAM_BOT_API_KEY) //  API if err != nil { log.Fatal(err) } telegramBot.API = botAPI botUpdate := tgbotapi.NewUpdate(0) //    botUpdate.Timeout = 64 botUpdates, err := telegramBot.API.GetUpdatesChan(botUpdate) if err != nil { log.Fatal(err) } telegramBot.Updates = botUpdates }
      
      





ボットは初期化されますが、何もする方法がまだわかりません。 続けましょう!



次のステップは「ボットのメインサイクル」です。



 func (telegramBot *TelegramBot) Start() { for update := range telegramBot.Updates { if update.Message != nil { //    ->   telegramBot.analyzeUpdate(update) } } }
      
      





これは無限のサイクルです。 すべての着信メッセージの処理は、それから始まります。 処理の開始時に、ユーザーがデータベースに存在するかどうかを確認する必要があります。 いいえ-番号を作成してリクエストします、あります-処理を続行します。



 //    func (telegramBot *TelegramBot) analyzeUpdate(update tgbotapi.Update) { chatID := update.Message.Chat.ID if telegramBot.findUser(chatID) { //     ? telegramBot.analyzeUser(update) } else { telegramBot.createUser(User{chatID, ""}) //   telegramBot.requestContact(chatID) //   } } func (telegramBot *TelegramBot) findUser(chatID int64) bool { find, err := Connection.Find(chatID) if err != nil { msg := tgbotapi.NewMessage(chatID, " !    !") telegramBot.API.Send(msg) } return find } func (telegramBot *TelegramBot) createUser(user User) { err := Connection.CreateUser(user) if err != nil { msg := tgbotapi.NewMessage(user.Chat_ID, " !    !") telegramBot.API.Send(msg) } } func (telegramBot *TelegramBot) requestContact(chatID int64) { //   requestContactMessage := tgbotapi.NewMessage(chatID, "          ?") //     acceptButton := tgbotapi.NewKeyboardButtonContact("") declineButton := tgbotapi.NewKeyboardButton("") //   requestContactReplyKeyboard := tgbotapi.NewReplyKeyboard([]tgbotapi.KeyboardButton{acceptButton, declineButton}) requestContactMessage.ReplyMarkup = requestContactReplyKeyboard telegramBot.API.Send(requestContactMessage) //   telegramBot.addContactRequestID(chatID) //  ChatID    } func (telegramBot *TelegramBot) addContactRequestID(chatID int64) { telegramBot.ActiveContactRequests = append(telegramBot.ActiveContactRequests, chatID) }
      
      





最初の処理が記述されました。次に、データベースとの通信を記述しましょう。



 var Connection DatabaseConnection // ,        //     func (connection *DatabaseConnection) Find(chatID int64) (bool, error) { collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) //   "users" count, err := collection.Find(bson.M{"chat_id": chatID}).Count() //      ChatID if err != nil || count == 0 { return false, err } else { return true, err } } //   func (connection *DatabaseConnection) GetUser(chatID int64) (User, error) { var result User find, err := connection.Find(chatID) //  ,    if err != nil { return result, err } if find { //   ->  collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) err = collection.Find(bson.M{"chat_id": chatID}).One(&result) return result, err } else { //  ->  NotFound return result, mgo.ErrNotFound } } //   func (connection *DatabaseConnection) CreateUser(user User) error { collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) err := collection.Insert(user) return err } //     func (connection *DatabaseConnection) UpdateUser(user User) error { collection := connection.DB.C(conf.MONGODB_COLLECTION_USERS) err := collection.Update(bson.M{"chat_id": user.Chat_ID}, &user) return err }
      
      





これらはすべて便利な機能です。 ボットについては、メッセージ処理と連絡先分析を継続するための関数を記述する必要があります。



 func (telegramBot *TelegramBot) analyzeUser(update tgbotapi.Update) { chatID := update.Message.Chat.ID user, err := Connection.GetUser(chatID) //        if err != nil { msg := tgbotapi.NewMessage(chatID, " !    !") telegramBot.API.Send(msg) return } if len(user.Phone_Number) > 0 { msg := tgbotapi.NewMessage(chatID, " : " + user.Phone_Number) //      ,    telegramBot.API.Send(msg) return } else { //   ,         ChatID if telegramBot.findContactRequestID(chatID) { telegramBot.checkRequestContactReply(update) //   ->  return } else { telegramBot.requestContact(chatID) //   ->   return } } } //    func (telegramBot *TelegramBot) checkRequestContactReply(update tgbotapi.Update) { if update.Message.Contact != nil { // ,     if update.Message.Contact.UserID == update.Message.From.ID { //       telegramBot.updateUser(User{update.Message.Chat.ID, update.Message.Contact.PhoneNumber}, update.Message.Chat.ID) //   telegramBot.deleteContactRequestID(update.Message.Chat.ID) //  ChatID    msg := tgbotapi.NewMessage(update.Message.Chat.ID, "!") msg.ReplyMarkup = tgbotapi.NewRemoveKeyboard(false) //   telegramBot.API.Send(msg) } else { msg := tgbotapi.NewMessage(update.Message.Chat.ID, " ,   ,   !") telegramBot.API.Send(msg) telegramBot.requestContact(update.Message.Chat.ID) } } else { msg := tgbotapi.NewMessage(update.Message.Chat.ID, "      ,     !") telegramBot.API.Send(msg) telegramBot.requestContact(update.Message.Chat.ID) } } //      func (telegramBot *TelegramBot) updateUser(user User, chatID int64) { err := Connection.UpdateUser(user) if err != nil { msg := tgbotapi.NewMessage(chatID, " !    !") telegramBot.API.Send(msg) return } } //  ChatID   ? func (telegramBot *TelegramBot) findContactRequestID(chatID int64) bool { for _, v := range telegramBot.ActiveContactRequests { if v == chatID { return true } } return false } //  ChatID    func (telegramBot *TelegramBot) deleteContactRequestID(chatID int64) { for i, v := range telegramBot.ActiveContactRequests { if v == chatID { copy(telegramBot.ActiveContactRequests[i:], telegramBot.ActiveContactRequests[i + 1:]) telegramBot.ActiveContactRequests[len(telegramBot.ActiveContactRequests) - 1] = 0 telegramBot.ActiveContactRequests = telegramBot.ActiveContactRequests[:len(telegramBot.ActiveContactRequests) - 1] } } }
      
      





ボットの準備が整いました! 実行するためだけに残ります。 これを行うには、 main.goに書き込みます



 var telegramBot src.TelegramBot func main() { src.Connection.Init() //     telegramBot.Init() //   telegramBot.Start() }
      
      





その結果、ユーザーに自分の番号を尋ねるボットを取得しました。この番号はシステムでさらに使用されます。 ボットは改善することができ、改善する必要があり、サイトとの統合を追加し、ワンタイムパスワードでログインします。



間違いなく、このシステムには欠点がありますが、その中で最も明白なのは、テレグラムの依存性(APIの変更、ブロッキング)です。 私にとって、これは電子メールやSMSの代替として最適です。使用するかどうかはあなた次第です。 ご清聴ありがとうございました!



All Articles