Un autre bot de télégramme ou mise en œuvre de bot de datation

Je m'appelle Vlad, de profession je suis militaire, mais je travaille à temps partiel dans une entreprise d'automatisation commerciale, où je fais de la programmation sur .net.

Bref historique


Au moment de la prochaine divergence de convergence avec mon ex-mariée (régulière), elle a déclaré que, par ennui, elle cherchait des gars pour des rendez-vous via un télégramme, qui pourrait envoyer des photos et de la géolocalisation et vous chercher des gens qui sont à proximité. J'ai promis d'écrire quelque chose de similaire si nous nous enfuyions à nouveau. Yara est pour toi.
Je l'ai oublié en toute sécurité, mais au moment de la prochaine oisiveté, j'ai fait défiler le site Web avec un petit gâteau sur fond vert , où je suis tombé sur une section où les gens venaient de poster un post avec une photo, d'écrire brièvement sur eux-mêmes et d'indiquer des contacts.

L'idée est donc venue d'écrire votre bot, ce qui aiderait les gens à trouver des amis ou n'importe qui d'autre.

Défi


Créez un bot où quiconque souhaite discuter peut publier de brèves informations sur lui-même et attendre de lui écrire.



Préparation au travail


Comment créer un bot via BotFather ne connaît pas seulement celui qui n'est pas intéressé, donc je ne remplirai pas l'article d'informations supplémentaires.

Stockage des "profils"


Au départ, j'ai créé le projet ClassLibrary, que j'allais utiliser pour travailler avec des données.

Vous devez d'abord décider comment stocker les données utilisateur. Pour ce faire, nous devons "décrire" l'utilisateur.

public class user { [Key] public string tg_id { get; set; }//   public string name { get; set; }//  public string age { get; set; }//  public string country { get; set; }//  public string city { get; set; }// public string gender { get; set; }// public string photo { get; set; }//   public string tg_username { get; set; }// -,           public string tg_chat_id { get; set; }// ,    } 

Pour le stockage, la base de données PostgreSQL a été sélectionnée, qui a été déployée sur un serveur distant.
Tout d'abord, définissez EntityFramework via NuGet. Il simplifie de façon irréaliste la vie en travaillant avec la base de données.

Pour travailler, vous avez besoin du package:

NpgSQL.EntityFrameworkCore.PostgreSQL

Et pour les migrations, un package est requis:

Microsoft.EntityFrameworkCore.Tools

Afin de ne pas traiter de la création de routine de la table, nous créons simplement le modèle de données lui-même (notre classe ci-dessus) et définissons la connexion à la base de données.

 public DbSet<user> user { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql(connectionString); } 

De plus, nous effectuons la migration.

Pour ce faire, dans la console du gestionnaire de packages, exécutez les commandes:
enable-migrations
Activer le mécanisme de migration
Add-migration * *
Créer une migration
update-database
Mise à jour de la base de données

Maintenant, dans notre base de données, deux tables apparaîtront: l'historique des migrations et la table utilisateur elle-même.



Après avoir résolu le problème du stockage des données et de la connexion à la base de données, vous pouvez procéder à l'écriture du gestionnaire de bot lui-même.

Bot gestionnaire


Telegram lui-même offre deux options pour recevoir des mises à jour: webhook ou tirer constamment sur le serveur, vérifier les mises à jour. Webhook a beaucoup de difficultés, il est donc plus facile de simplement vérifier les mises à jour.

Recevoir des mises à jour, les traiter


Afin de ne pas créer de vélo (parfois c'est utile), il est plus facile d'utiliser une solution toute faite: Telegram.Bot de MrRoundRobin est une excellente bibliothèque très pratique pour travailler avec Telegram.

Nous créons un nouveau projet ConsoleApp dans la solution, où nous installons ce package.

 private static readonly TelegramBotClient Bot = new TelegramBotClient(token);//  static void Main(string[] args) { var me = Bot.GetMeAsync().Result;//  ,    (  ,   ) Console.Title = me.Username; //   Bot.OnMessage += BotOnMessageReceived; Bot.OnCallbackQuery += BotOnCallbackQueryReceived; Bot.OnReceiveError += BotOnReceiveError; //   Bot.StartReceiving(Array.Empty<UpdateType>()); Console.WriteLine($"Start listening for @{me.Username}"); Console.ReadLine(); Bot.StopReceiving(); } 

Ainsi, nous avons commencé à rechercher des mises à jour et installé nos gestionnaires d'erreurs.
BotOnMessageReceived - un gestionnaire pour recevoir des messages "réguliers"
BotOnCallbackQueryReceived - le gestionnaire pour appuyer sur les boutons qui apparaissent sous le message.

Le cas est petit, la possibilité de laisser un questionnaire et la possibilité de faire défiler le reste. Vous devez donc envoyer à l'utilisateur deux boutons: Enregistrement et Suivant. Un bouton représente un objet InlineKeyboardButton , et tous les boutons doivent être emballés dans

 IEnumerable<IEnumerable<InlineKeyboardButton>> 

Lorsque le bot est ouvert, un message avec le texte "/ start" lui est immédiatement envoyé, nous devons donc traiter ce message dans BotOnMessageReceived et envoyer nos boutons en réponse.

 if (message.Text == "/start") { var inlineKeyboard = new InlineKeyboardMarkup(new[] { new [] // first row { InlineKeyboardButton.WithCallbackData("!", "Next"), InlineKeyboardButton.WithCallbackData("", "Registration") } }); Bot.SendTextMessageAsync(message.Chat.Id, "   lovebot! \r\n   - /start\r\n       - /register\r\n     - /stats\r\n     - @hahah2016", replyMarkup: inlineKeyboard); return; } 

Inscription


Pour vous inscrire, vous devez vous rappeler ce que l'utilisateur a entré plus tôt. Autrement dit, nous devons créer un stockage de bot. Je viens de créer une classe où j'ai décrit la logique de remplissage des données.

RegForm.cs
 public class RegForm { public string tg_id { get; set; } public string name { get; set; } public string age { get; set; } public string country { get; set; } public string city { get; set; } public string gender { get; set; } public string photo { get; set; } public string tg_username { get; set; } public string tg_chat_id { get; set; } public int stage; public RegForm(string id, string chat_id, string username) { stage = 1; tg_id = id; tg_username = username; } public (string, int) StageText(string id) { if (stage == 1) return ("  :", stage); if (stage == 2) return (" :", stage); if (stage == 3) return ("  :", stage); if (stage == 4) return ("  :", stage); if (stage == 5) return ("  :", stage); else return ("   :", stage); } public bool SetParam(string param) { if (stage == 1) name = param; if (stage == 2) age = param; if (stage == 3) country = param; if (stage == 4) city = param; if (stage == 5) gender = param; if (stage == 6) photo = param; stage++; return true; } } 

Dans cette classe, vous pouvez implémenter la validation des données, par exemple, ne manquez pas l'âge sous forme de texte, etc.

Et la mémoire elle-même est le static Dictionary<string, RegForm> registrations = new Dictionary<string, RegForm>(); dans lequel nous ajoutons un nouveau KeyValuePair, au clic d'un bouton.

Pour que le bot sache comment répondre au clic, vous devez ajouter dans BotOnCallbackQueryReceived

 var message = e.CallbackQuery; if (message.Data == "Registration") { RegForm form = new RegForm(message.From.Id.ToString(), message.Message.Chat.Id.ToString(), message.From.Username);//    registrations.Add(message.From.Id.ToString(), form);//   "",    telegram_id . var t = form.StageText(form.tg_id); // ,   ,     . Bot.SendTextMessageAsync(message.Message.Chat.Id, t.Item1);//  . return; } 

Et de la même manière, en traitant les données reçues, vous pouvez remplir le formulaire et enregistrer les données.
  using (Context db = new Context()) { IMapper mapper = new MapperConfiguration(cfg => cfg.CreateMap<RegForm, User>()).CreateMapper(); if (db.user.Where(x => x.tg_id == message.From.Id.ToString()).Count() != 0) db.user.Update(mapper.Map<RegForm, tgbot_base.classes.user>(u)); else { db.user.Add(mapper.Map<RegForm, tgbot_base.classes.user>(u)); } db.SaveChanges(); } 

Si l'utilisateur a déjà un profil, il suffit de mettre à jour les données.

Enregistrement de la photo de l'utilisateur
 if (message.Type == MessageType.Photo) { string file = Bot.GetFileAsync(message.Photo[message.Photo.Count() - 1].FileId).Result.FilePath; string filepath = message.From.Id + "." + file.Split('.').Last(); using (FileStream fileStream = new FileStream("C:\\images\\" + filepath, FileMode.OpenOrCreate, FileAccess.ReadWrite)) { var st = Bot.DownloadFileAsync(file).Result; st.Position = 0; st.CopyTo(fileStream); } u.SetParam("C:\\images\\" + filepath); } 


Afficher d'autres profils


Pour ce faire, il vous suffit de prendre les données de la base de données et de les envoyer à l'utilisateur.

Pour ce faire, nous écrivons une méthode simple qui prendra les données de la base de données et les renverra dans un format pratique:

 public static User GetRandom() { Stopwatch s = new Stopwatch(); s.Start(); User u; using (Context db = new Context()) { Random r = new Random(); int count = db.user.Count(); if (count > 1) count = count - 1; List<User> users = mapper.Map<List<tgbot_base.classes.user>, List<User>>(db.user.ToList()); u = users.ElementAt(r.Next(0, count)); } Console.WriteLine("[" + DateTime.Now + "] For finding " + s.ElapsedMilliseconds + " ms"); s = null; return u; } 

Gestionnaire de clics sur le bouton Suivant:

 if (message.Data == "Next") { if (searchForms.Count != 0) { searchForms.Remove(message.From.Id.ToString()); } IMapper mapper = new MapperConfiguration(cfg => cfg.CreateMap<RegForm, User>()).CreateMapper(); User user = BaseWorker.GetRandom(); SendAnket(user, message.Message.Chat.Id.ToString());//,     . return; } 

Conclusion


Pour toute sa simplicité, le public a aimé le bot.

En moins d'une journée, 134 utilisateurs ont quitté leur profil, les retours sont positifs. Et sans publicité spéciale - il n'y a qu'un seul message sur le site, qui n'a pas particulièrement marqué d'avantages.

Les robots sont un vieux vieux oublié qui a trouvé une nouvelle vie. Ils aident à vraiment automatiser de nombreux processus et même à chercher un partenaire sur Internet. Contourner les sites de rencontres monétisés.

Merci d'avoir lu jusqu'au bout.

Bonne chance, amusez-vous, ne mangez pas de neige jaune.

Source: https://habr.com/ru/post/fr430314/


All Articles