ट्रिविया गेम एक आकर्षक और शैक्षिक अनुभव प्रदान करते हैं जहां आप नए तथ्य सीख सकते हैं और विभिन्न विषयों में अपने ज्ञान का विस्तार कर सकते हैं। आजकल, ट्रिविया क्विज़ मोबाइल और वेब एप्लिकेशन ऐसी गतिविधि के लिए सबसे आम क्षेत्र हैं। व्हाट्सएप पर ट्रिविया गेम खेलने के बारे में क्या ख़याल है?
इस ट्यूटोरियल गाइड में, आप सीखेंगे कि व्हाट्सएप, एएसपी.नेट कोर और के लिए ट्विलियो का उपयोग करके एक सामान्य ज्ञान प्रश्नोत्तरी एप्लिकेशन कैसे बनाया जाए।
इन प्रश्नों को लाने के लिए, आप द ट्रिविया एपीआई, एक आरईएसटी एपीआई का उपयोग करेंगे, जो डेवलपर्स के लिए बहुविकल्पीय सामान्य ज्ञान प्रश्न प्रदान करके क्विज़ ऐप बनाना आसान बनाता है। ट्रिविया एपीआई के बारे में अधिक जानने के लिए, कृपया ट्रिविया एपीआई दस्तावेज़ पर जाएँ।
इस ट्यूटोरियल को पूरा करने के लिए, आपको आवश्यकता होगी:
आरंभ करने के लिए, पसंदीदा कार्यशील निर्देशिका में अपने शेल टर्मिनल का उपयोग करके, एक नया वेब एपीआई प्रोजेक्ट बनाने के लिए निम्नलिखित कमांड चलाएँ:
dotnet new webapi -n TwilioWhatsAppTriviaApp --no-openapi
उपरोक्त स्निपेट में दूसरा कमांड निर्दिष्ट नाम के साथ और ओपनएपीआई (स्वैगर) समर्थन के बिना एक नया वेब एपीआई प्रोजेक्ट बनाएगा। यदि आप प्रोजेक्ट में स्वैगर का उपयोग करना चाहते हैं, तो बस उपरोक्त कमांड में --no-openapi
छोड़ दें।
इस आदेश को चलाकर प्रोजेक्ट निर्देशिका में बदलें:
cd TwilioWhatsAppTriviaApp
स्थापित करें
dotnet add package Twilio.AspNet.Core
यह लाइब्रेरी ASP.NET कोर एप्लिकेशन में ट्विलियो वेबहुक और एपीआई के साथ काम करना सरल बनाती है।
अपनी पसंदीदा आईडीई का उपयोग करके प्रोजेक्ट खोलें। कंट्रोलर फ़ोल्डर में, बॉयलरप्लेट टेम्प्लेट नियंत्रक फ़ाइल, वेदरफॉरकास्टकंट्रोलर.cs को हटा दें, और प्रोजेक्ट निर्देशिका में वेदरफॉरकास्ट.cs को भी हटा दें।
निम्नलिखित आदेशों का उपयोग करके यह सुनिश्चित करने के लिए अपना प्रोजेक्ट बनाएं और चलाएं कि आपने अब तक जो कुछ भी किया है वह अच्छी तरह से काम करता है:
dotnet build dotnet run
प्रोजेक्ट को सफलतापूर्वक चलाने के बाद, डिबगिंग कंसोल में दिखाई देने वाले किसी भी लोकलहोस्ट यूआरएल पर ध्यान दें। आप ngrok का उपयोग करके सार्वजनिक रूप से सुलभ स्थानीय वेब सर्वर स्थापित करने के लिए इनमें से किसी भी URL का उपयोग कर सकते हैं।
सत्र ASP.NET कोर एप्लिकेशन में उपयोगकर्ता के डेटा को संग्रहीत करने के कई तरीकों में से एक है। यह तब आवश्यक है जब आप अनुरोधों के बीच उपयोगकर्ता डेटा को बनाए रखना चाहते हैं क्योंकि डिफ़ॉल्ट रूप से, HTTP प्रोटोकॉल स्टेटलेस है - इसका मतलब है कि डेटा संरक्षित नहीं है।
प्रोग्राम.सीएस को संशोधित करके इन-मेमोरी सत्र प्रदाता जोड़ें, जैसा कि निम्नलिखित कोड में दिखाया गया है:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromSeconds(40); options.Cookie.IsEssential = true; }); var app = builder.Build(); app.UseSession(); app.MapControllers(); app.Run();
AddDistributedMemoryCache()
वितरित मेमोरी कैश सेवा को पंजीकृत करता है। यह सेवा एक इन-मेमोरी कैश प्रदान करती है जिसका उपयोग कई अनुरोधों या सत्रों में डेटा को संग्रहीत और पुनर्प्राप्त करने के लिए किया जा सकता है।
AddSession()
सत्र सेवाओं को पंजीकृत करता है, जिससे एप्लिकेशन सत्र स्थिति बनाए रखने में सक्षम होता है। options
पैरामीटर आपको विभिन्न सत्र-संबंधित विकल्पों को कॉन्फ़िगर करने की अनुमति देता है। IdleTimeout
का उपयोग निष्क्रियता की अवधि निर्धारित करने के लिए किया जाता है जिसके बाद एक सत्र निष्क्रिय माना जाएगा। इस स्थिति में, इसे 40 सेकंड पर सेट किया गया है। Cookie.IsEssential
यह सुनिश्चित करता है कि सत्र की स्थिति कार्यात्मक बनी रहे और यहां तक कि उन परिदृश्यों में भी जहां कुकी अस्वीकृति सक्षम है।
सत्र समर्थन को एप्लिकेशन पाइपलाइन में UseSession
मिडलवेयर जोड़कर सक्षम किया जाता है, अर्थात, आपका एप्लिकेशन एक सत्र ऑब्जेक्ट तक पहुंच प्राप्त करता है जिसका उपयोग डेटा को संग्रहीत और पुनर्प्राप्त करने के लिए किया जा सकता है।
अपनी प्रोजेक्ट निर्देशिका में एक नया फ़ोल्डर, मॉडल बनाएं। निम्नलिखित कोड नमूनों में दिखाए गए गुणों के साथ दो मॉडल क्लास फ़ाइलें, TriviaApiResponse.cs और Question.cs जोड़ें:
using Newtonsoft.Json; namespace TwilioWhatsAppTriviaApp.Models; public class TriviaApiResponse { [JsonProperty("category")] public string Category { get; set; } [JsonProperty("correctAnswer")] public string CorrectAnswer { get; set; } [JsonProperty("incorrectAnswers")] public List<string> IncorrectAnswers { get; set; } [JsonProperty("question")] public string Question { get; set; } [JsonProperty("type")] public string? Type { get; set; } [JsonProperty("difficulty")] public string Difficulty { get; set; } }
namespace TwilioWhatsAppTriviaApp.Models; public class Question { public string QuestionText { get; set; } public List<(string option, bool isCorrect)> Options { get; set; } }
TriviaApiResponse
मॉडल में वे गुण शामिल हैं जो ट्रिविया एपीआई प्रतिक्रिया के क्षेत्रों का प्रतिनिधित्व करते हैं। JsonProperty
विशेषता यह सुनिश्चित करती है कि प्रत्येक प्रॉपर्टी संबंधित JSON डेटा के साथ सही ढंग से भरी हुई है।
सामान्य ज्ञान के प्रश्नों को सुव्यवस्थित तरीके से संभालने के लिए, Question
कक्षा बचाव के लिए आती है। यह कक्षा एक सामान्य प्रश्न के लिए आवश्यक जानकारी को समाहित करती है, जिसमें प्रश्न पाठ और विकल्पों की सूची शामिल है। प्रत्येक विकल्प को एक टपल द्वारा दर्शाया जाता है जिसमें विकल्प टेक्स्ट और एक बूलियन मान होता है जो दर्शाता है कि यह सही विकल्प है या नहीं।
अपनी प्रोजेक्ट निर्देशिका में एक सेवा फ़ोल्डर बनाएं और TriviaService.cs नामक एक नई क्लास फ़ाइल जोड़ें। इसकी सामग्री को संशोधित करें, जैसा कि निम्नलिखित कोड में दिखाया गया है:
using Newtonsoft.Json; using TwilioWhatsAppTriviaApp.Models; namespace TwilioWhatsAppTriviaApp.Services; public class TriviaService { private const string TheTriviaApiUrl = @"https://the-trivia-api.com/api/questions?limit=3"; private HttpClient httpClient; public TriviaService(HttpClient httpClient) { this.httpClient = httpClient; } public async Task<IEnumerable<TriviaApiResponse>> GetTrivia() { var response = await httpClient.GetAsync(TheTriviaApiUrl); var triviaJson = await response.Content.ReadAsStringAsync(); var trivia = JsonConvert.DeserializeObject<IEnumerable<TriviaApiResponse>>(triviaJson); return trivia; } public List<Question> ConvertTriviaToQuestions(IEnumerable<TriviaApiResponse> questions) { List<Question> newQuestions = new(); foreach (var question in questions) { var options = new List<(string option, bool isCorrect)>() { (question.CorrectAnswer, true), (question.IncorrectAnswers[0], false), (question.IncorrectAnswers[1], false), (question.IncorrectAnswers[2], false) }; // Shuffle the options randomly Random random = new(); options = options.OrderBy(_ => random.Next()).ToList(); newQuestions.Add(new Question { QuestionText = question.Question, Options = options }); } return newQuestions; } }
TriviaService
क्लास में दो विधियाँ हैं: GetTrivia
और ConvertTriviaToQuestions
। GetTrivia
विधि एक क्वेरी पैरामीटर, limit=3
के साथ ट्रिविया एपीआई को HTTP GET अनुरोध भेजती है, जो निर्दिष्ट करती है कि केवल 3 प्रश्न लौटाए जाने चाहिए। सीमा पैरामीटर के बिना, एपीआई डिफ़ॉल्ट रूप से 10 प्रश्न लौटाता है।
ConvertTriviaToQuestions
विधि एपीआई से प्रतिक्रिया को व्यवस्थित तरीके से परिवर्तित करती है। यह विधि सभी प्रश्न विकल्पों को बेतरतीब ढंग से बदल देती है, जिससे कि एक ही विकल्प सभी प्रश्नों का उत्तर नहीं होगा।
अपने एप्लिकेशन के डिपेंडेंसी इंजेक्शन (डीआई) कंटेनर में TriviaService
और HTTP क्लाइंट को पंजीकृत करने के लिए, निम्नलिखित कोड में दिखाए अनुसार प्रोग्राम.सीएस को संशोधित करें:
using TwilioWhatsAppTriviaApp.Services; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddDistributedMemoryCache(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromSeconds(40); options.Cookie.IsEssential = true; }); builder.Services.AddHttpClient(); builder.Services.AddScoped<TriviaService>(); var app = builder.Build(); app.UseSession(); app.MapControllers(); app.Run();
कंट्रोलर फ़ोल्डर में TriviaController.cs नामक फ़ाइल में एक खाली एपीआई नियंत्रक वर्ग जोड़ें और इसकी सामग्री को निम्न कोड में दिखाए अनुसार संशोधित करें:
using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Twilio.AspNet.Core; using Twilio.TwiML; using Twilio.TwiML.Messaging; using TwilioWhatsAppTriviaApp.Models; using TwilioWhatsAppTriviaApp.Services; namespace WhatsappTrivia.Controllers; [Route("[controller]")] [ApiController] public class TriviaController : TwilioController { private const string SessionKeyIsGameOn = "IsGameOn"; private const string SessionKeyScore = "Score"; private const string SessionKeyCurrentQuestionIndex = "CurrentQuestionIndex"; private const string SessionKeyTotalQuestions = "TotalQuestions"; private const string SessionKeyQuestions = "Questions"; private static readonly string[] StartCommands = { "START", "S" }; private static readonly string[] OptionValues = { "A", "B", "C", "D" }; private readonly TriviaService triviaService; public TriviaController(TriviaService triviaService) { this.triviaService = triviaService; } [HttpPost] public async Task<IActionResult> Index() { var response = new MessagingResponse(); var form = await Request.ReadFormAsync(); var body = form["Body"].ToString().ToUpper().Trim(); await HttpContext.Session.LoadAsync(); var isGameOn = Convert.ToBoolean(HttpContext.Session.GetString(SessionKeyIsGameOn)); int currentQuestionIndex = HttpContext.Session.GetInt32(SessionKeyCurrentQuestionIndex) ?? 0; int totalQuestions = HttpContext.Session.GetInt32(SessionKeyTotalQuestions) ?? 0; if (StartCommands.Contains(body) && !isGameOn) { await StartGame(); HttpContext.Session.SetString(SessionKeyIsGameOn, "true"); response.Message(PresentQuestionWithOptions(currentQuestionIndex)); return TwiML(response); } if (OptionValues.Contains(body) && isGameOn) { var result = ProcessUserAnswer(body, currentQuestionIndex); response.Message(result); currentQuestionIndex++; if (currentQuestionIndex <= totalQuestions - 1) { HttpContext.Session.SetInt32(SessionKeyCurrentQuestionIndex, currentQuestionIndex); response.Append(new Message(PresentQuestionWithOptions(currentQuestionIndex))); } else { response.Append(new Message(EndTrivia())); } return TwiML(response); } response.Message(!isGameOn ? "*Hello! Send 'Start' or 'S' to play game*" : "*Invalid Input! Send a correct option 'A', 'B', 'C' or 'D'*"); return TwiML(response); } private async Task StartGame() { if (HttpContext.Session.GetString(SessionKeyQuestions) != null) { HttpContext.Session.Remove(SessionKeyQuestions); } var trivia = await this.triviaService.GetTrivia(); var questions = this.triviaService.ConvertTriviaToQuestions(trivia); AddNewQuestionsToSession(questions); HttpContext.Session.SetInt32(SessionKeyTotalQuestions, questions.Count); } private string ProcessUserAnswer(string userAnswer, int questionIndex) { bool optionIsCorrect = false; int score = HttpContext.Session.GetInt32(SessionKeyScore) ?? 0; var question = RetrieveQuestionFromSession(questionIndex); switch (userAnswer) { case "A": optionIsCorrect = question.Options[0].isCorrect; break; case "B": optionIsCorrect = question.Options[1].isCorrect; break; case "C": optionIsCorrect = question.Options[2].isCorrect; break; case "D": optionIsCorrect = question.Options[3].isCorrect; break; } if (optionIsCorrect) { score++; HttpContext.Session.SetInt32(SessionKeyScore, score); } return optionIsCorrect ? "_Correct ✅_" : $"_Incorrect ❌ Correct answer is {question.Options.Find(o => o.isCorrect).option.TrimEnd()}_"; } private string PresentQuestionWithOptions(int questionIndex) { var question = RetrieveQuestionFromSession(questionIndex); return $""" {questionIndex + 1}. {question.QuestionText} {OptionValues[0]}. {question.Options[0].option} {OptionValues[1]}. {question.Options[1].option} {OptionValues[2]}. {question.Options[2].option} {OptionValues[3]}. {question.Options[3].option} """; } private void AddNewQuestionsToSession(List<Question> questions) => HttpContext.Session.SetString(SessionKeyQuestions, JsonConvert.SerializeObject(questions)); private Question RetrieveQuestionFromSession(int questionIndex) { var questionsFromSession = HttpContext.Session.GetString(SessionKeyQuestions); return JsonConvert.DeserializeObject<List<Question>>(questionsFromSession)[questionIndex]; } private string EndTrivia() { var score = HttpContext.Session.GetInt32(SessionKeyScore) ?? 0; var totalQuestions = HttpContext.Session.GetInt32(SessionKeyTotalQuestions) ?? 0; var userResult = $""" Thanks for playing! 😊 You answered {score} out of {totalQuestions} questions correctly. To play again, send 'Start' or 'S' """; HttpContext.Session.Clear(); return userResult; } }
यह नियंत्रक वर्ग आने वाले संदेशों को संभालने, सत्र स्थिति को प्रबंधित करने और प्रतिक्रियाएँ उत्पन्न करने के लिए जिम्मेदार है। यह Twilio.AspNet.Core लाइब्रेरी द्वारा प्रदान की गई TwilioController
क्लास से प्राप्त होता है, जो आपको TwiML
विधि तक पहुंच प्रदान करता है। आप प्रतिक्रिया देने के लिए इस पद्धति का उपयोग कर सकते हैंTriviaController
क्लास सत्र के साथ इंटरैक्ट करने के लिए HttpContext.Session
विधियों का उपयोग करता है।
मान्य इनपुट StartCommands
और OptionValues
रीड-ओनली ऐरे में तत्व हैं। यह सुनिश्चित करने के लिए कि उपयोगकर्ता ने उचित इनपुट भेजा है, आने वाले संदेश के मुख्य भाग की तुलना इन तत्वों से की जाती है, यदि नहीं, तो उपयोगकर्ता को गेम की वर्तमान स्थिति के आधार पर सही इनपुट करने के लिए संकेत देते हुए एक संदेश भेजा जाएगा। "SessionKey" उपसर्ग वाले अन्य फ़ील्ड का उपयोग प्रोग्राम में सत्र कुंजियों के लिए निजी स्थिरांक स्ट्रिंग को परिभाषित करने के लिए किया जाता है।
Index
विधि मुख्य क्रिया विधि है जो /ट्रिविया मार्ग के माध्यम से व्हाट्सएप से आने वाले HTTP POST अनुरोधों को संभालती है। यह HttpContext.Session.LoadAsync()
का उपयोग करके सत्र डेटा लोड करता है और HttpContext.Session.GetString()
और HttpContext.Session.GetInt32()
विधियों का उपयोग करके सत्र से गेम स्थिति के बारे में डेटा पुनर्प्राप्त करता है।
कुछ स्ट्रिंग्स की शुरुआत और अंत में अंडरस्कोर (_) और तारांकन (*) का उपयोग क्रमशः प्रदान किए गए व्हाट्सएप संदेशों में इटैलिक और बोल्ड टेक्स्ट फ़ॉर्मेटिंग प्राप्त करने के लिए है।
TriviaController
में प्रत्येक सहायक विधि एक विशिष्ट कार्य करती है जो कक्षा की मुख्य कार्यक्षमता का समर्थन करती है।
StartGame
विधि सामान्य ज्ञान के प्रश्नों को पुनः प्राप्त करके, उन्हें गेम के लिए उपयुक्त प्रारूप में परिवर्तित करके और उन्हें सत्र में संग्रहीत करके गेम को आरंभ करती है।ProcessUserAnswer
विधि किसी प्रश्न के लिए उपयोगकर्ता के उत्तर को संसाधित करती है और यह निर्धारित करती है कि यह सही है या नहीं।PresentQuestionWithOptions
विधि किसी प्रश्न को उसके विकल्पों के साथ स्वरूपित करने और प्रस्तुत करने के लिए जिम्मेदार है।AddNewQuestionsToSession
विधि सत्र में प्रश्नों की एक सूची संग्रहीत करती है। यह प्रश्नों को JSON प्रारूप में परिवर्तित करता है और सत्र में JSON स्ट्रिंग को सहेजता है।RetrieveQuestionFromSession
विधि प्रश्न अनुक्रमणिका का उपयोग करके सत्र से एक प्रश्न पुनर्प्राप्त करती है।EndTrivia
विधि ट्रिविया गेम को समाप्त करने के लिए एक संदेश उत्पन्न करती है। यह विधि गेम से संबंधित सत्र डेटा भी हटा देती है। प्रोग्राम.सीएस में सत्र सेवा के कॉन्फ़िगरेशन के आधार पर, यह स्वचालित रूप से तब होता है जब सत्र 40 सेकंड के लिए निष्क्रिय होता है।
एप्लिकेशन का परीक्षण करने के लिए, आपको व्हाट्सएप के लिए ट्विलियो सैंडबॉक्स सेट अप करना होगा, अपने एप्लिकेशन एंडपॉइंट को सार्वजनिक रूप से पहुंच योग्य बनाना होगा और सैंडबॉक्स कॉन्फ़िगरेशन में एंडपॉइंट यूआरएल को वेबहुक के रूप में जोड़ना होगा।
के पास जाओ
व्हाट्सएप सैंडबॉक्स के साथ एक सफल कनेक्शन बनाने के लिए, अपने डिवाइस से दिए गए ट्विलियो नंबर पर एक व्हाट्सएप संदेश भेजकर, सैंडबॉक्स से कनेक्ट करने के लिए पेज पर दिए गए निर्देशों का पालन करें। इसी तरह, अन्य व्यक्ति जो अपने संबंधित नंबरों के साथ आपके ऐप का परीक्षण करना चाहते हैं, उन्हें उसी प्रक्रिया का पालन करना होगा।
अब, एक शेल टर्मिनल खोलें और ngrok शुरू करने के लिए निम्न कमांड चलाएँ और <localhost-url>
को आपके द्वारा प्रारंभ में कॉपी किए गए लोकलहोस्ट के पूर्ण URL से प्रतिस्थापित करके अपने स्थानीय ASP.NET कोर ऐप को उजागर करें:
ngrok http <localhost-url>
एनग्रोक एक सार्वजनिक यूआरएल उत्पन्न करेगा जो आपके स्थानीय एएसपी.नेट ऐप पर अनुरोधों को अग्रेषित करेगा। ngrok टर्मिनल विंडो में फ़ॉरवर्डिंग लेबल वाले फ़ॉरवर्डिंग URL को देखें और उसे कॉपी करें।
ट्विलियो ट्राई व्हाट्सएप पेज पर वापस जाएं, सैंडबॉक्स सेटिंग्स पर क्लिक करें, और एनग्रोक प्लस / ट्रिविया रूट द्वारा जेनरेट किए गए फॉरवर्डिंग यूआरएल के साथ एंडपॉइंट यूआरएल में जब कोई संदेश आता है तो इसे बदलें और सुनिश्चित करें कि विधि POST पर सेट है। फिर नए सैंडबॉक्स कॉन्फ़िगरेशन को सहेजने के लिए सहेजें पर क्लिक करें।
निम्नलिखित कमांड का उपयोग करके अपना ASP.NET कोर प्रोजेक्ट चलाएँ:
dotnet run
अब, ट्विलियो सैंडबॉक्स नंबर के साथ शुरुआती बातचीत में एक संदेश भेजकर अपने एप्लिकेशन का परीक्षण करें।
ट्विलियो प्लेटफ़ॉर्म और व्हाट्सएप की शक्ति का लाभ उठाकर, आपने उपयोगकर्ताओं के आनंद के लिए एक व्यापक ट्रिविया गेम अनुभव बनाया है। आपने यह भी सीखा कि सत्रों से डेटा को कैसे सहेजना और पुनः प्राप्त करना है।
ऐसे कई तरीके हैं जिनसे इस परियोजना को बेहतर बनाया जा सकता है। आप टाइमर जोड़कर, अपवादों को संभालकर, उपयोगकर्ताओं को कठिनाई चुनने की अनुमति देकर और ट्रिविया एपीआई यूआरएल के माध्यम से क्वेरी पैरामीटर के रूप में चुनी गई कठिनाई को लागू करके इस प्रोजेक्ट को और बेहतर बना सकते हैं (उदाहरण के लिए)