इस गाइड में आप सीखेंगे कि कैसे आप Gmail API और Google Pub/Sub का उपयोग करके अपने PHP सर्वर पर रियल-टाइम ईमेल नोटिफिकेशन सेट कर सकते हैं। जैसे ही आपके Gmail पर कोई नई मेल आती है, आपका सिस्टम उसे तुरंत पढ़कर OTP वेरिफाई कर सकता है।
🎯 यह सिस्टम क्या करता है?
-
✅ जैसे ही आपके Gmail पर कोई नई मेल आती है, उसकी सूचना आपके सर्वर को तुरंत (Real-time) मिल जाती है।
-
✅ आपको बार-बार Cron Job या Polling नहीं करनी पड़ती।
-
✅ OTP (4-6 अंक) को ऑटोमैटिक रूप से निकालकर लॉग या वेरिफाई किया जा सकता है।
-
✅ यह सिस्टम 7×24 चलता है और Cron Job से अपने आप Renew होता रहता है।
📋 पूर्व-आवश्यकताएँ (Prerequisites)
इस सेटअप को शुरू करने से पहले आपके पास ये होने चाहिए:
| # | चीज़ | विवरण |
|---|---|---|
| 1 | Google Cloud Account | एक Gmail अकाउंट जिससे आप Google Cloud Console में लॉगिन कर सकें। |
| 2 | PHP Server | एक वेब सर्वर (Shared/VPS) जहाँ PHP (≥7.4) चलता हो और composer उपलब्ध हो। |
| 3 | Domain with HTTPS | आपकी वेबसाइट पर SSL/HTTPS सक्षम होना चाहिए (Pub/Sub HTTP पर काम नहीं करता)। |
| 4 | Gmail Account | वह Gmail ID जिस पर OTP आता है और जिसे आप मॉनिटर करना चाहते हैं। |
🏗️ आर्किटेक्चर (कैसे काम करता है)
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ │ │ │ │ │ │ │
│ Gmail │─────▶│ Pub/Sub │─────▶│ Webhook │─────▶│ OTP Log │
│ Inbox │ │ Topic │ │ (PHP) │ │ / Verify │
│ │ │ │ │ │ │ │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│ │ │ │
│ │ │ │
▼ ▼ ▼ ▼
New Email Push Notification process_latest_email email_content.log
🚀 चरण 1: Google Cloud Console (GCP) सेटअप
⚠️ ध्यान दें: ये सेटअप एक बार करना है। इसके बाद इसे दोबारा नहीं करना पड़ता।
1.1 API Enable करें
-
Google Cloud Console में लॉगिन करें।
-
एक नया Project बनाएँ (या मौजूदा Project चुनें)।
-
API & Services > Library पर जाएँ।
-
इन दोनों APIs को Enable करें:
-
✅ Gmail API
-
✅ Cloud Pub/Sub API
-
1.2 OAuth 2.0 Client ID बनाएँ
-
APIs & Services > Credentials पर जाएँ।
-
+ CREATE CREDENTIALS > OAuth client ID चुनें।
-
Application type में Web application चुनें।
-
Name डालें (जैसे
Gmail OTP Watcher)। -
Authorized redirect URIs में + ADD URI करके यह URL डालें:
https://yourdomain.com/project/watch_gmail.php
(अपने असली डोमेन और फोल्डर पाथ से बदलें)
-
CREATE बटन दबाएँ।
-
Download JSON बटन से JSON फाइल डाउनलोड करें और उसका नाम
client_secret.jsonरखें – इसे बाद में सर्वर पर अपलोड करना है।
1.3 Pub/Sub Topic बनाएँ
-
Pub/Sub > Topics पर जाएँ।
-
Create Topic पर क्लिक करें।
-
Topic ID डालें:
gmail-otp-topic -
बाकी सभी सेटिंग्स डिफॉल्ट पर रखें और Create करें।
1.4 ⚠️ सबसे महत्वपूर्ण: Permission देना
यह कदम भूलना सबसे बड़ी गलती है! अगर यह नहीं किया तो
users.watch()कभी काम नहीं करेगा।
-
Pub/Sub > Topics पर जाएँ।
-
अपने
gmail-otp-topicके आगे ⋮ (3 dots) > View Permissions पर क्लिक करें। -
Add Principal पर क्लिक करें।
-
New Principals में डालें:
-
Role में
Pub/Sub Publisherचुनें। -
Save करें।
1.5 Push Subscription बनाएँ
-
Pub/Sub > Subscriptions पर जाएँ।
-
Create Subscription पर क्लिक करें।
-
Subscription ID डालें:
gmail-otp-subscription -
Topic में
gmail-otp-topicचुनें। -
Delivery Type में Push चुनें।
-
Endpoint URL डालें:
https://yourdomain.com/project/gmail_webhook.php
-
Retry Policy में “Retry after exponential backoff delay” चुनें (Minimum: 10s, Maximum: 600s)।
-
बाकी सेटिंग्स डिफॉल्ट पर रखें और Create करें।
📂 चरण 2: सर्वर पर PHP फाइलें सेट करें
अब आपको अपने सर्वर पर एक फोल्डर (जैसे project/) बनाकर उसमें ये फाइलें रखनी हैं।
2.1 Composer Install करें
cd /path/to/your/project composer require google/apiclient
2.2 client_secret.json अपलोड करें
Google Cloud से डाउनलोड की गई JSON फाइल को इसी फोल्डर में client_secret.json नाम से अपलोड करें।
2.3 watch_gmail.php – Watch Start / Renew
<?php // watch_gmail.php - OAuth 2.0 Web Application require_once 'vendor/autoload.php'; use Google_Client; use Google_Service_Gmail; use Google_Service_Gmail_WatchRequest; // ============ कॉन्फ़िगरेशन ============ define('MY_EMAIL', '[email protected]'); // अपना Gmail ID define('PROJECT_ID', 'your-project-id'); // Google Cloud Project ID define('TOPIC_NAME', 'gmail-otp-topic'); // Pub/Sub Topic Name define('CLIENT_SECRET_FILE', 'client_secret.json'); define('TOKEN_FILE', 'token.json'); // ======================================== function getClient() { $client = new Google_Client(); $client->setAuthConfig(CLIENT_SECRET_FILE); $client->setScopes(['https://mail.google.com/']); $client->setAccessType('offline'); $client->setPrompt('consent'); return $client; } // 1. OAuth Callback - Code से Token बनाएँ if (isset($_GET['code'])) { $code = $_GET['code']; $client = getClient(); try { $accessToken = $client->fetchAccessTokenWithAuthCode($code); if (isset($accessToken['error'])) { throw new Exception($accessToken['error_description'] ?? 'Unknown error'); } file_put_contents(TOKEN_FILE, json_encode($accessToken)); echo "✅ Authorization Successful! Token saved.<br>"; echo "🔄 अब आप watch_gmail.php को बिना ?code= के Run करें।"; exit; } catch (Exception $e) { die("❌ Error: " . $e->getMessage()); } } // 2. Token मौजूद है - Watch शुरू करें if (file_exists(TOKEN_FILE)) { $client = getClient(); $accessToken = json_decode(file_get_contents(TOKEN_FILE), true); $client->setAccessToken($accessToken); // Token Expire हो तो Refresh if ($client->isAccessTokenExpired()) { $refreshToken = $client->getRefreshToken(); if ($refreshToken) { $newToken = $client->fetchAccessTokenWithRefreshToken($refreshToken); file_put_contents(TOKEN_FILE, json_encode($client->getAccessToken())); } else { unlink(TOKEN_FILE); header('Location: ' . filter_var($client->createAuthUrl(), FILTER_SANITIZE_URL)); exit; } } $service = new Google_Service_Gmail($client); try { $watch = new Google_Service_Gmail_WatchRequest(); $watch->setTopicName("projects/" . PROJECT_ID . "/topics/" . TOPIC_NAME); $response = $service->users->watch(MY_EMAIL, $watch); $expiry = $response->getExpiration() / 1000; echo "\n✅ Watch Setup Successful!\n"; echo "📅 Expires at: " . date('Y-m-d H:i:s', $expiry) . "\n"; echo "🔄 इसे हर 7 दिन में Renew करें (Cron Job).\n"; } catch (Exception $e) { echo "\n❌ Error: " . $e->getMessage() . "\n"; echo "💡 अगर Error आए, तो token.json डिलीट करें और watch_gmail.php को बिना ?code= के Run करें।\n"; } exit; } // 3. Token नहीं है - Google Login पर Redirect $client = getClient(); $authUrl = $client->createAuthUrl(); header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL)); exit; ?>
2.4 gmail_webhook.php – Pub/Sub Webhook Receiver
<?php // gmail_webhook.php - Pub/Sub से POST पढ़े और Log करे $logFile = __DIR__ . '/pubsub_callback_log.txt'; $rawInput = file_get_contents('php://input'); $headers = getallheaders(); $logEntry = [ 'timestamp' => date('Y-m-d H:i:s'), 'remote_ip' => $_SERVER['REMOTE_ADDR'] ?? 'unknown', 'headers' => $headers, 'raw_input' => $rawInput, 'decoded' => json_decode($rawInput, true) ]; $logLine = json_encode($logEntry, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n\n---\n\n"; file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX); // OTP Processing Trigger $data = json_decode($rawInput, true); if (isset($data['message']['data'])) { $messageData = base64_decode($data['message']['data']); $gmailEvent = json_decode($messageData, true); if (isset($gmailEvent['historyId'])) { file_put_contents( __DIR__ . '/otp_trigger.log', date('Y-m-d H:i:s') . " - historyId: " . $gmailEvent['historyId'] . PHP_EOL, FILE_APPEND ); // Background में process_latest_email.php चलाएँ shell_exec("php " . __DIR__ . "/process_latest_email.php >> /dev/null 2>&1 &"); } } http_response_code(200); echo 'OK'; ?>
2.5 process_latest_email.php – Latest Email Content Reader
<?php // process_latest_email.php - नवीनतम मेल का कंटेंट लॉग करें require_once 'vendor/autoload.php'; use Google_Client; use Google_Service_Gmail; define('MY_EMAIL', '[email protected]'); define('TOKEN_FILE', 'token.json'); define('CLIENT_SECRET_FILE', 'client_secret.json'); define('LOG_FILE', __DIR__ . '/email_content.log'); function getGmailService() { $client = new Google_Client(); $client->setAuthConfig(CLIENT_SECRET_FILE); $client->setScopes(['https://mail.google.com/']); $client->setAccessType('offline'); if (file_exists(TOKEN_FILE)) { $accessToken = json_decode(file_get_contents(TOKEN_FILE), true); $client->setAccessToken($accessToken); } if ($client->isAccessTokenExpired()) { $refreshToken = $client->getRefreshToken(); if ($refreshToken) { $newToken = $client->fetchAccessTokenWithRefreshToken($refreshToken); file_put_contents(TOKEN_FILE, json_encode($client->getAccessToken())); } else { die("❌ Refresh Token नहीं मिला।\n"); } } return new Google_Service_Gmail($client); } function htmlToPlainText($html) { $text = strip_tags($html); $text = html_entity_decode($text, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $text = preg_replace('/\s+/', ' ', $text); return trim($text); } function getEmailBody($payload) { $plain = ''; $html = ''; if ($payload->getMimeType() == 'text/plain') { $data = $payload->getBody()->getData(); if ($data) $plain = base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); } elseif ($payload->getMimeType() == 'text/html') { $data = $payload->getBody()->getData(); if ($data) $html = base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); } elseif (strpos($payload->getMimeType(), 'multipart/') === 0) { foreach ($payload->getParts() as $part) { $result = getEmailBody($part); if ($result['plain']) $plain = $result['plain']; if ($result['html']) $html = $result['html']; } } return ['plain' => $plain, 'html' => $html]; } $service = getGmailService(); try { $optParams = ['maxResults' => 1, 'q' => 'in:inbox']; $messages = $service->users_messages->listUsersMessages('me', $optParams); if (count($messages->getMessages()) == 0) { file_put_contents(LOG_FILE, date('Y-m-d H:i:s') . " - No new emails.\n", FILE_APPEND); echo "📭 Inbox empty.\n"; exit; } $msgId = $messages->getMessages()[0]->getId(); $message = $service->users_messages->get('me', $msgId, ['format' => 'full']); $subject = $from = ''; foreach ($message->getPayload()->getHeaders() as $header) { if ($header->getName() == 'Subject') $subject = $header->getValue(); if ($header->getName() == 'From') $from = $header->getValue(); } $body = getEmailBody($message->getPayload()); $plainText = $body['plain'] ?: htmlToPlainText($body['html']); $logContent = "========================================\n"; $logContent .= "📅 Time: " . date('Y-m-d H:i:s') . "\n"; $logContent .= "📩 From: " . $from . "\n"; $logContent .= "📌 Subject: " . $subject . "\n"; $logContent .= "📝 Body:\n" . $plainText . "\n"; $logContent .= "========================================\n\n"; file_put_contents(LOG_FILE, $logContent, FILE_APPEND); echo "✅ Email logged.\n"; } catch (Exception $e) { file_put_contents(LOG_FILE, date('Y-m-d H:i:s') . " - Error: " . $e->getMessage() . "\n", FILE_APPEND); echo "❌ Error: " . $e->getMessage() . "\n"; } ?>
🔓 चरण 3: पहली बार One-Time Activation
⚠️ यह कदम केवल पहली बार करना है। इसके बाद सब कुछ ऑटोमैटिक हो जाएगा।
3.1 ब्राउज़र से Authorization करें
-
अपनी ब्राउज़र में यह URL खोलें:
https://yourdomain.com/project/watch_gmail.php
-
Google Login पेज पर अपने Gmail ID से लॉगिन करें।
-
सभी Permissions को Allow करें।
-
✅ “Authorization Successful! Token saved.” का मैसेज आना चाहिए।
इससे आपके सर्वर पर
token.jsonफाइल बन जाएगी, जिसमें Refresh Token सेव है।
3.2 SSH Terminal से Watch Start करें
php /path/to/your/project/watch_gmail.php
✅ आउटपुट कुछ इस तरह आना चाहिए:
✅ Watch Setup Successful! 📅 Expires at: 2026-09-13 14:02:40 🔄 इसे हर 7 दिन में Renew करें (Cron Job).
🗓️ चरण 4: Auto-Renew के लिए Cron Job
Gmail API Watch 7 दिन में Expire हो जाती है। इसे अपने आप Renew करने के लिए यह Cron Job लगाएँ:
crontab -e
यह लाइन डालें:
0 6 * * * php /path/to/your/project/watch_gmail.php >> /var/log/gmail_watch_renew.log 2>&1
-
यह हर दिन सुबह 6 बजे Watch Renew करेगा।
-
Log फ़ाइल:
/var/log/gmail_watch_renew.log– इसे चेक करके Confirm करें।
🧪 चरण 5: फाइनल टेस्ट
-
अपने Gmail (
[email protected]) पर एक टेस्ट मेल भेजें। -
1-2 मिनट बाद अपने सर्वर के
project/फोल्डर में ये फाइलें चेक करें:
| फाइल | क्या चेक करें |
|---|---|
otp_trigger.log |
नई एंट्री आई – historyId लिखा होना चाहिए |
email_content.log |
मेल का From, Subject, और Body साफ-साफ दिखना चाहिए |
pubsub_callback_log.txt |
Google से आई पूरी POST डिटेल |
अगर ये तीनों फाइलें अपडेट हुई हैं, तो आपका सिस्टम 100% काम कर रहा है! 🎉
📂 फाइलें कहाँ रखें (फोल्डर स्ट्रक्चर)
/public_html/project/ ├── client_secret.json # GCP से Download की गई JSON ├── token.json # Auto-generated (कभी Delete न करें) ├── watch_gmail.php # Cron वाली फाइल ├── gmail_webhook.php # Pub/Sub Endpoint ├── process_latest_email.php # Email Reader ├── vendor/ # Composer Libraries ├── email_content.log # मेल कंटेंट (Auto-generated) ├── otp_trigger.log # historyId Log (Auto-generated) └── pubsub_callback_log.txt # Pub/Sub POST Log (Auto-generated)
🆘 समस्या और समाधान (Troubleshooting)
| समस्या | तुरंत समाधान |
|---|---|
| Webhook पर कुछ नहीं आ रहा | 1. watch_gmail.php को SSH पर Run करें → Renew हो जाएगी।2. gmail_webhook.php को ब्राउज़र में खोलें → सिर्फ “OK” आना चाहिए। |
| 401 Unauthenticated Error | token.json Delete करें → Browser से watch_gmail.php खोलें → दोबारा Allow करें → नया token.json बनेगा। |
email_content.log खाली है |
process_latest_email.php को SSH पर Run करें → PHP Error देखें (जैसे vendor/autoload.php न मिलना)। |
| Cron Job काम नहीं कर रहा | cat /var/log/gmail_watch_renew.log देखें – उसमें Error लिखा होगा। |
| Permission Denied | [email protected] को Pub/Sub Publisher Role देना न भूलें। |
✅ निष्कर्ष
इस गाइड को Follow करने के बाद:
-
🔹 आपका सिस्टम हर नई मेल को रियल-टाइम में पढ़ेगा।
-
🔹 OTP (4-6 अंक) को ऑटोमैटिक रूप से Extract करेगा।
-
🔹 Cron Job से Watch हर दिन Renew होती रहेगी।
-
🔹 आपको कभी मैन्युअली कुछ नहीं करना पड़ेगा – बस एक बार Set करें और भूल जाएँ।