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

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

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

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

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

<पी> हम पहले से ही अपस्टैश को रेडिस स्टोर के रूप में उपयोग कर रहे थे, और हमने पाया कि QStash शेड्यूल सुविधा का भी समर्थन करता है। थोड़ा और गहराई से जानने पर, हमने पाया कि QStash CRON अभिव्यक्तियों का भी समर्थन करता है। इसलिए, हमने क्रॉन नौकरियों को शेड्यूल करने के लिए QStash का उपयोग करने का निर्णय लिया।

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

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

आवश्यकताएँ

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

  • एक अपस्टैश खाता
  • एक Node.js विकास परिवेश

प्रोजेक्ट सेट करें

<पी> आरंभ करने के लिए, निम्नलिखित कमांड का उपयोग करके एक नया Next.js प्रोजेक्ट बनाएं:

npx create-next-app qstash-email-scheduling
<पी> इसके बाद, अपस्टैश के साथ इंटरैक्ट करने के लिए निम्नलिखित निर्भरताएँ स्थापित करें:

npm install --save @upstash/redis axios
<पी> एक नया .env.local बनाएं अपने प्रोजेक्ट के रूट में फ़ाइल करें और अपने अपस्टैश खाते से निम्नलिखित पर्यावरण चर जोड़ें:

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 - ईमेल भेजने के लिए निर्धारित क्रॉन जॉब द्वारा ट्रिगर किया गया।
<पी> एपीआई मार्गों के अलावा, हम ईमेल प्राप्त करने के लिए उपयोगकर्ता का पसंदीदा समय एकत्र करने के लिए एक सरल फॉर्म भी बनाएंगे।

यूजर इंटरफ़ेस बनाएं

<पी> उपयोगकर्ता इंटरफ़ेस बनाने के लिए, हम 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!,
});
 
// Edit this endpoint to match your domain
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);
 
 // remove existing schedule before creating a new one
 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} * * *`;
 
 // create and store new schedule
 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 है फ़ंक्शन, जो एक एपीआई समापन बिंदु है। यह आने वाले POST अनुरोधों को संभालता है और निम्नलिखित चरण निष्पादित करता है:

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

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

<पी> 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;
 
 // prepare and send email
 
 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);
 
 // remove existing schedule before creating a new one
 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" });
}

निष्कर्ष

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

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


  1. जावास्क्रिप्ट स्क्रॉल डाउन के लिए लूप को कैसे रोकें? जावास्क्रिप्ट स्क्रॉल डाउन के लिए लूप को कैसे रोकें?

    लूप को रोकने के लिए, जावास्क्रिप्ट में clearInterval() का उपयोग करें। उदाहरण निम्नलिखित कोड है - <!DOCTYPE html> <html lang="en"> <head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width,

  1. एंड्रॉइड में आंतरिक भंडारण में एक txt फ़ाइल कैसे बनाएं? एंड्रॉइड में आंतरिक भंडारण में एक txt फ़ाइल कैसे बनाएं?

    यह उदाहरण दर्शाता है कि एंड्रॉइड में आंतरिक भंडारण में एक txt फ़ाइल कैसे बनाई जाती है। चरण 1 - एंड्रॉइड स्टूडियो में एक नया प्रोजेक्ट बनाएं, फाइल ⇒ न्यू प्रोजेक्ट पर जाएं और एक नया प्रोजेक्ट बनाने के लिए सभी आवश्यक विवरण भरें। चरण 2 - निम्न कोड को res/layout/activity_main.xml में जोड़ें। उपरोक

  1. सी++ का उपयोग करके एन-आरी ट्री को पार करने के तरीकों की संख्या ज्ञात करें सी++ का उपयोग करके एन-आरी ट्री को पार करने के तरीकों की संख्या ज्ञात करें

    एक एन-आरी पेड़ को देखते हुए और हमें इस पेड़ को पार करने के कुल तरीकों को खोजने का काम सौंपा गया है, उदाहरण के लिए - उपरोक्त पेड़ के लिए, हमारा उत्पादन 192 होगा। इस समस्या के लिए, हमें कॉम्बिनेटरिक्स के बारे में कुछ ज्ञान होना चाहिए। अब इस समस्या में, हमें बस हर पथ के लिए सभी संभावित संयोजनों की