Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Redis

QStash के साथ टाइमज़ोन-जागरूक शेड्यूलिंग: ईमेल अलर्ट को ठीक तब वितरित करें जब आप चाहते हैं

docsly में, हमने उपयोगकर्ताओं को पिछले सप्ताह या महीने में प्राप्त सभी फीडबैक का सारांश भेजने के लिए एक नई सुविधा लॉन्च की। ईमेल भेजना कोई नई समस्या नहीं है, लेकिन हम इस संबंध में सर्वोत्तम उपयोगकर्ता अनुभव प्रदान करना चाहते थे, इसलिए हमने तय किया कि सभी ईमेल उपयोगकर्ता के टाइमज़ोन में भेजे जाने चाहिए ताकि विषम घंटों पर ईमेल भेजने से बचा जा सके। हम उपयोगकर्ताओं को यह चुनने की क्षमता भी देना चाहते थे कि वे कितनी बार ईमेल प्राप्त करना चाहते हैं। हम उपयोगकर्ताओं को किसी भी समय शेड्यूल्ड ईमेल सूचनाओं को रद्द करने की क्षमता भी देना चाहते थे।

इस समाधान को लागू करना मुश्किल था क्योंकि:

  1. हम उपयोगकर्ता के टाइमज़ोन को अपने डेटाबेस में संग्रहीत नहीं करना चाहते थे।
  2. हम यह जांचने के लिए हर मिनट या घंटे में एक क्रॉन जॉब भी नहीं चलाना चाहते थे कि क्या ईमेल भेजने का समय हो गया है।
  3. हम उपयोगकर्ताओं को शेड्यूल्ड ईमेल सूचनाओं को रद्द करने देना भी चाहते थे।

तो, हम एक अनूठे समाधान के साथ आए: उपयोगकर्ता के टाइमज़ोन में क्रॉन जॉब शेड्यूल करें और फिर जब उपयोगकर्ता ईमेल सूचनाओं को रद्द करता है तो क्रॉन जॉब को रद्द करें। लेकिन एक सवाल बाकी था: कैसे?

हम पहले से ही Upstash को Redis स्टोर के रूप में उपयोग कर रहे थे, और हमने पाया कि QStash एक शेड्यूल सुविधा का भी समर्थन करता है। थोड़ा गहराई से खोदने पर, हमने पाया कि QStash CRON एक्सप्रेशन का भी समर्थन करता है। इसलिए, हमने क्रॉन जॉब शेड्यूल करने के लिए QStash का उपयोग करने का फैसला किया।

इस लेख में, हम आपको Next.js एप्लिकेशन में QStash और Upstash Redis का उपयोग करके उपयोगकर्ता के टाइमज़ोन में ईमेल शेड्यूल करने की प्रक्रिया के बारे में बताएंगे। आप GitHub पर पूरा सोर्स कोड भी पा सकते हैं।

उपयोगकर्ता के टाइमज़ोन में ईमेल शेड्यूल करने के लिए Next.js एप्लिकेशन बनाना

पूर्वापेक्षाएँ

इस ट्यूटोरियल का पालन करने के लिए, आपको आवश्यकता होगी:

  • एक Upstash खाता
  • एक Node.js विकास वातावरण

प्रोजेक्ट सेट अप करना

शुरू करने के लिए, निम्न कमांड का उपयोग करके एक नया Next.js प्रोजेक्ट बनाएं:

npx create-next-app qstash-email-scheduling

अगला, Upstash के साथ बातचीत करने के लिए निम्न निर्भरताएँ इंस्टॉल करें:

npm install --save @upstash/redis axios

अपने प्रोजेक्ट के रूट में एक नई .env.local फ़ाइल बनाएं और अपने Upstash खाते से निम्नलिखित पर्यावरण चर जोड़ें:

UPSTASH_REDIS_REST_URL= UPSTASH_REDIS_REST_TOKEN= QSTASH_URL= QSTASH_TOKEN= QSATSH_CURRENT_SIGNING_KEY= QSATSH_NEXT_SIGNING_KEY=

समाधान अवलोकन

कोड लागू करने से पहले, आइए समाधान अवलोकन पर एक नज़र डालें। हम तीन Next.js API रूट बनाएंगे:

  • POST /api/schedule-cron - उपयोगकर्ता के टाइमज़ोन में ईमेल क्रॉन जॉब शेड्यूल करने के लिए।
  • POST /api/cancel-schedule - शेड्यूल्ड ईमेल क्रॉन जॉब को रद्द करने के लिए।
  • POST /api/send-email - शेड्यूल्ड क्रॉन जॉब द्वारा ईमेल भेजने के लिए ट्रिगर किया गया।

API रूट के अलावा, हम उपयोगकर्ता का पसंदीदा ईमेल प्राप्त करने का समय एकत्र करने के लिए एक साधारण फॉर्म भी बनाएंगे।

उपयोगकर्ता इंटरफ़ेस बनाना

उपयोगकर्ता इंटरफ़ेस बनाने के लिए, हम निम्न कोड के साथ app/page.tsx पर एक नया पेज बनाएंगे:

"use client"; import { useState } from "react"; import axios from "axios"; export default function Home() { const userId = "tony-stark-11"; const [selectedTime, setSelectedTime] = useState("10:00"); async function createEmailNotificationSchedule() { try { await axios.post( "/api/schedule-cron", { userId, selectedTime, utcOffset: new Date().getTimezoneOffset(), }, { headers: { "Content-Type": "application/json", }, }, ); alert("Email notification scheduled"); } catch (e) { console.log("Client side error", e); alert("Error scheduling email notification"); } } async function cancelEmailNotificationSchedule() { try { await axios.post( "/api/cancel-schedule", { userId, }, { headers: { "Content-Type": "application/json", }, }, ); alert("Email notification schedule cancelled"); } catch (e) { console.log("Client side error", e); alert("Error scheduling email notification"); } } return ( <main className="mx-auto flex min-h-screen max-w-md flex-col justify-center p-24"> <h1 className="mb-4 text-xl font-bold text-neutral-600"> Email Notification for {userId} </h1> Send daily email summary at: <select onChange={(e) => setSelectedTime(e.target.value)} className="mt-4 h-12 w-64 rounded-lg border-2 border-neutral-600 bg-neutral-800 p-2 text-white" > {new Array(24).fill(0).map((_, i) => { const time = i < 10 ? `0${i}:00` : `${i}:00`; return ( <option key={i} value={time}> {time} </option> ); })} </select> <button className="mt-4 rounded bg-green-700 px-4 py-2 text-white" onClick={createEmailNotificationSchedule} > Schedule </button> <button className="mt-4 rounded bg-red-500 px-4 py-2 text-white" onClick={cancelEmailNotificationSchedule} > Cancel Schedule </button> </main> ); }

उपरोक्त कोड उपयोगकर्ताओं के लिए दैनिक ईमेल सारांश प्राप्त करने के लिए अपना पसंदीदा समय निर्धारित करने के लिए एक ड्रॉप-डाउन के साथ एक फॉर्म बनाता है। वे इन सूचनाओं को शेड्यूल या रद्द कर सकते हैं, और एप्लिकेशन HTTP POST अनुरोधों का उपयोग करके सर्वर के साथ संचार करता है। हम अगले अनुभागों में HTTP एंडपॉइंट बनाएंगे।

QStash के साथ टाइमज़ोन-जागरूक शेड्यूलिंग: ईमेल अलर्ट को ठीक तब वितरित करें जब आप चाहते हैं

ईमेल क्रॉन जॉब शेड्यूल करना

QStash के साथ टाइमज़ोन-जागरूक शेड्यूलिंग: ईमेल अलर्ट को ठीक तब वितरित करें जब आप चाहते हैं

आइए POST /api/schedule-cron रूट बनाकर शुरू करें। इस रूट का उपयोग उपयोगकर्ता के टाइमज़ोन में ईमेल क्रॉन जॉब शेड्यूल करने के लिए किया जाएगा। हम क्रॉन जॉब शेड्यूल करने के लिए QStash लाइब्रेरी का उपयोग करेंगे।

import { NextApiRequest, NextApiResponse } from "next"; import { Redis } from "@upstash/redis"; import axios from "axios"; export const QSTASH_CONFIG = { QSTASH_URL: process.env.QSTASH_URL, QSTASH_TOKEN: process.env.QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY: process.env.QSTASH_CURRENT_SIGNING_KEY, }; export const upstash = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL!, token: process.env.UPSTASH_REDIS_REST_TOKEN!, }); // इस एंडपॉइंट को अपने डोमेन से मेल खाने के लिए संपादित करें const SUMMARY_ENDPOINT = "https://<your-domain>/api/send-email"; export default async function scheduleSummary( req: NextApiRequest, res: NextApiResponse, ) { console.log("========SCHEDULE SUMMARY========"); if (req.method !== "POST") { return res.status(400).json({ message: "bad request" }); } const { body } = req; const { userId, selectedTime, utcOffset } = body; const emailScheduleKey = `email-schedule-${userId}`; const scheduleId = await upstash.get(emailScheduleKey); // नया बनाने से पहले मौजूदा शेड्यूल को हटाएं if (scheduleId) { try { await axios.delete( `https://qstash.upstash.io/v1/schedules/${scheduleId}`, { headers: { Authorization: `Bearer ${QSTASH_CONFIG.QSTASH_TOKEN}`, }, }, ); } catch (e) { console.log("Schedule not found in QStash "); } await upstash.del(emailScheduleKey); } const [hour, min] = convertToUTC(selectedTime, utcOffset).split(":"); const selectedCron = `${min} ${hour} * * *`; // नया शेड्यूल बनाएं और संग्रहीत करें try { const { data, status } = await axios.post( `${QSTASH_CONFIG.QSTASH_URL}${SUMMARY_ENDPOINT}`, { userId }, { headers: { "Content-Type": "application/json", Authorization: `Bearer ${QSTASH_CONFIG.QSTASH_TOKEN}`, "Upstash-Cron": selectedCron, }, }, ); console.log({ data, status }); if (data.scheduleId) { await upstash.set(emailScheduleKey, data.scheduleId); } } catch (e) { console.log({ e }); } return res.status(200).json({ message: "success" }); } function convertToUTC(timeString: string, utcOffset: number) { const [hours, minutes] = timeString.split(":").map(Number); const timeInMinutes = hours * 60 + minutes; const utcTimeInMinutes = (timeInMinutes + utcOffset + 1440) % 1440; const utcHours = Math.floor(utcTimeInMinutes / 60); const utcMinutes = utcTimeInMinutes % 60; return `${utcHours.toString().padStart(2, "0")}:${utcMinutes .toString() .padStart(2, "0")}`; }

कोड का मूल scheduleSummary फ़ंक्शन है, जो एक API एंडपॉइंट है। यह आने वाले POST अनुरोधों को संभालता है और निम्नलिखित चरणों को करता है:

  1. अनुरोध विधि को मान्य करता है, यह सुनिश्चित करते हुए कि यह एक POST अनुरोध है।
  2. अनुरोध शरीर से डेटा निकालता है, जिसमें userId, selectedTime, और utcOffset शामिल हैं।
  3. Upstash डेटाबेस में उपयोगकर्ता के ईमेल शेड्यूल के लिए एक कुंजी बनाता है।
  4. उपयोगकर्ता के लिए किसी भी मौजूदा शेड्यूल को पुनः प्राप्त करता है और इसे QStash से हटा देता है।
  5. convertToUTC फ़ंक्शन का उपयोग करके उपयोगकर्ता के चयनित समय को UTC प्रारूप में परिवर्तित करता है जो एक समय स्ट्रिंग और UTC ऑफसेट लेता है, ऑफसेट के लिए लेखांकन करते हुए समय को UTC प्रारूप में परिवर्तित करता है।
  6. QStash की शेड्यूलिंग कार्यक्षमता का उपयोग करके ईमेल सारांश भेजने के लिए एक नया शेड्यूल बनाता है और userId को पेलोड के रूप में जोड़ता है जो /api/send-email एंडपॉइंट प्राप्त करता है।
  7. नवनिर्मित शेड्यूल आईडी को Upstash डेटाबेस में संग्रहीत करता है।

ईमेल सारांश भेजना

POST /api/send-email रूट शेड्यूल्ड क्रॉन जॉब द्वारा ईमेल भेजने के लिए ट्रिगर किया जाएगा। हम अनुरोध के हस्ताक्षर को सत्यापित करने के लिए @upstash/qstash/nextjs लाइब्रेरी का उपयोग करेंगे। यह सुनिश्चित करेगा कि अनुरोध QStash से आ रहा है न कि किसी अन्य स्रोत से।

POST /api/send-email फ़ंक्शन अनुरोध शरीर में userId प्राप्त करता है। आप userId के आधार पर ईमेल तैयार करने और भेजने के लिए एक फ़ंक्शन लागू कर सकते हैं।

import { NextApiRequest, NextApiResponse } from "next"; import { verifySignature } from "@upstash/qstash/nextjs"; async function handler(request: NextApiRequest, res: NextApiResponse) { console.log("==========Project summary handler=========="); if (request.method !== "POST") { return res.status(400).json({ message: "bad request" }); } const { body } = request; const { userId } = body; // ईमेल तैयार करें और भेजें return res.status(200).json({ message: "success" }); } export default verifySignature(handler); export const config = { api: { bodyParser: false, }, };

शेड्यूल्ड ईमेल क्रॉन जॉब रद्द करना

QStash के साथ टाइमज़ोन-जागरूक शेड्यूलिंग: ईमेल अलर्ट को ठीक तब वितरित करें जब आप चाहते हैं

अब, आइए POST /api/cancel-schedule रूट बनाएं। इस रूट का उपयोग शेड्यूल्ड ईमेल क्रॉन जॉब को रद्द करने के लिए किया जाएगा। हम क्रॉन जॉब को रद्द करने के लिए QStash लाइब्रेरी का उपयोग करेंगे।

import { NextApiRequest, NextApiResponse } from "next"; import axios from "axios"; import { Redis } from "@upstash/redis"; export const QSTASH_CONFIG = { QSTASH_URL: process.env.QSTASH_URL, QSTASH_TOKEN: process.env.QSTASH_TOKEN, QSTASH_CURRENT_SIGNING_KEY: process.env.QSTASH_CURRENT_SIGNING_KEY, }; export const upstash = new Redis({ url: process.env.UPSTASH_REDIS_REST_URL!, token: process.env.UPSTASH_REDIS_REST_TOKEN!, }); export default async function scheduleSummary( req: NextApiRequest, res: NextApiResponse ) { console.log("========REMOVE SCHEDULE SUMMARY========"); if (req.method !== "POST") { return res.status(400).json({ message: "bad request" }); } const { body } = req; const { userId } = body; const emailScheduleKey = `email-schedule-${userId}`; const scheduleId = await upstash.get(emailScheduleKey); // नया बनाने से पहले मौजूदा शेड्यूल को हटाएं if (scheduleId) { try { await axios.delete( `https://qstash.upstash.io/v1/schedules/${scheduleId}`, { headers: { Authorization: `Bearer ${QSTASH_CONFIG.QSTASH_TOKEN}`, }, } ); } catch (e) { console.log("Schedule not found in QStash "); } await upstash.del(emailScheduleKey); } return res.status(200).json({ message: "success" }); }

निष्कर्ष

संक्षेप में, हम Upstash Redis और QStash का उपयोग करके उपयोगकर्ता के टाइमज़ोन में ईमेल शेड्यूल करने में सक्षम थे। हमने इसे उपयोगकर्ता के टाइमज़ोन को अपने डेटाबेस में संग्रहीत किए बिना हासिल किया। हम उपयोगकर्ताओं को किसी भी समय शेड्यूल्ड ईमेल सूचनाओं को रद्द करने की क्षमता देने में भी सक्षम थे।

यदि आप अपने उत्पाद के लिए दस्तावेज़ीकरण बनाए रख रहे हैं, तो आपको docsly देखना चाहिए। यह तकनीकी दस्तावेज़ीकरण के लिए तैयार एक फीडबैक टूल है जो आपको अपने उपयोगकर्ताओं से फीडबैक एकत्र करने और उन्हें कार्रवाई योग्य अंतर्दृष्टि में बदलने में मदद करता है।

  1. रूबी के साथ व्यावहारिक ग्राफ थ्योरी में महारत रूबी के साथ व्यावहारिक ग्राफ थ्योरी में महारत

    यह व्यावहारिक कंप्यूटर विज्ञान श्रृंखला में अगली किस्त है, जहां आप सीखेंगे कि क्लासिक कंप्यूटर विज्ञान अवधारणाओं को रूबी का उपयोग करके वास्तविक समस्याओं को हल करने के लिए कैसे लागू किया जाए। आज हम ग्राफ थ्योरी के बारे में बात करने जा रहे हैं। आपने बाइनरी ट्री के बारे में सुना होगा, वे ऐसे दिखते हैं:

  1. HTML Window innerHeight प्रॉपर्टी HTML Window innerHeight प्रॉपर्टी

    HTML Window innerHeight प्रॉपर्टी एक HTML दस्तावेज़ में विंडो के कंटेंट एरिया की ऊंचाई लौटाती है।सिंटैक्सनिम्नलिखित सिंटैक्स है:window.innerHeightआइए HTML Window innerHeight प्रॉपर्टी का एक उदाहरण देखें:उदाहरण<!DOCTYPE html> <html> <style>    body {       c

  1. एसिम्प्टोटिक कॉम्प्लेक्सिटी (आशय जटिलता) एसिम्प्टोटिक कॉम्प्लेक्सिटी (आशय जटिलता)

    एसिम्प्टोटिक एनालिसिसएसिम्प्टोटिक विश्लेषण का उपयोग करके, हम इनपुट आकार के आधार पर एल्गोरिदम के प्रदर्शन के बारे में एक विचार प्राप्त कर सकते हैं। हमें सटीक रनिंग टाइम की गणना नहीं करनी चाहिए, बल्कि रनिंग टाइम और इनपुट आकार के बीच संबंध ढूंढना चाहिए। हमें रनिंग टाइम का पालन करना चाहिए जब इनपुट का आक