READ FULL STORY →
सब फीचर्स का पूरा अपडेटेड कोड एक फाइल में दे सकता हूँ। बिल्कुल, मैं आपको एक संपूर्ण Python स्क्रिप्ट दे रहा हूँ जिसमें ये सभी फीचर्स शामिल हैं:
मल्टीपल RSS फीड्स – एक साथ कई स्रोतों से खबरें लाना
फोटो के साथ पोस्ट – खबरों के साथ इमेज भेजना
ऑटोमैटिक लैंग्वेज ट्रांसलेशन – खबरों को हिंदी या किसी भी भाषा में अनुवाद करना
टॉपिक के हिसाब से फ़िल्टर – सिर्फ चुनिंदा विषयों की खबरें भेजना
टाइमटेबल सेट करना – निश्चित समय पर खबरें भेजना
यूज़र सब्सक्रिप्शन – यूज़र खुद चुन सकते हैं कि उन्हें खबरें चाहिए या नहीं, और किन टॉपिक्स में दिलचस्पी है
मैं यह कोड आपको नीचे दे रहा हूँ। कृपया ध्यान दें कि इसे चलाने के लिए आपको कुछ Python लाइब्रेरी इंस्टॉल करनी होंगी (python-telegram-bot, feedparser, googletrans, beautifulsoup4, requests, schedule आदि)। साथ ही, आपको अपने बॉट के टोकन, चैनल ID, RSS फीड URLs आदि को Environment Variables में सेट करना होगा (Railway या किसी अन्य होस्टिंग पर)।
यहाँ पूरा कोड है:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
न्यूज़वेव एडवांस्ड टेलीग्राम बॉट
फीचर्स:
- मल्टीपल RSS फीड्स
- फोटो सपोर्ट
- ऑटोमैटिक ट्रांसलेशन (हिंदी या अन्य भाषा)
- टॉपिक-आधारित फ़िल्टरिंग
- टाइमटेबल शेड्यूलिंग
- यूज़र सब्सक्रिप्शन
"""
import feedparser
import time
import sqlite3
import logging
import hashlib
import html
import re
import os
import requests
import schedule
from datetime import datetime
from telegram import Bot, Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, MessageHandler, Filters, CallbackContext
from telegram.error import TelegramError
from googletrans import Translator
from bs4 import BeautifulSoup
# ============================================
# कॉन्फ़िगरेशन - Environment Variables से लें
# ============================================
BOT_TOKEN = os.environ.get("BOT_TOKEN")
CHANNEL_ID = os.environ.get("CHANNEL_ID") # मुख्य चैनल (ऑप्शनल)
# मल्टीपल RSS फीड्स (कॉमा से अलग)
RSS_FEEDS = os.environ.get("RSS_FEEDS", "https://newswaveblog24.blogspot.com/feeds/posts/default").split(',')
# ट्रांसलेशन सेटिंग्स
ENABLE_TRANSLATION = os.environ.get("ENABLE_TRANSLATION", "True").lower() == "true"
TARGET_LANGUAGE = os.environ.get("TARGET_LANGUAGE", "hi") # hi = हिंदी
# फोटो सेटिंग्स
SEND_WITH_PHOTO = os.environ.get("SEND_WITH_PHOTO", "True").lower() == "true"
# फ़िल्टरिंग सेटिंग्स
FILTER_BY_TOPIC = os.environ.get("FILTER_BY_TOPIC", "False").lower() == "true"
ALLOWED_TOPICS = [t.strip().lower() for t in os.environ.get("ALLOWED_TOPICS", "").split(',') if t.strip()]
# टाइमटेबल सेटिंग्स (कॉमा से अलग समय, जैसे "08:00,14:00,19:00")
SCHEDULE_TIMES = [t.strip() for t in os.environ.get("SCHEDULE_TIMES", "08:00,14:00,19:00").split(',') if t.strip()]
# यूज़र सब्सक्रिप्शन चालू करें?
ENABLE_SUBSCRIPTIONS = os.environ.get("ENABLE_SUBSCRIPTIONS", "True").lower() == "true"
# अन्य सेटिंग्स
CHECK_INTERVAL = int(os.environ.get("CHECK_INTERVAL", 15)) # पुराने बैकअप के लिए (शेड्यूलर न हो तो)
MAX_POSTS_PER_RUN = int(os.environ.get("MAX_POSTS_PER_RUN", 5))
# ============================================
# लॉगिंग सेटअप
# ============================================
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('bot.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# ============================================
# ट्रांसलेटर
# ============================================
translator = Translator()
def translate_text(text, dest_lang=TARGET_LANGUAGE):
if not text or not ENABLE_TRANSLATION:
return text
try:
if len(text) > 5000:
text = text[:5000]
translated = translator.translate(text, dest=dest_lang)
return translated.text
except Exception as e:
logger.error(f"❌ ट्रांसलेशन एरर: {e}")
return text
# ============================================
# डेटाबेस सेटअप
# ============================================
def setup_database():
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
# भेजे गए पोस्ट की टेबल
c.execute('''
CREATE TABLE IF NOT EXISTS sent_posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_hash TEXT UNIQUE,
title TEXT,
link TEXT,
published TEXT,
source_feed TEXT,
sent_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# यूज़र सब्सक्रिप्शन टेबल
c.execute('''
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
chat_id INTEGER,
username TEXT,
first_name TEXT,
subscribed BOOLEAN DEFAULT 1,
topics TEXT, -- कॉमा से अलग टॉपिक, NULL का मतलब सब
subscribed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_active TIMESTAMP
)
''')
conn.commit()
conn.close()
logger.info("✅ डेटाबेस सेटअप पूरा")
def is_post_sent(post_hash):
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("SELECT id FROM sent_posts WHERE post_hash = ?", (post_hash,))
result = c.fetchone()
conn.close()
return result is not None
def mark_post_sent(post_hash, title, link, published, source_feed):
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
try:
c.execute(
"INSERT INTO sent_posts (post_hash, title, link, published, source_feed) VALUES (?, ?, ?, ?, ?)",
(post_hash, title, link, published, source_feed)
)
conn.commit()
except sqlite3.IntegrityError:
pass
finally:
conn.close()
def save_user(update: Update):
user = update.effective_user
chat_id = update.effective_chat.id
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute('''
INSERT OR REPLACE INTO users (user_id, chat_id, username, first_name, last_active)
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
''', (user.id, chat_id, user.username, user.first_name))
conn.commit()
conn.close()
def get_subscribed_users():
"""सब्सक्राइब्ड यूज़र्स की लिस्ट (chat_id, topics) लौटाता है"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("SELECT chat_id, topics FROM users WHERE subscribed = 1")
users = c.fetchall()
conn.close()
return users
def update_user_subscription(user_id, subscribed):
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("UPDATE users SET subscribed = ? WHERE user_id = ?", (1 if subscribed else 0, user_id))
conn.commit()
conn.close()
def update_user_topics(user_id, topics):
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("UPDATE users SET topics = ? WHERE user_id = ?", (topics, user_id))
conn.commit()
conn.close()
# ============================================
# इमेज एक्सट्रैक्ट और डाउनलोड
# ============================================
def extract_first_image(entry):
"""RSS एंट्री से पहली इमेज ढूंढ़ें"""
if 'media_content' in entry and entry.media_content:
for media in entry.media_content:
if 'url' in media:
return media['url']
if 'media_thumbnail' in entry and entry.media_thumbnail:
return entry.media_thumbnail[0]['url']
if 'enclosures' in entry:
for enc in entry.enclosures:
if enc.get('type', '').startswith('image/'):
return enc.get('href', '')
content = ''
if 'summary' in entry:
content = entry.summary
elif 'description' in entry:
content = entry.description
elif 'content' in entry and entry.content:
content = entry.content[0].value
if content:
soup = BeautifulSoup(content, 'html.parser')
img = soup.find('img')
if img and img.get('src'):
return img['src']
return None
def download_image(url):
try:
headers = {'User-Agent': 'Mozilla/5.0'}
resp = requests.get(url, headers=headers, timeout=10)
if resp.status_code == 200:
return resp.content
except Exception as e:
logger.error(f"❌ इमेज डाउनलोड एरर: {e}")
return None
# ============================================
# टॉपिक एक्सट्रैक्शन और फ़िल्टरिंग
# ============================================
def extract_topics(entry):
topics = []
if 'tags' in entry:
for tag in entry.tags:
if 'term' in tag:
topics.append(tag['term'].lower())
if 'category' in entry:
if isinstance(entry.category, list):
topics.extend([c.lower() for c in entry.category])
else:
topics.append(entry.category.lower())
return topics
def should_send_post(entry):
if not FILTER_BY_TOPIC or not ALLOWED_TOPICS:
return True
post_topics = extract_topics(entry)
for t in post_topics:
if t in ALLOWED_TOPICS:
return True
return False
# ============================================
# मैसेज फॉर्मेटिंग
# ============================================
def clean_html(text):
if not text:
return ""
text = html.unescape(text)
text = re.sub(r'<[^>]+>', '', text)
return text.strip()
def create_message(entry, source_feed_name=""):
title = clean_html(entry.get('title', 'कोई शीर्षक नहीं'))
translated_title = translate_text(title)
desc = ''
if 'summary' in entry:
desc = clean_html(entry.summary)
elif 'description' in entry:
desc = clean_html(entry.description)
elif 'content' in entry and entry.content:
desc = clean_html(entry.content[0].value)
translated_desc = translate_text(desc)
words = translated_desc.split()
if len(words) > 300:
translated_desc = ' '.join(words[:300]) + "..."
published = entry.get('published', '')
if published:
try:
dt = datetime.strptime(published, '%a, %d %b %Y %H:%M:%S %Z')
published = dt.strftime('%d %B %Y, %I:%M %p')
except:
pass
link = entry.get('link', '')
source_text = f"📡 स्रोत: {source_feed_name}\n" if source_feed_name else ""
message = f"📰 *{translated_title}*\n\n{source_text}"
if published:
message += f"🕒 {published}\n\n"
if translated_desc:
message += f"📝 {translated_desc}\n\n"
message += f"🔗 [पूरा पढ़ें]({link})"
if len(message) > 4000:
message = message[:4000] + "...\n\n" + f"[पूरा पढ़ें]({link})"
return message
# ============================================
# RSS फीड चेक करना और पोस्ट भेजना
# ============================================
def check_rss_feeds(context: CallbackContext = None):
"""सभी RSS फीड्स चेक करें और नई पोस्ट भेजें"""
logger.info(f"🔍 {len(RSS_FEEDS)} RSS फीड्स चेक कर रहा हूं...")
bot = context.bot if context else Bot(token=BOT_TOKEN)
total_new = 0
for feed_url in RSS_FEEDS:
feed_url = feed_url.strip()
if not feed_url:
continue
try:
feed = feedparser.parse(feed_url)
feed_title = feed.feed.get('title', 'ब्लॉग')
new_in_feed = 0
for entry in feed.entries[:MAX_POSTS_PER_RUN]:
post_hash = hashlib.md5(f"{entry.get('link','')}{entry.get('title','')}".encode()).hexdigest()
if is_post_sent(post_hash):
continue
if not should_send_post(entry):
logger.info(f"⏭️ टॉपिक फ़िल्टर: {entry.get('title','')[:50]}... skipped")
continue
message = create_message(entry, feed_title)
image_url = extract_first_image(entry)
image_data = download_image(image_url) if (SEND_WITH_PHOTO and image_url) else None
# मुख्य चैनल पर भेजें (अगर CHANNEL_ID दिया है)
if CHANNEL_ID:
try:
if image_data:
bot.send_photo(chat_id=CHANNEL_ID, photo=image_data, caption=message, parse_mode='Markdown')
else:
bot.send_message(chat_id=CHANNEL_ID, text=message, parse_mode='Markdown')
except Exception as e:
logger.error(f"❌ चैनल को भेजने में एरर: {e}")
# सब्सक्राइब्ड यूज़र्स को भेजें
if ENABLE_SUBSCRIPTIONS:
users = get_subscribed_users()
for chat_id, user_topics_str in users:
# यूज़र के टॉपिक फ़िल्टर (अगर उसने कुछ चुना है)
if user_topics_str and user_topics_str != 'None':
user_topics = [t.strip().lower() for t in user_topics_str.split(',')]
post_topics = extract_topics(entry)
if not any(t in user_topics for t in post_topics):
continue # यूज़र को यह टॉपिक नहीं चाहिए
try:
if image_data:
bot.send_photo(chat_id=chat_id, photo=image_data, caption=message, parse_mode='Markdown')
else:
bot.send_message(chat_id=chat_id, text=message, parse_mode='Markdown')
except Exception as e:
logger.error(f"❌ यूज़र {chat_id} को भेजने में एरर: {e}")
mark_post_sent(post_hash, entry.get('title',''), entry.get('link',''), entry.get('published',''), feed_url)
new_in_feed += 1
total_new += 1
time.sleep(1) # रेट लिमिट से बचने के लिए
logger.info(f"📊 {feed_title}: {new_in_feed} नई पोस्ट")
except Exception as e:
logger.error(f"❌ RSS एरर {feed_url}: {e}")
logger.info(f"✅ कुल {total_new} नई पोस्ट भेजीं")
# ============================================
# टेलीग्राम कमांड हैंडलर
# ============================================
def start(update: Update, context: CallbackContext):
save_user(update)
update.message.reply_text(
"नमस्ते! 🙏\n"
"मैं न्यूज़वेव बॉट हूं। यहां आपको ताज़ा खबरें मिलेंगी।\n\n"
"उपलब्ध कमांड:\n"
"/subscribe - खबरें लेना शुरू करें\n"
"/unsubscribe - खबरें बंद करें\n"
"/topics - अपने पसंदीदा टॉपिक चुनें\n"
"/help - मदद"
)
def subscribe(update: Update, context: CallbackContext):
user_id = update.effective_user.id
update_user_subscription(user_id, True)
update.message.reply_text("✅ आपने सब्सक्राइब कर लिया! अब आपको नई खबरें मिलेंगी।")
def unsubscribe(update: Update, context: CallbackContext):
user_id = update.effective_user.id
update_user_subscription(user_id, False)
update.message.reply_text("❌ आपने सब्सक्रिप्शन बंद कर दिया। /subscribe से फिर शुरू करें।")
def topics_menu(update: Update, context: CallbackContext):
keyboard = [
[InlineKeyboardButton("राजनीति", callback_data='topic_राजनीति')],
[InlineKeyboardButton("खेल", callback_data='topic_खेल')],
[InlineKeyboardButton("मनोरंजन", callback_data='topic_मनोरंजन')],
[InlineKeyboardButton("सभी टॉपिक (डिफ़ॉल्ट)", callback_data='topic_all')],
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("अपने पसंदीदा टॉपिक चुनें (एक या अधिक):", reply_markup=reply_markup)
def button_callback(update: Update, context: CallbackContext):
query = update.callback_query
query.answer()
user_id = query.from_user.id
data = query.data
if data == 'topic_all':
update_user_topics(user_id, None)
query.edit_message_text("✅ आपको सभी टॉपिक की खबरें मिलेंगी।")
elif data.startswith('topic_'):
topic = data.replace('topic_', '')
# मौजूदा टॉपिक्स को पढ़ें और अपडेट करें (यहाँ सरलता के लिए सिर्फ एक टॉपिक सेट कर रहे हैं)
# आप चाहें तो मल्टी-सेलेक्ट का भी प्रबंध कर सकते हैं
update_user_topics(user_id, topic)
query.edit_message_text(f"✅ आपने टॉपिक चुन लिया: {topic}")
def help_command(update: Update, context: CallbackContext):
update.message.reply_text(
"मैं न्यूज़वेव बॉट हूं।\n"
"/subscribe - खबरें लेना शुरू करें\n"
"/unsubscribe - खबरें बंद करें\n"
"/topics - अपने पसंदीदा टॉपिक चुनें\n"
"/start - बॉट शुरू करें"
)
# ============================================
# मेन फंक्शन
# ============================================
def main():
logger.info("🚀 न्यूज़वेव एडवांस्ड बॉट शुरू हो रहा है...")
setup_database()
updater = Updater(BOT_TOKEN, use_context=True)
dp = updater.dispatcher
# कमांड हैंडलर
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("subscribe", subscribe))
dp.add_handler(CommandHandler("unsubscribe", unsubscribe))
dp.add_handler(CommandHandler("topics", topics_menu))
dp.add_handler(CommandHandler("help", help_command))
dp.add_handler(CallbackQueryHandler(button_callback))
# शेड्यूलर सेटअप
if SCHEDULE_TIMES:
for t in SCHEDULE_TIMES:
schedule.every().day.at(t).do(lambda: check_rss_feeds(updater.bot))
logger.info(f"⏰ शेड्यूल जोड़ा: {t}")
# पहली बार तुरंत चलाएं (ऑप्शनल)
check_rss_feeds(updater.bot)
# शेड्यूलर को एक अलग थ्रेड में या मेन लूप में चलाएं
# यहाँ हम शेड्यूलर को मेन लूप में चलाएंगे
updater.start_polling()
logger.info("📡 बॉट पोलिंग शुरू...")
while True:
schedule.run_pending()
time.sleep(60) # हर मिनट चेक करें
else:
# अगर शेड्यूल नहीं है तो पुराने तरीके से इंटरवल पर चलाएं
updater.start_polling()
logger.info(f"⏱️ हर {CHECK_INTERVAL} मिनट में चेक करूंगा")
while True:
check_rss_feeds(updater.bot)
time.sleep(CHECK_INTERVAL * 60)
if __name__ == "__main__":
main()
⚙️ आवश्यक Environment Variables (Railway या .env में सेट करें)
Variable उदाहरण विवरण
BOT_TOKEN 123456:ABC-DEF... BotFather से मिला टोकन
CHANNEL_ID -1001234567890 (वैकल्पिक) मुख्य चैनल/ग्रुप ID
RSS_FEEDS https://.../feeds/posts/default,https://.../rss.xml एक या अधिक RSS URLs (कॉमा से अलग)
ENABLE_TRANSLATION True अनुवाद चालू करें
TARGET_LANGUAGE hi लक्ष्य भाषा (hi, en, mr, etc.)
SEND_WITH_PHOTO True फोटो सहित भेजें
FILTER_BY_TOPIC True टॉपिक फ़िल्टर चालू करें
ALLOWED_TOPICS राजनीति,खेल,मनोरंजन अनुमत टॉपिक (कॉमा से अलग)
SCHEDULE_TIMES 08:00,14:00,19:00 भेजने के समय (24-घंटे फॉर्मेट)
ENABLE_SUBSCRIPTIONS True यूज़र सब्सक्रिप्शन चालू करें
MAX_POSTS_PER_RUN 5 एक बार में अधिकतम पोस्ट
📦 आवश्यक Python पैकेज (requirements.txt)
python-telegram-bot==20.7
feedparser==6.0.10
googletrans==4.0.0rc1
beautifulsoup4==4.12.2
requests==2.31.0
schedule==1.2.0
🚀 Railway पर डिप्लॉयमेंट
GitHub पर नया रिपॉजिटरी बनाएं और उपरोक्त फाइलें (bot.py, requirements.txt) डालें।
Railway में नया प्रोजेक्ट बनाएँ और GitHub से कनेक्ट करें।
सभी Environment Variables ऊपर दिए अनुसार सेट करें।
डिप्लॉय करें – Railway स्वचालित रूप से बॉट को चलाएगा।
अब मैं आपको सभी फीचर्स को एक साथ स्टेप बाय स्टेप इंप्लीमेंट करने का पूरा तरीका बताता हूँ। हम एक ऐसा Telegram Bot बनाएंगे जिसमें ये सब होगा:
✅ मल्टीपल RSS फीड
✅ फोटो के साथ पोस्ट
✅ ऑटोमैटिक लैंग्वेज ट्रांसलेशन
✅ टॉपिक के हिसाब से फिल्टर
✅ टाइमटेबल सेट करना
✅ यूजर सब्सक्रिप्शन
📦 चरण 1: प्रोजेक्ट फोल्डर तैयार करें
अपने कंप्यूटर पर एक नया फोल्डर बनाएँ:
mkdir newswave-advanced-bot
cd newswave-advanced-bot
📝 चरण 2: सभी जरूरी फाइलें बनाएँ
फाइल 1: requirements.txt
python-telegram-bot==20.7
feedparser==6.0.10
googletrans==4.0.0rc1
beautifulsoup4==4.12.2
requests==2.31.0
schedule==1.2.0
फाइल 2: Procfile
worker: python bot.py
फाइल 3: railway.json
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "NIXPACKS"
},
"deploy": {
"numReplicas": 1,
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10
}
}
फाइल 4: bot.py (पूरा कोड)
नीचे दिया गया कोड कॉपी करके bot.py में सेव करें। इसमें सारे फीचर्स शामिल हैं और हर लाइन पर हिंदी में कमेंट दिया गया है ताकि आप समझ सकें।
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
न्यूज़वेव एडवांस्ड टेलीग्राम बॉट
फीचर्स: मल्टीपल RSS, फोटो, ट्रांसलेशन, टॉपिक फिल्टर, टाइमटेबल, यूजर सब्सक्रिप्शन
"""
import feedparser
import time
import sqlite3
import logging
import hashlib
import html
import re
import os
import requests
import schedule
from datetime import datetime
from telegram import Bot, Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, MessageHandler, Filters, CallbackContext
from telegram.error import TelegramError
from googletrans import Translator
from bs4 import BeautifulSoup
# ============================================
# कॉन्फ़िगरेशन - Environment Variables से लें
# ============================================
BOT_TOKEN = os.environ.get("BOT_TOKEN")
CHANNEL_ID = os.environ.get("CHANNEL_ID") # ऑप्शनल: अगर चैनल में भी भेजना है
# मल्टीपल RSS फीड्स (कॉमा से अलग करें)
RSS_FEEDS = os.environ.get("RSS_FEEDS", "https://newswaveblog24.blogspot.com/feeds/posts/default").split(',')
# ट्रांसलेशन ऑन/ऑफ
ENABLE_TRANSLATION = os.environ.get("ENABLE_TRANSLATION", "True").lower() == "true"
TARGET_LANGUAGE = os.environ.get("TARGET_LANGUAGE", "hi") # hi = हिंदी
# टॉपिक फिल्टर
FILTER_BY_TOPIC = os.environ.get("FILTER_BY_TOPIC", "False").lower() == "true"
ALLOWED_TOPICS = os.environ.get("ALLOWED_TOPICS", "").split(',') # जैसे "राजनीति,खेल,मनोरंजन"
# टाइमटेबल (कॉमा से अलग समय, 24-घंटे फॉर्मेट में)
SCHEDULE_TIMES = os.environ.get("SCHEDULE_TIMES", "08:00,14:00,19:00").split(',')
# फोटो के साथ भेजना है?
SEND_WITH_PHOTO = os.environ.get("SEND_WITH_PHOTO", "True").lower() == "true"
# एक बार में कितने पोस्ट भेजने हैं
MAX_POSTS_PER_RUN = int(os.environ.get("MAX_POSTS_PER_RUN", 5))
# चैनल मोड (True = सिर्फ चैनल में भेजे, False = सब्सक्राइब्ड यूजर्स को भेजे)
CHANNEL_MODE = os.environ.get("CHANNEL_MODE", "True").lower() == "true"
# ============================================
# लॉगिंग सेटअप
# ============================================
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('bot.log'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# ============================================
# ट्रांसलेटर सेटअप
# ============================================
translator = Translator()
def translate_text(text, dest_lang=TARGET_LANGUAGE):
"""टेक्स्ट को टार्गेट लैंग्वेज में ट्रांसलेट करता है"""
if not text or not ENABLE_TRANSLATION:
return text
try:
if len(text) > 5000:
text = text[:5000]
translated = translator.translate(text, dest=dest_lang)
return translated.text
except Exception as e:
logger.error(f"❌ ट्रांसलेशन एरर: {e}")
return text
# ============================================
# डेटाबेस सेटअप
# ============================================
def setup_database():
"""SQLite डेटाबेस बनाता है - पोस्ट और यूजर्स के लिए"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
# भेजे गए पोस्ट की टेबल
c.execute('''
CREATE TABLE IF NOT EXISTS sent_posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
post_hash TEXT UNIQUE,
title TEXT,
link TEXT,
published TEXT,
source_feed TEXT,
topics TEXT,
sent_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# यूजर सब्सक्रिप्शन टेबल
c.execute('''
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY,
chat_id INTEGER,
username TEXT,
first_name TEXT,
subscribed BOOLEAN DEFAULT 1,
topics TEXT, -- NULL का मतलब सभी टॉपिक
subscribed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_active TIMESTAMP
)
''')
conn.commit()
conn.close()
logger.info("✅ डेटाबेस सेटअप पूरा")
# ============================================
# पोस्ट ट्रैकिंग फंक्शन
# ============================================
def is_post_sent(post_hash):
"""चेक करता है कि पोस्ट पहले भेजी जा चुकी है या नहीं"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("SELECT id FROM sent_posts WHERE post_hash = ?", (post_hash,))
result = c.fetchone()
conn.close()
return result is not None
def mark_post_sent(post_hash, title, link, published, source_feed, topics):
"""पोस्ट को डेटाबेस में सेव करता है"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
try:
c.execute(
"INSERT INTO sent_posts (post_hash, title, link, published, source_feed, topics) VALUES (?, ?, ?, ?, ?, ?)",
(post_hash, title, link, published, source_feed, topics)
)
conn.commit()
except sqlite3.IntegrityError:
pass
finally:
conn.close()
# ============================================
# यूजर मैनेजमेंट फंक्शन
# ============================================
def save_user(update: Update):
"""यूजर को डेटाबेस में सेव/अपडेट करता है"""
user = update.effective_user
chat_id = update.effective_chat.id
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute('''
INSERT OR REPLACE INTO users
(user_id, chat_id, username, first_name, last_active)
VALUES (?, ?, ?, ?, CURRENT_TIMESTAMP)
''', (user.id, chat_id, user.username, user.first_name))
conn.commit()
conn.close()
def get_subscribed_users():
"""सब्सक्राइब्ड यूजर्स की लिस्ट लौटाता है (user_id, chat_id, topics)"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("SELECT user_id, chat_id, topics FROM users WHERE subscribed = 1")
users = c.fetchall()
conn.close()
return users
def update_user_subscription(user_id, subscribed):
"""यूजर के सब्सक्रिप्शन स्टेटस को अपडेट करता है"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("UPDATE users SET subscribed = ?, last_active = CURRENT_TIMESTAMP WHERE user_id = ?", (subscribed, user_id))
conn.commit()
conn.close()
def update_user_topics(user_id, topics):
"""यूजर के पसंदीदा टॉपिक अपडेट करता है"""
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("UPDATE users SET topics = ?, last_active = CURRENT_TIMESTAMP WHERE user_id = ?", (topics, user_id))
conn.commit()
conn.close()
# ============================================
# इमेज एक्सट्रैक्ट करने के फंक्शन
# ============================================
def extract_first_image(entry):
"""RSS एंट्री से पहली इमेज ढूंढता है"""
# मीडिया कंटेंट
if 'media_content' in entry and len(entry.media_content) > 0:
for media in entry.media_content:
if 'url' in media:
return media['url']
# media:thumbnail
if 'media_thumbnail' in entry and len(entry.media_thumbnail) > 0:
return entry.media_thumbnail[0]['url']
# enclosures
if 'enclosures' in entry and len(entry.enclosures) > 0:
for enclosure in entry.enclosures:
if enclosure.get('type', '').startswith('image/'):
return enclosure.get('href', '')
# HTML कंटेंट से img टैग
content = ''
if 'summary' in entry:
content = entry.summary
elif 'description' in entry:
content = entry.description
elif 'content' in entry and len(entry.content) > 0:
content = entry.content[0].value
if content:
soup = BeautifulSoup(content, 'html.parser')
img = soup.find('img')
if img and img.get('src'):
return img['src']
return None
def download_image(url):
"""इमेज डाउनलोड करता है"""
try:
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers, timeout=10)
if response.status_code == 200:
return response.content
except Exception as e:
logger.error(f"❌ इमेज डाउनलोड एरर: {e}")
return None
# ============================================
# टॉपिक एक्सट्रैक्ट करने के फंक्शन
# ============================================
def extract_topics(entry):
"""RSS एंट्री से टॉपिक/कैटेगरी निकालता है"""
topics = []
# Blogger के लिए: कैटेगरी टैग
if 'tags' in entry:
for tag in entry.tags:
if 'term' in tag:
topics.append(tag['term'].strip())
# dc:subject
if 'dc_subject' in entry:
if isinstance(entry.dc_subject, list):
topics.extend(entry.dc_subject)
else:
topics.append(entry.dc_subject)
# category फील्ड
if 'category' in entry:
if isinstance(entry.category, list):
topics.extend(entry.category)
else:
topics.append(entry.category)
# डुप्लीकेट हटाएँ और lowercase करें
topics = list(set([t.lower().strip() for t in topics if t]))
return topics
def should_send_post(entry):
"""चेक करता है कि पोस्ट भेजनी चाहिए या नहीं (ग्लोबल फिल्टर के हिसाब से)"""
if not FILTER_BY_TOPIC or not ALLOWED_TOPICS or ALLOWED_TOPICS == ['']:
return True
topics = extract_topics(entry)
allowed = [t.strip().lower() for t in ALLOWED_TOPICS if t.strip()]
# अगर कोई भी टॉपिक allowed में है तो भेजें
for topic in topics:
if topic in allowed:
return True
return False # सिर्फ मैच होने पर भेजेगा
def user_wants_topic(user_topics, post_topics):
"""चेक करता है कि यूजर इस पोस्ट के टॉपिक में इंटरेस्टेड है या नहीं"""
if not user_topics or user_topics == 'None' or user_topics == '':
return True # सभी टॉपिक
user_topic_list = [t.strip().lower() for t in user_topics.split(',')]
for topic in post_topics:
if topic in user_topic_list:
return True
return False
# ============================================
# मैसेज फॉर्मेट करने के फंक्शन
# ============================================
def clean_html(text):
"""HTML टैग्स हटाता है"""
if not text:
return ""
text = html.unescape(text)
text = re.sub(r'<[^>]+>', '', text)
return text.strip()
def create_message(post, source_feed_name="", post_topics=None):
"""
पोस्ट से Telegram मैसेज बनाता है (ट्रांसलेशन के साथ)
"""
title = clean_html(post.get('title', 'कोई शीर्षक नहीं'))
translated_title = translate_text(title)
# डिस्क्रिप्शन
description = ""
if 'summary' in post:
description = clean_html(post.summary)
elif 'description' in post:
description = clean_html(post.description)
elif 'content' in post and len(post.content) > 0:
description = clean_html(post.content[0].value)
translated_desc = translate_text(description)
# छोटा करें
words = translated_desc.split()
if len(words) > 300:
translated_desc = ' '.join(words[:300]) + "..."
# पब्लिश डेट
published = post.get('published', '')
if published:
try:
dt = datetime.strptime(published, '%a, %d %b %Y %H:%M:%S %Z')
published = dt.strftime('%d %B %Y, %I:%M %p')
except:
pass
link = post.get('link', '')
# सोर्स और टॉपिक
source_text = f"📡 सोर्स: {source_feed_name}\n" if source_feed_name else ""
topics_text = ""
if post_topics:
topics_text = f"🏷️ टॉपिक: {', '.join(post_topics[:3])}\n"
# मैसेज बनाएं
message = f"📰 *{translated_title}*\n\n"
message += source_text
message += topics_text
if published:
message += f"🕒 {published}\n\n"
if translated_desc:
message += f"📝 {translated_desc}\n\n"
message += f"🔗 [पूरा पढ़ें]({link})"
if len(message) > 4000:
message = message[:4000] + "...\n\n" + f"[पूरा पढ़ें]({link})"
return message
# ============================================
# पोस्ट भेजने के फंक्शन (चैनल और यूजर्स को)
# ============================================
def send_post_to_channel(bot, message, image_data=None):
"""चैनल में पोस्ट भेजता है"""
try:
if image_data and SEND_WITH_PHOTO:
bot.send_photo(chat_id=CHANNEL_ID, photo=image_data, caption=message, parse_mode='Markdown')
else:
bot.send_message(chat_id=CHANNEL_ID, text=message, parse_mode='Markdown', disable_web_page_preview=False)
return True
except Exception as e:
logger.error(f"❌ चैनल में भेजने में एरर: {e}")
return False
def send_post_to_users(bot, message, image_data=None, post_topics=None):
"""सब्सक्राइब्ड यूजर्स को पोस्ट भेजता है (टॉपिक फिल्टर के साथ)"""
users = get_subscribed_users()
sent_count = 0
for user_id, chat_id, topics_str in users:
# यूजर के टॉपिक से मिलान करें
if post_topics and not user_wants_topic(topics_str, post_topics):
continue
try:
if image_data and SEND_WITH_PHOTO:
bot.send_photo(chat_id=chat_id, photo=image_data, caption=message, parse_mode='Markdown')
else:
bot.send_message(chat_id=chat_id, text=message, parse_mode='Markdown', disable_web_page_preview=False)
sent_count += 1
time.sleep(0.05) # थ्रॉटलिंग
except Exception as e:
logger.error(f"❌ यूजर {chat_id} को भेजने में एरर: {e}")
logger.info(f"👥 {sent_count} यूजर्स को पोस्ट भेजी")
return sent_count
# ============================================
# RSS फीड चेक करने का मेन फंक्शन
# ============================================
def check_rss_feeds(context: CallbackContext = None):
"""
सभी RSS फीड्स चेक करता है और नई पोस्ट भेजता है
"""
logger.info(f"🔍 {len(RSS_FEEDS)} RSS फीड्स चेक कर रहा हूं...")
bot = context.bot if context else Bot(token=BOT_TOKEN)
total_new_posts = 0
for feed_url in RSS_FEEDS:
feed_url = feed_url.strip()
if not feed_url:
continue
try:
feed = feedparser.parse(feed_url)
if feed.bozo:
logger.warning(f"⚠️ RSS पार्सिंग में दिक्कत: {feed.bozo_exception}")
feed_title = feed.feed.get('title', 'ब्लॉग')
logger.info(f"📊 {feed_title} - {len(feed.entries)} पोस्ट मिलीं")
new_posts = 0
for entry in feed.entries[:MAX_POSTS_PER_RUN]:
# यूनिक हैश बनाएं
post_hash = hashlib.md5(
f"{entry.get('link', '')}{entry.get('title', '')}".encode()
).hexdigest()
# पहले भेजा तो नहीं?
if is_post_sent(post_hash):
continue
# टॉपिक फिल्टर चेक करें
post_topics = extract_topics(entry)
if not should_send_post(entry):
logger.debug(f"⏭️ टॉपिक फिल्टर हटाया: {entry.get('title', '')[:50]}")
continue
# मैसेज बनाएं
message = create_message(entry, feed_title, post_topics)
# इमेज डाउनलोड करें
image_data = None
if SEND_WITH_PHOTO:
image_url = extract_first_image(entry)
if image_url:
image_data = download_image(image_url)
# पोस्ट भेजें
success = False
if CHANNEL_MODE and CHANNEL_ID:
success = send_post_to_channel(bot, message, image_data)
else:
success_count = send_post_to_users(bot, message, image_data, post_topics)
success = success_count > 0
if success:
# डेटाबेस में मार्क करें
topics_str = ','.join(post_topics) if post_topics else ''
mark_post_sent(
post_hash,
entry.get('title', ''),
entry.get('link', ''),
entry.get('published', ''),
feed_url,
topics_str
)
new_posts += 1
total_new_posts += 1
logger.info(f"✅ नई पोस्ट भेजी: {entry.get('title', '')[:50]}...")
time.sleep(2) # स्पैम न लगे
except Exception as e:
logger.error(f"❌ RSS फीड एरर: {feed_url} - {e}")
logger.info(f"✅ कुल {total_new_posts} नई पोस्ट भेजीं")
return total_new_posts
# ============================================
# टेलीग्राम कमांड हैंडलर
# ============================================
def start(update: Update, context: CallbackContext):
"""कमांड: /start"""
save_user(update)
update.message.reply_text(
"नमस्ते! 🙏\n"
"मैं न्यूज़वेव एडवांस्ड बॉट हूं। यहां आपको ताज़ा खबरें मिलेंगी।\n\n"
"उपलब्ध कमांड:\n"
"/subscribe - खबरें लेना शुरू करें\n"
"/unsubscribe - खबरें बंद करें\n"
"/topics - अपने पसंदीदा टॉपिक चुनें\n"
"/help - मदद"
)
def subscribe(update: Update, context: CallbackContext):
"""कमांड: /subscribe"""
user_id = update.effective_user.id
update_user_subscription(user_id, 1)
update.message.reply_text("✅ आपने सफलतापूर्वक सब्सक्राइब कर लिया! अब आपको नई खबरें मिलेंगी।")
def unsubscribe(update: Update, context: CallbackContext):
"""कमांड: /unsubscribe"""
user_id = update.effective_user.id
update_user_subscription(user_id, 0)
update.message.reply_text("❌ आपने सब्सक्रिप्शन बंद कर दिया। फिर से शुरू करने के लिए /subscribe करें।")
def topics_command(update: Update, context: CallbackContext):
"""कमांड: /topics - टॉपिक चुनने के लिए इनलाइन कीबोर्ड"""
keyboard = [
[InlineKeyboardButton("राजनीति", callback_data='topic_politics')],
[InlineKeyboardButton("खेल", callback_data='topic_sports')],
[InlineKeyboardButton("मनोरंजन", callback_data='topic_entertainment')],
[InlineKeyboardButton("बॉलीवुड", callback_data='topic_bollywood')],
[InlineKeyboardButton("टेक्नोलॉजी", callback_data='topic_tech')],
[InlineKeyboardButton("सभी टॉपिक (डिफ़ॉल्ट)", callback_data='topic_all')],
]
reply_markup = InlineKeyboardMarkup(keyboard)
update.message.reply_text("अपने पसंदीदा टॉपिक चुनें (एक से अधिक के लिए /set_topics का इस्तेमाल करें):", reply_markup=reply_markup)
def set_topics_command(update: Update, context: CallbackContext):
"""कमांड: /set_topics राजनीति,खेल - मैन्युअली टॉपिक सेट करें"""
try:
args = context.args
if not args:
update.message.reply_text("कृपया टॉपिक दें। उदाहरण: /set_topics राजनीति,खेल,मनोरंजन")
return
topics_input = ' '.join(args)
user_id = update.effective_user.id
update_user_topics(user_id, topics_input)
update.message.reply_text(f"✅ आपके पसंदीदा टॉपिक सेट कर दिए गए: {topics_input}")
except Exception as e:
update.message.reply_text("❌ कुछ गड़बड़ हुई। कृपया फिर से कोशिश करें।")
def button_callback(update: Update, context: CallbackContext):
"""इनलाइन कीबोर्ड कॉलबैक हैंडलर"""
query = update.callback_query
query.answer()
user_id = query.from_user.id
data = query.data
# टॉपिक मैपिंग
topic_map = {
'topic_politics': 'राजनीति',
'topic_sports': 'खेल',
'topic_entertainment': 'मनोरंजन',
'topic_bollywood': 'बॉलीवुड',
'topic_tech': 'टेक्नोलॉजी',
'topic_all': None
}
selected_topic = topic_map.get(data)
if selected_topic is None:
# सभी टॉपिक
update_user_topics(user_id, '')
query.edit_message_text("✅ आपको सभी टॉपिक की खबरें मिलेंगी।")
else:
# पुराने टॉपिक को रिप्लेस न करके अपेंड करना है तो हमें पहले करंट टॉपिक लेने होंगे
# सिंपल तरीका: सिर्फ एक टॉपिक सेट करें
update_user_topics(user_id, selected_topic)
query.edit_message_text(f"✅ आपने टॉपिक चुन लिया: {selected_topic}")
def help_command(update: Update, context: CallbackContext):
"""कमांड: /help"""
help_text = """
🤖 *न्यूज़वेव बॉट हेल्प*
*सब्सक्रिप्शन कमांड:*
/subscribe - खबरें लेना शुरू करें
/unsubscribe - खबरें बंद करें
/status - अपना सब्सक्रिप्शन स्टेटस देखें
*टॉपिक कमांड:*
/topics - इनलाइन कीबोर्ड से टॉपिक चुनें
/set_topics टॉपिक1,टॉपिक2 - मैन्युअली टॉपिक सेट करें
*अन्य कमांड:*
/start - बॉट शुरू करें
/help - यह मदद
*उदाहरण:* /set_topics राजनीति,खेल,मनोरंजन
*नोट:* अगर कोई टॉपिक नहीं चुनोगे तो सभी खबरें मिलेंगी।
"""
update.message.reply_text(help_text, parse_mode='Markdown')
def status_command(update: Update, context: CallbackContext):
"""कमांड: /status - यूजर का स्टेटस दिखाए"""
user_id = update.effective_user.id
conn = sqlite3.connect('news_bot.db')
c = conn.cursor()
c.execute("SELECT subscribed, topics FROM users WHERE user_id = ?", (user_id,))
result = c.fetchone()
conn.close()
if result:
subscribed, topics = result
status_text = "✅ सब्सक्राइब्ड" if subscribed else "❌ अनसब्सक्राइब्ड"
topics_text = topics if topics and topics != 'None' else "सभी टॉपिक"
update.message.reply_text(f"आपका स्टेटस:\n{status_text}\nपसंदीदा टॉपिक: {topics_text}")
else:
update.message.reply_text("आप हमारे डेटाबेस में नहीं हैं। /start करें।")
# ============================================
# शेड्यूल्ड जॉब
# ============================================
def scheduled_job(context: CallbackContext):
"""शेड्यूल के अनुसार यह फंक्शन चलेगा"""
logger.info("⏰ शेड्यूल्ड जॉब शुरू")
check_rss_feeds(context)
# ============================================
# मेन फंक्शन
# ============================================
def main():
"""बॉट को इनिशियलाइज़ और स्टार्ट करता है"""
logger.info("🚀 न्यूज़वेव एडवां्स्ड बॉट शुरू हो रहा है...")
# कॉन्फ़िगरेशन दिखाएं
logger.info(f"📡 RSS फीड्स: {len(RSS_FEEDS)}")
logger.info(f"🔤 ट्रांसलेशन: {'चालू' if ENABLE_TRANSLATION else 'बंद'} -> {TARGET_LANGUAGE}")
logger.info(f"🎯 टॉपिक फिल्टर: {'चालू' if FILTER_BY_TOPIC else 'बंद'} -> {ALLOWED_TOPICS}")
logger.info(f"⏰ टाइमटेबल: {SCHEDULE_TIMES}")
logger.info(f"🖼️ फोटो के साथ: {'हां' if SEND_WITH_PHOTO else 'नहीं'}")
logger.info(f"📢 मोड: {'चैनल' if CHANNEL_MODE else 'यूजर सब्सक्रिप्शन'}")
# डेटाबेस सेटअप
setup_database()
# अपडेटर बनाएं
updater = Updater(BOT_TOKEN, use_context=True)
dp = updater.dispatcher
# कमांड हैंडलर रजिस्टर करें
dp.add_handler(CommandHandler("start", start))
dp.add_handler(CommandHandler("subscribe", subscribe))
dp.add_handler(CommandHandler("unsubscribe", unsubscribe))
dp.add_handler(CommandHandler("topics", topics_command))
dp.add_handler(CommandHandler("set_topics", set_topics_command))
dp.add_handler(CommandHandler("status", status_command))
dp.add_handler(CommandHandler("help", help_command))
# कॉलबैक हैंडलर
dp.add_handler(CallbackQueryHandler(button_callback))
# जॉब क्यू में शेड्यूल जोड़ें
jq = updater.job_queue
for time_str in SCHEDULE_TIMES:
time_str = time_str.strip()
if time_str:
try:
hour, minute = map(int, time_str.split(':'))
jq.run_daily(scheduled_job, time=datetime.time(hour, minute), days=tuple(range(7)))
logger.info(f"⏰ शेड्यूल जोड़ा: {time_str}")
except Exception as e:
logger.error(f"❌ शेड्यूल एरर {time_str}: {e}")
# बॉट शुरू करें
updater.start_polling()
logger.info("✅ बॉट पोलिंग शुरू")
# एक बार तुरंत चेक कर लें (ऑप्शनल)
# check_rss_feeds(updater.bot)
# बॉट को चलने दें
updater.idle()
if __name__ == "__main__":
main()
🚀 चरण 3: GitHub पर अपलोड करें
git init
git add .
git commit -m "एडवांस्ड बॉट with all features"
git branch -M main
git remote add origin https://github.com/आपका-यूजरनेम/newswave-advanced-bot.git
git push -u origin main
🌐 चरण 4: Railway पर डिप्लॉय करें
Railway.com पर लॉगिन करें
"New Project" → "Deploy from GitHub repo" चुनें
अपना रिपॉजिटरी चुनें
"Variables" टैब में जाकर ये सारी Environment Variables डालें:
Variable Example Value Description
BOT_TOKEN 123456789:ABCdefGHIjkl BotFather से लिया
CHANNEL_ID -1001234567890 ऑप्शनल, चैनल मोड के लिए
RSS_FEEDS https://newswaveblog24.blogspot.com/feeds/posts/default,https://anotherblog.com/feed.xml कॉमा से अलग करें
ENABLE_TRANSLATION True True या False
TARGET_LANGUAGE hi hi, en, mr, gu, bn, ta, te, etc
FILTER_BY_TOPIC True True या False
ALLOWED_TOPICS राजनीति,खेल,मनोरंजन सिर्फ ये टॉपिक भेजेगा
SCHEDULE_TIMES 08:00,14:00,19:00 24-घंटे फॉर्मेट
SEND_WITH_PHOTO True True या False
MAX_POSTS_PER_RUN 5 एक बार में कितनी पोस्ट
CHANNEL_MODE False False = यूजर्स को भेजेगा
डिप्लॉयमेंट शुरू हो जाएगा। "Deployments" टैब में देखें और "Logs" में चेक करें कि बॉट चल रहा है।
🤖 चरण 5: बॉट को Telegram में टेस्ट करें
अपने बॉट को Telegram में ढूंढें (जैसे @newswave_advanced_bot)
/start करें
/subscribe करें
/topics से अपने पसंदीदा टॉपिक चुनें
/status से चेक करें
अब जब भी आपके ब्लॉग पर नई पोस्ट आएगी, वह आपको Telegram पर मिलेगी (निर्धारित समय पर)
⚙️ फीचर-वाइज एक्सप्लेनेशन
1. मल्टीपल RSS फीड
RSS_FEEDS में कॉमा से अलग करके जितने चाहें उतने फीड डालें।
बॉट हर फीड को चेक करेगा और सबसे नई पोस्ट भेजेगा।
2. फोटो के साथ पोस्ट
SEND_WITH_PHOTO=True करें।
बॉट अपने आप पोस्ट में पहली इमेज ढूंढकर भेजेगा।
3. ऑटो ट्रांसलेशन
ENABLE_TRANSLATION=True और TARGET_LANGUAGE=hi करें।
सारी खबरें हिंदी में आएँगी (भले ही सोर्स अंग्रेजी में हो)।
4. टॉपिक फिल्टर
FILTER_BY_TOPIC=True और ALLOWED_TOPICS="राजनीति,खेल" करें।
बॉट सिर्फ उन्हीं पोस्ट को भेजेगा जिनमें ये टॉपिक हों।
5. टाइमटेबल
SCHEDULE_TIMES="08:00,14:00,19:00" करें।
बॉट दिन में सिर्फ इन तीन समय पर चेक करेगा और खबरें भेजेगा।
6. यूजर सब्सक्रिप्शन
CHANNEL_MODE=False करें।
यूजर्स /subscribe और /unsubscribe कर सकते हैं।
हर यूजर अपने पसंदीदा टॉपिक चुन सकता है (/topics)।
बॉट सिर्फ उन्हीं यूजर्स को खबरें भेजेगा जिन्होंने subscribe किया है और जिनके टॉपिक मैच होते हैं।
🔧 मेंटेनेंस टिप्स
लॉग देखना: Railway के Logs टैब में देखें कि बॉट सही चल रहा है या नहीं।
डेटाबेस बैकअप: Railway पर SQLite डेटाबेस फाइल रहेगी। अगर डिप्लॉय रीसेट होता है तो डेटा चला जाएगा। बेहतर होगा कि आप PostgreSQL या MySQL का इस्तेमाल करें, लेकिन इसके लिए अलग सेटअप चाहिए।
अपडेट: GitHub पर नया कोड पुश करते ही Railway अपने आप नया वर्जन डिप्लॉय कर देगा।
🎉 अब आपके पास पूरी तरह से काम करने वाला एडवांस्ड Telegram Bot है!
क्या आपको किसी और चीज़ में मदद चाहिए? जैसे:
PostgreSQL डेटाबेस से कनेक्ट करना?
मल्टीपल चैनल सपोर्ट?
और भी कस्टमाइज़ेशन?
बताइए, मैं हर कदम पर आपकी मदद के लिए हूँ! 🚀
🏗️ चरण 1: PostgreSQL सेटअप
सबसे पहले Railway पर PostgreSQL डेटाबेस ऐड करते हैं।
1.1 Railway पर PostgreSQL डेटाबेस बनाएं
Railway डैशबोर्ड पर अपने प्रोजेक्ट में जाएं
"New" बटन दबाएं → "Database" → "PostgreSQL" चुनें
Railway अपने आप PostgreSQL डेटाबेस बना देगा और आपको एक Database Connection URL देगा (कुछ इस तरह: postgresql://postgres:password@containers-us-west-xxx.railway.app:5432/railway)
1.2 नई लाइब्रेरीज इंस्टॉल करें
अपनी requirements.txt फाइल में ये जोड़ें:
asyncpg==0.29.0
sqlalchemy==2.0.23
alembic==1.13.0
psycopg2-binary==2.9.9
pytrends==4.9.2
openai==1.12.0
1.3 PostgreSQL कनेक्शन सेटअप
एक नई फाइल बनाएं database.py:
import os
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import Column, Integer, String, Boolean, DateTime, Text, JSON
import datetime
# PostgreSQL connection URL (Railway से मिलेगा)
DATABASE_URL = os.environ.get("DATABASE_URL", "postgresql+asyncpg://user:pass@localhost/dbname")
# Async engine बनाएं
engine = create_async_engine(
DATABASE_URL.replace("postgresql://", "postgresql+asyncpg://"),
echo=True,
future=True
)
# Session factory
AsyncSessionLocal = sessionmaker(
engine, class_=AsyncSession, expire_on_commit=False
)
# Base class for models
Base = declarative_base()
# ============================================
# Database Models
# ============================================
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, unique=True, index=True)
chat_id = Column(Integer)
username = Column(String, nullable=True)
first_name = Column(String, nullable=True)
subscribed = Column(Boolean, default=True)
topics = Column(String, nullable=True) # comma-separated
created_at = Column(DateTime, default=datetime.datetime.utcnow)
last_active = Column(DateTime, default=datetime.datetime.utcnow)
class SentPost(Base):
__tablename__ = "sent_posts"
id = Column(Integer, primary_key=True)
post_hash = Column(String, unique=True, index=True)
title = Column(String)
link = Column(String)
published = Column(String, nullable=True)
source_feed = Column(String)
topics = Column(String, nullable=True)
sent_to_channels = Column(JSON, default=list) # list of channel IDs
sent_date = Column(DateTime, default=datetime.datetime.utcnow)
class Channel(Base):
__tablename__ = "channels"
id = Column(Integer, primary_key=True)
channel_id = Column(String, unique=True, index=True)
channel_name = Column(String)
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.datetime.utcnow)
# ============================================
# Database Functions
# ============================================
async def get_db():
async with AsyncSessionLocal() as session:
yield session
async def init_db():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
1.4 मेन फाइल में PostgreSQL इंटीग्रेट करें
bot.py की शुरुआत में ये इंपोर्ट जोड़ें:
import asyncio
from database import init_db, AsyncSessionLocal, User, SentPost, Channel
from sqlalchemy import select, update, delete
from sqlalchemy.ext.asyncio import AsyncSession
मेन फंक्शन में डेटाबेस इनिशियलाइज़ेशन जोड़ें:
async def async_main():
"""Async version of main function"""
logger.info("🚀 डेटाबेस इनिशियलाइज़ कर रहा हूं...")
await init_db()
# ... बाकी कोड ...
def main():
# ... पुराना कोड ...
asyncio.run(async_main())
📢 चरण 2: मल्टीपल चैनल सपोर्ट
अब हमारा बॉट एक साथ कई Telegram चैनलों में पोस्ट भेज सकेगा।
2.1 Environment Variables में चैनल्स जोड़ें
Railway पर नए वेरिएबल्स:
# कॉमा से अलग किए गए चैनल IDs
CHANNEL_IDS = os.environ.get("CHANNEL_IDS", "").split(',')
# चैनल मोड (multiple/single)
CHANNEL_MODE = os.environ.get("CHANNEL_MODE", "multiple") # multiple या single
2.4 नए Telegram कमांड्स (चैनल मैनेजमेंट के लिए)
async def addchannel_command(update: Update, context: CallbackContext):
"""कमांड: /addchannel - नया चैनल ऐड करें (सिर्फ एडमिन के लिए)"""
# चेक करें कि यूजर एडमिन है या नहीं
user_id = update.effective_user.id
admin_ids = [int(id) for id in os.environ.get("ADMIN_IDS", "").split(',') if id]
if user_id not in admin_ids:
await update.message.reply_text("❌ आपके पास यह कमांड चलाने की अनुमति नहीं है।")
return
try:
args = context.args
if len(args) < 2:
await update.message.reply_text("Usage: /addchannel CHANNEL_ID CHANNEL_NAME")
return
channel_id = args[0]
channel_name = ' '.join(args[1:])
async with AsyncSessionLocal() as session:
await add_channel(session, channel_id, channel_name)
await update.message.reply_text(f"✅ चैनल '{channel_name}' ({channel_id}) सफलतापूर्वक ऐड कर दिया गया!")
except Exception as e:
await update.message.reply_text(f"❌ एरर: {str(e)}")
async def listchannels_command(update: Update, context: CallbackContext):
"""कमांड: /listchannels - सभी एक्टिव चैनल्स दिखाए"""
async with AsyncSessionLocal() as session:
channels = await get_active_channels(session)
if not channels:
await update.message.reply_text("📭 कोई एक्टिव चैनल नहीं है।")
return
message = "📢 *एक्टिव चैनल्स:*\n\n"
for channel in channels:
message += f"• {channel.channel_name}: `{channel.channel_id}`\n"
await update.message.reply_text(message, parse_mode='Markdown')
📈 चरण 3: Google Trends से ऑटोमेटिक ब्लॉग पोस्ट
यह सबसे दिलचस्प फीचर है। हम Google Trends से ट्रेंडिंग टॉपिक्स लेंगे, उन्हें AI से यूनिक स्टाइल में ब्लॉग पोस्ट में बदलेंगे, और फिर अपने ब्लॉग पर अपने आप पब्लिश करेंगे।
3.1 Google Trends से टॉपिक्स निकालना
trends_fetcher.py नाम से नई फाइल बनाएं:
import os
import pandas as pd
from pytrends.request import TrendReq
import logging
from datetime import datetime
import random
logger = logging.getLogger(__name__)
class GoogleTrendsFetcher:
"""Google Trends से ट्रेंडिंग टॉपिक्स निकालने के लिए"""
def __init__(self):
self.pytrends = TrendReq(hl='en-US', tz=330) # hl='hi-IN' for Hindi
self.categories = self._load_categories()
def _load_categories(self):
"""प्री-डिफाइंड कैटेगरी लोड करता है"""
return {
'technology': ['AI', 'Python', 'smartphone', 'laptop'],
'entertainment': ['movie', 'song', 'celebrity', 'web series'],
'sports': ['cricket', 'football', 'ipl', 'olympics'],
'business': ['stock market', 'crypto', 'bitcoin', 'startup'],
'health': ['fitness', 'yoga', 'diet', 'workout'],
}
def get_trending_searches(self, pn='india'):
"""रियल-टाइम ट्रेंडिंग सर्चेस लेता है [citation:1]"""
try:
trending_df = self.pytrends.trending_searches(pn=pn)
if not trending_df.empty:
return trending_df[0].tolist()[:10] # टॉप 10 ट्रेंड्स
except Exception as e:
logger.error(f"❌ Trending searches एरर: {e}")
return []
def get_related_queries(self, keyword):
"""कीवर्ड से जुड़े क्वेरीज़ लेता है [citation:1]"""
try:
self.pytrends.build_payload([keyword], timeframe='today 1-m')
related = self.pytrends.related_queries()
if keyword in related and related[keyword] and 'top' in related[keyword]:
top_queries = related[keyword]['top']
if not top_queries.empty:
return top_queries['query'].tolist()[:5]
except Exception as e:
logger.error(f"❌ Related queries एरर: {e}")
return []
def get_interest_by_region(self, keyword):
"""रिजन-वाइज इंटरेस्ट डेटा लेता है [citation:1]"""
try:
self.pytrends.build_payload([keyword], timeframe='today 1-m')
region_df = self.pytrends.interest_by_region(resolution='COUNTRY')
if not region_df.empty and keyword in region_df.columns:
return region_df[keyword].nlargest(5)
except Exception as e:
logger.error(f"❌ Interest by region एरर: {e}")
return pd.Series()
def get_trending_topics(self, category=None):
"""
मेन फंक्शन - ट्रेंडिंग टॉपिक्स की लिस्ट लौटाता है
"""
all_topics = []
# 1. ट्रेंडिंग सर्चेस से
trending = self.get_trending_searches()
all_topics.extend(trending)
# 2. कैटेगरी-बेस्ड टॉपिक्स
if category and category in self.categories:
for kw in self.categories[category][:3]:
related = self.get_related_queries(kw)
all_topics.extend(related[:2])
# 3. डुप्लीकेट हटाएं
all_topics = list(set(all_topics))
# 4. स्कोरिंग और फिल्टर
scored_topics = self._score_topics(all_topics)
return scored_topics[:10] # टॉप 10 टॉपिक्स
def _score_topics(self, topics):
"""टॉपिक्स को स्कोर करता है (सिंपल वर्जन) [citation:7]"""
scored = []
for topic in topics:
if not topic or len(topic) < 3:
continue
score = 100 # बेस स्कोर
# लेंथ के हिसाब से
if 10 <= len(topic) <= 50:
score += 20
# लोअरकेस/अपरकेस चेक
if topic[0].isupper():
score += 10
# नंबर्स वाले टॉपिक्स (जैसे IPL 2026) को ज्यादा स्कोर
if any(char.isdigit() for char in topic):
score += 15
scored.append((topic, score))
# स्कोर के हिसाब से सॉर्ट करें
scored.sort(key=lambda x: x[1], reverse=True)
return [topic for topic, _ in scored]
3.2 AI से ब्लॉग पोस्ट जनरेट करना
blog_generator.py नाम से नई फाइल:
import os
import openai
import logging
from datetime import datetime
logger = logging.getLogger(__name__)
class BlogPostGenerator:
"""AI से यूनिक स्टाइल में ब्लॉग पोस्ट जनरेट करता है"""
def __init__(self):
self.openai_api_key = os.environ.get("OPENAI_API_KEY")
openai.api_key = self.openai_api_key
# ब्लॉग स्टाइल प्रॉम्प्ट्स
self.styles = {
"conversational": """
Write in a friendly, conversational style as if talking to a friend.
Use simple language, ask rhetorical questions, and keep it engaging.
Add personal touches like "I think", "You know", "Honestly".
""",
"professional": """
Write in a professional, authoritative style suitable for news.
Use formal language, cite sources, maintain objectivity.
Structure with clear headings and logical flow.
""",
"storytelling": """
Write in a storytelling style with narrative flow.
Start with a hook, build suspense, include examples.
Make it feel like you're telling a fascinating story.
""",
"controversial": """
Write with an opinionated, slightly controversial edge.
Challenge common beliefs, ask thought-provoking questions.
Back up opinions with facts but maintain strong perspective.
""",
"humorous": """
Write with wit and humor where appropriate.
Use light jokes, wordplay, and entertaining examples.
Keep it professional but make readers smile.
"""
}
def generate_blog_post(self, topic, style="conversational", word_count=800):
"""
टॉपिक पर ब्लॉग पोस्ट जनरेट करता है
"""
try:
style_prompt = self.styles.get(style, self.styles["conversational"])
prompt = f"""
Write a unique, engaging blog post about: "{topic}"
Style guidelines:
{style_prompt}
Requirements:
- Word count: approximately {word_count} words
- Include an attention-grabbing headline
- Add 3-4 subheadings
- End with a conclusion
- Make it completely original and plagiarism-free
- Use markdown formatting (# for headline, ## for subheadings)
Blog post:
"""
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "You are an expert content writer who creates viral, engaging blog posts."},
{"role": "user", "content": prompt}
],
temperature=0.8,
max_tokens=2000
)
content = response.choices[0].message.content
# टॉपिक को हेडलाइन के रूप में निकालें
lines = content.strip().split('\n')
headline = lines[0].replace('#', '').strip()
return {
"title": headline,
"content": content,
"topic": topic,
"style": style,
"generated_at": datetime.now().isoformat()
}
except Exception as e:
logger.error(f"❌ Blog generation एरर: {e}")
return None
def generate_seo_tags(self, topic, content):
"""SEO टैग्स जनरेट करता है"""
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "Generate 5-7 SEO tags/keywords for this blog post. Return as comma-separated list."},
{"role": "user", "content": f"Topic: {topic}\nContent: {content[:500]}"}
],
temperature=0.5,
max_tokens=100
)
tags = response.choices[0].message.content.strip()
return [tag.strip() for tag in tags.split(',')]
except Exception as e:
logger.error(f"❌ SEO tags एरर: {e}")
return [topic.lower().replace(' ', ',')]
def generate_meta_description(self, content):
"""मेटा डिस्क्रिप्शन जनरेट करता है"""
try:
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "Generate a compelling 150-160 character meta description for this blog post."},
{"role": "user", "content": content[:1000]}
],
temperature=0.5,
max_tokens=50
)
return response.choices[0].message.content.strip()
except Exception as e:
logger.error(f"❌ Meta description एरर: {e}")
return ""
3.3 Blogger API से पोस्ट पब्लिश करना
blogger_publisher.py नाम से नई फाइल:
import os
import requests
import json
import logging
from google.oauth2.credentials import Credentials
from google.auth.transport.requests import Request
from googleapiclient.discovery import build
logger = logging.getLogger(__name__)
class BloggerPublisher:
"""Blogger API से पोस्ट पब्लिश करता है [citation:3][citation:8]"""
def __init__(self):
self.api_key = os.environ.get("GOOGLE_API_KEY")
self.blog_id = os.environ.get("BLOGGER_BLOG_ID")
self.client_id = os.environ.get("GOOGLE_CLIENT_ID")
self.client_secret = os.environ.get("GOOGLE_CLIENT_SECRET")
self.refresh_token = os.environ.get("GOOGLE_REFRESH_TOKEN")
self.service = self._get_service()
def _get_service(self):
"""Blogger API सर्विस बनाता है"""
try:
creds = Credentials(
token=None,
refresh_token=self.refresh_token,
token_uri="https://oauth2.googleapis.com/token",
client_id=self.client_id,
client_secret=self.client_secret,
scopes=["https://www.googleapis.com/auth/blogger"]
)
# रिफ्रेश टोकन से एक्सेस टोकन लें
creds.refresh(Request())
service = build('blogger', 'v3', credentials=creds)
return service
except Exception as e:
logger.error(f"❌ Blogger service एरर: {e}")
return None
def create_post(self, title, content, labels=None, is_draft=False):
"""
नई ब्लॉग पोस्ट क्रिएट करता है [citation:8]
"""
if not self.service:
logger.error("❌ Blogger service उपलब्ध नहीं है")
return None
try:
post_body = {
'title': title,
'content': content,
'labels': labels or []
}
if is_draft:
post_body['status'] = 'draft'
request = self.service.posts().insert(
blogId=self.blog_id,
body=post_body,
isDraft=is_draft
)
result = request.execute()
logger.info(f"✅ पोस्ट पब्लिश हुई: {result.get('url')}")
return {
'id': result.get('id'),
'url': result.get('url'),
'title': result.get('title'),
'published': result.get('published')
}
except Exception as e:
logger.error(f"❌ Post creation एरर: {e}")
return None
def update_post(self, post_id, title=None, content=None, labels=None):
"""पोस्ट अपडेट करता है"""
try:
# पहले मौजूदा पोस्ट लें
post = self.service.posts().get(blogId=self.blog_id, postId=post_id).execute()
if title:
post['title'] = title
if content:
post['content'] = content
if labels:
post['labels'] = labels
result = self.service.posts().update(
blogId=self.blog_id,
postId=post_id,
body=post
).execute()
return result
except Exception as e:
logger.error(f"❌ Post update एरर: {e}")
return None
def get_posts(self, max_results=10):
"""हाल की पोस्ट्स लेता है"""
try:
request = self.service.posts().list(
blogId=self.blog_id,
maxResults=max_results,
fetchBodies=False
)
result = request.execute()
return result.get('items', [])
except Exception as e:
logger.error(f"❌ Get posts एरर: {e}")
return []
3.4 ऑटोमेटिक ब्लॉग पोस्टिंग पाइपलाइन
एक नई फाइल auto_blogger.py बनाएं जो सब कुछ जोड़ेगी:
import asyncio
import logging
import random
from datetime import datetime
from trends_fetcher import GoogleTrendsFetcher
from blog_generator import BlogPostGenerator
from blogger_publisher import BloggerPublisher
from database import AsyncSessionLocal, SentPost
import hashlib
logger = logging.getLogger(__name__)
class AutoBlogger:
"""ऑटोमेटिक ब्लॉग पोस्टिंग सिस्टम"""
def __init__(self):
self.trends_fetcher = GoogleTrendsFetcher()
self.blog_generator = BlogPostGenerator()
self.blogger_publisher = BloggerPublisher()
async def generate_and_publish(self, num_posts=1):
"""
ट्रेंडिंग टॉपिक्स पर पोस्ट जनरेट और पब्लिश करता है
"""
logger.info(f"🚀 {num_posts} नई पोस्ट जनरेट कर रहा हूं...")
# 1. ट्रेंडिंग टॉपिक्स लें
all_topics = self.trends_fetcher.get_trending_topics()
if not all_topics:
logger.warning("⚠️ कोई ट्रेंडिंग टॉपिक नहीं मिला")
return []
logger.info(f"📊 {len(all_topics)} ट्रेंडिंग टॉपिक्स मिले")
published_posts = []
for i in range(min(num_posts, len(all_topics))):
topic = all_topics[i]
# 2. यूनिक स्टाइल चुनें (रैंडम)
style = random.choice(['conversational', 'professional', 'storytelling', 'controversial', 'humorous'])
# 3. ब्लॉग पोस्ट जनरेट करें
logger.info(f"✍️ '{topic}' पर '{style}' स्टाइल में पोस्ट लिख रहा हूं...")
post_data = self.blog_generator.generate_blog_post(topic, style=style)
if not post_data:
continue
# 4. SEO टैग्स और मेटा डिस्क्रिप्शन जनरेट करें
seo_tags = self.blog_generator.generate_seo_tags(topic, post_data['content'])
meta_desc = self.blog_generator.generate_meta_description(post_data['content'])
# 5. HTML कंटेंट तैयार करें
html_content = f"""
{post_data['content']}
\n' + formatted
return formatted
# ============================================
# Google Trends Fetcher
# ============================================
class GoogleTrendsFetcher:
def __init__(self):
self.rss_urls = [
"https://trends.google.com/trends/trendingsearches/daily/rss?geo=IN", # India
"https://trends.google.com/trends/trendingsearches/daily/rss?geo=US", # US
]
def fetch_topics(self, limit=10):
"""Google Trends से टॉपिक्स लें"""
topics = []
for rss_url in self.rss_urls:
try:
feed = feedparser.parse(rss_url)
for entry in feed.entries[:limit]:
topic = {
'title': entry.get('title', ''),
'description': entry.get('description', ''),
'source': 'google_trends',
'score': 100 - len(topics) # Simple ranking
}
topics.append(topic)
except Exception as e:
logger.error(f"Error fetching Google Trends: {e}")
return topics
# ============================================
# Telegram Bot Handler
# ============================================
class TelegramBotHandler:
def __init__(self, token):
self.bot = Bot(token=token)
self.channels = config.TELEGRAM_CHANNELS
def send_post(self, post, image_url=None):
"""पोस्ट को Telegram channels में भेजें"""
# Message format
message = f"""📰 *{post['title']}*
{post.get('summary', '')[:200]}...
🔗 [पूरा पढ़ें]({post.get('link', '#')})
#news #trending
"""
results = []
for channel in self.channels:
try:
if image_url and image_url.startswith('http'):
# Send with photo
msg = self.bot.send_photo(
chat_id=channel,
photo=image_url,
caption=message,
parse_mode='Markdown'
)
else:
# Send text only
msg = self.bot.send_message(
chat_id=channel,
text=message,
parse_mode='Markdown',
disable_web_page_preview=False
)
results.append({
'channel': channel,
'message_id': msg.message_id,
'status': 'success'
})
logger.info(f"✅ Sent to channel {channel}")
except Exception as e:
logger.error(f"❌ Failed to send to {channel}: {e}")
results.append({
'channel': channel,
'error': str(e),
'status': 'failed'
})
return results
def setup_handlers(self, updater):
"""Telegram command handlers setup करें"""
dp = updater.dispatcher
dp.add_handler(CommandHandler("start", self.start_command))
dp.add_handler(CommandHandler("latest", self.latest_command))
dp.add_handler(CommandHandler("trends", self.trends_command))
dp.add_handler(CommandHandler("subscribe", self.subscribe_command))
dp.add_handler(CommandHandler("help", self.help_command))
logger.info("✅ Telegram handlers setup complete")
def start_command(self, update, context):
"""Start command handler"""
update.message.reply_text(
"नमस्ते! 🙏\n"
"मैं न्यूज़वेव बॉट हूं।\n\n"
"उपलब्ध कमांड:\n"
"/latest - ताज़ा खबरें\n"
"/trends - ट्रेंडिंग टॉपिक्स\n"
"/subscribe - खबरें लेना शुरू करें\n"
"/help - मदद"
)
def latest_command(self, update, context):
"""Latest news command"""
posts = BlogPost.query.order_by(BlogPost.created_at.desc()).limit(5).all()
if not posts:
update.message.reply_text("अभी कोई खबर नहीं है।")
return
for post in posts:
message = f"📰 *{post.title}*\n\n{post.summary[:200]}..."
update.message.reply_text(message, parse_mode='Markdown')
def trends_command(self, update, context):
"""Trending topics command"""
topics = TrendingTopic.query.filter_by(used=False).order_by(TrendingTopic.created_at.desc()).limit(10).all()
if not topics:
update.message.reply_text("अभी कोई ट्रेंडिंग टॉपिक नहीं।")
return
message = "🔥 *ट्रेंडिंग टॉपिक्स:*\n\n"
for i, topic in enumerate(topics, 1):
message += f"{i}. {topic.topic}\n"
update.message.reply_text(message, parse_mode='Markdown')
def subscribe_command(self, update, context):
"""Subscribe command"""
# यहां आप यूजर को सब्सक्राइब कर सकते हैं
update.message.reply_text("✅ आपने सफलतापूर्वक सब्सक्राइब कर लिया!")
def help_command(self, update, context):
"""Help command"""
update.message.reply_text(
"सहायता:\n"
"/start - बॉट शुरू करें\n"
"/latest - ताज़ा खबरें\n"
"/trends - ट्रेंडिंग टॉपिक्स\n"
"/subscribe - खबरें सब्सक्राइब करें"
)
# ============================================
# Main Scheduler
# ============================================
class NewsScheduler:
def __init__(self):
self.ai_blog = AIBlogGenerator()
self.ai_image = AIImageGenerator()
self.trends = GoogleTrendsFetcher()
self.telegram = TelegramBotHandler(config.BOT_TOKEN)
def run_once(self):
"""एक बार सारे टास्क चलाएं"""
logger.info("🚀 Starting scheduled news generation...")
with app.app_context():
# 1. Get trending topics
topics = self.trends.fetch_topics(limit=config.MAX_POSTS_PER_DAY)
logger.info(f"📊 Found {len(topics)} trending topics")
for topic_data in topics:
try:
topic = topic_data['title']
# Save to database
db_topic = TrendingTopic(
topic=topic,
source=topic_data.get('source', 'google'),
score=topic_data.get('score', 50)
)
db.session.add(db_topic)
db.session.commit()
# 2. Generate blog post
logger.info(f"📝 Generating post for: {topic}")
content = self.ai_blog.generate_blog_post(topic)
# 3. Generate image
logger.info(f"🎨 Generating image for: {topic}")
image_url = self.ai_image.generate_image(topic)
# 4. Create post object
post = {
'title': topic,
'content': content,
'summary': content[:300] + "...",
'image_url': image_url,
'source_topic': topic,
'link': f"https://newswaveblog24.blogspot.com/search?q={topic.replace(' ', '+')}"
}
# 5. Publish to Blogger
blogger = BloggerAPI(credentials=session.get('google_credentials'))
blogger_post_id = blogger.create_post(
title=topic,
content=content,
labels=[topic_data.get('source', 'news'), 'AI Generated'],
image_url=image_url
)
# 6. Save to database
db_post = BlogPost(
title=topic,
content=content,
summary=content[:300],
image_url=image_url,
source_topic=topic,
blogger_post_id=blogger_post_id,
published_at=datetime.utcnow(),
is_published=True
)
db.session.add(db_post)
db.session.commit()
# 7. Send to Telegram
telegram_results = self.telegram.send_post(post, image_url)
# 8. Save Telegram messages
for result in telegram_results:
if result['status'] == 'success':
tm = TelegramMessage(
post_id=db_post.id,
channel_id=result['channel'],
message_id=str(result['message_id']),
status='sent'
)
db.session.add(tm)
# 9. Mark topic as used
db_topic.used = True
db_topic.used_at = datetime.utcnow()
db.session.commit()
logger.info(f"✅ Successfully processed: {topic}")
except Exception as e:
logger.error(f"❌ Error processing topic: {e}")
db.session.rollback()
logger.info("✅ Scheduled run completed!")
def run_scheduler(self):
"""Schedule setup और run"""
# Schedule times
for schedule_time in config.SCHEDULE_TIMES:
schedule.every().day.at(schedule_time).do(self.run_once)
logger.info(f"⏰ Scheduled job at {schedule_time}")
logger.info("🔄 Scheduler started...")
# Run once immediately on startup
self.run_once()
# Keep running
while True:
schedule.run_pending()
time.sleep(60)
# ============================================
# HTML Templates (simplified - in real app, create separate files)
# ============================================
@app.route('/templates/index.html')
def serve_index():
return """
न्यूज़वेव - AI न्यूज़ जेनरेटर
डैशबोर्ड - न्यूज़वेव
",
"labels": ["AI Generated", "Trending", "News"]
}
📱 चरण 5: टेलीग्राम पर भेजें
5.1 टेलीग्राम मैसेज फॉर्मेट करें
text
Node: Code
JavaScript Code:
javascript
const data = $input.first().json;
const message = `📰 *${data.trending_keyword}*
${data.blogPost.substring(0, 300)}...
🔗 [ब्लॉग पर पूरा पढ़ें](${data.bloggerUrl})
#news #trending #AINews`;
return { message };
5.2 टेलीग्राम पर फोटो के साथ भेजें
text
Node: Telegram
कॉन्फ़िगरेशन:
- Operation: Send Photo
- Chat ID: {{$env.TELEGRAM_CHANNEL_ID}} (या कॉमा से अलग किए गए मल्टीपल IDs)
- Photo: {{ $json.imageBinary }}
- Caption: {{ $json.message }}
- Parse Mode: Markdown
अगर आपके पास मल्टीपल टेलीग्राम चैनल हैं, तो आप Split In Batches या Loop नोड का इस्तेमाल करके सभी चैनल्स पर भेज सकते हैं ।
📊 चरण 6: Google Sheets में सेव करें (बैकअप और ट्रैकिंग)
text
Node: Google Sheets
कॉन्फ़िगरेशन:
- Operation: Append
- Sheet ID: आपकी Google Sheet का ID
- Range: Sheet1!A:Z
- Mapping:
- trending_keyword: {{ $json.trending_keyword }}
- approx_traffic: {{ $json.approx_traffic }}
- pubDate: {{ $json.pubDate }}
- blog_url: {{ $json.bloggerUrl }}
- status: "published"
- created_at: {{ Date.now() }}
Google Sheets के लिए कॉलम हेडर्स पहले से सेट कर लें :
trending_keyword | approx_traffic | pubDate | blog_url | status | created_at
🧩 चरण 7: एडवांस्ड फीचर्स जोड़ें
7.1 Jina.ai से न्यूज आर्टिकल्स समरी करें (ऑप्शनल)
अगर आप चाहते हैं कि AI सिर्फ टॉपिक के नाम से नहीं, बल्कि असली न्यूज आर्टिकल्स पढ़कर ब्लॉग लिखे, तो Jina.ai का इस्तेमाल करें :
text
Node: HTTP Request (Jina.ai)
कॉन्फ़िगरेशन:
- Method: GET
- URL: https://r.jina.ai/{{ $json.news_url1 }}
- Headers:
- Authorization: Bearer {{$env.JINA_API_KEY}}
फिर तीनों आर्टिकल्स के कंटेंट को मिलाकर OpenAI को भेजें।
7.2 एरर हैंडलिंग और नोटिफिकेशन
text
Node: IF (एरर चेक करने के लिए)
Condition: {{ $json.blogPost.length > 100 }}
अगर TRUE → आगे बढ़ें
अगर FALSE → एरर टेलीग्राम भेजें
7.3 मल्टीपल टेलीग्राम चैनल के लिए लूप
text
Node: Split In Batches
Batch Size: 1
Item Data: चैनल IDs की लिस्ट
Node: Telegram
Chat ID: {{ $json.channelId }}
🎯 चरण 8: पूरे वर्कफ्लो का फ्लोचार्ट
text
┌─────────────────────────────────────────────────────────────────┐
│ न्यूज़रूम ऑटोमेशन - n8n वर्कफ्लो │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ Schedule │ (हर दिन 8,14,19 बजे)
│ Trigger │
└────────┬────────┘
↓
┌─────────────────┐
│ HTTP Request │ (Google Trends RSS फेच करें)
│ (Google Trends)│
└────────┬────────┘
↓
┌─────────────────┐
│ XML to JSON │ (RSS को JSON में बदलें)
└────────┬────────┘
↓
┌─────────────────┐
│ Code Node │ (ट्रेंड्स नॉर्मलाइज़ करें, ट्रैफिक पार्स करें)
│ (Normalize) │
└────────┬────────┘
↓
┌─────────────────┐
│ Google Sheets │ (पुराने टॉपिक्स पढ़ें - डुप्लीकेट चेक)
│ (Read) │
└────────┬────────┘
↓
┌─────────────────┐
│ Code Node │ (डुप्लीकेट फिल्टर करें)
│ (Deduplicate) │
└────────┬────────┘
↓
┌─────────────────┐
│ Split In │ (हर टॉपिक के लिए अलग-अलग प्रोसेस)
│ Batches │
└────────┬────────┘
↓
╭────┴────╮
↓ ↓
┌──────────┐ ┌──────────┐ (तीनों न्यूज लिंक के लिए)
│ Jina.ai │ │ Jina.ai │
│ (Article │ │ (Article │
│ 1) │ │ 2) │
└────┬─────┘ └────┬─────┘
↓ ↓
╰────┬────╯
↓
┌─────────────────┐
│ Code Node │ (सारे कंटेंट मिलाएं)
│ (Combine) │
└────────┬────────┘
↓
┌─────────────────┐
│ OpenAI │ (AI से ब्लॉग पोस्ट लिखवाएं)
│ (ChatGPT) │
└────────┬────────┘
↓
┌─────────────────┐
│ Stability AI │ (AI से इमेज जनरेट करें)
│ (Image Gen) │
└────────┬────────┘
↓
┌─────────────────┐
│ HTTP Request │ (Blogger API से पोस्ट करें)
│ (Blogger API) │
└────────┬────────┘
↓
┌─────────────────┐
│ Code Node │ (टेलीग्राम मैसेज फॉर्मेट करें)
│ (Format Msg) │
└────────┬────────┘
↓
┌─────────────────┐
│ Split In │ (मल्टीपल टेलीग्राम चैनल के लिए)
│ Batches │
└────────┬────────┘
↓
╭────┴────╮
↓ ↓
┌──────────┐ ┌──────────┐
│Telegram │ │Telegram │
│ Channel 1│ │ Channel 2│
└────┬─────┘ └────┬─────┘
↓ ↓
╰────┬────╯
↓
┌─────────────────┐
│ Google Sheets │ (पोस्ट की जानकारी सेव करें)
│ (Append) │
└─────────────────┘
⚙️ चरण 9: Environment Variables सेट करें (Railway के लिए)
Railway डैशबोर्ड में Variables सेक्शन में ये सब डालें:
Variable Value
BLOG_ID आपका Blogger Blog ID
TELEGRAM_BOT_TOKEN BotFather से मिला टोकन
TELEGRAM_CHANNEL_IDS -1001234567890,-1009876543210 (कॉमा से अलग)
OPENAI_API_KEY OpenAI API Key
STABILITY_API_KEY Stability AI API Key
JINA_API_KEY Jina.ai API Key
GOOGLE_SHEET_ID Google Sheet का ID
✅ चरण 10: टेस्ट और डीबग
10.1 हर नोड को अलग-अलग टेस्ट करें
हर नोड पर "Execute Node" बटन दबाकर चेक करें कि सही आउटपुट आ रहा है
10.2 कॉमन एरर्स और सॉल्यूशन
एरर कारण समाधान
401 Unauthorized API Key गलत या एक्सपायर क्रेडेंशियल्स दोबारा जनरेट करें
429 Too Many Requests रेट लिमिट वर्कफ्लो में Wait नोड लगाएं
XML पार्सिंग एरर RSS फीड का फॉर्मेट बदला Code Node में पार्सिंग लॉजिक चेक करें
Telegram "Chat not found" Chat ID गलत Chat ID में माइनस साइन है? (-100 से शुरू)
10.3 डीबगिंग टिप्स
हर नोड के आउटपुट में "Binary Data" या "JSON" टैब देखें
एरर आने पर नोड पर रेड आइकन दिखेगा, उस पर क्लिक करके एरर मैसेज पढ़ें
टेस्टिंग के लिए "Execute Workflow" बटन दबाकर पूरा वर्कफ्लो चलाएं
🚀 निष्कर्ष
अब आपके पास n8n में पूरी तरह से ऑटोमेटेड न्यूज़रूम सिस्टम है जो:
✅ Google Trends से ट्रेंडिंग टॉपिक्स लेता है
✅ AI से यूनिक ब्लॉग पोस्ट लिखता है
✅ AI से संबंधित इमेज जनरेट करता है
✅ Blogger पर ऑटोमेटिक पोस्ट करता है
✅ मल्टीपल टेलीग्राम चैनल्स में भेजता है
✅ Google Sheets में सारा डेटा सेव करता है
यह वर्कफ्लो दिन में तीन बार (8,14,19 बजे) अपने आप चलेगा और आपको ताजा कंटेंट देता रहेगा ।
अगले स्टेप:
n8n डैशबोर्ड में जाकर वर्कफ्लो को "Activate" करें
पहली बार "Execute Workflow" दबाकर टेस्ट करें
लॉग्स चेक करें और जरूरत के हिसाब से ट्वीक करें
कोई प्रॉब्लम आए तो बताएं, मैं हर स्टेप में मदद करूंगा! 🎉
n8n dashboard me activate kaise
Read 10 web pages
नमस्ते! आपने पूछा है कि n8n डैशबोर्ड में वर्कफ्लो को Activate कैसे करें। यह एक बहुत ही कॉमन सवाल है, क्योंकि n8n के नए वर्जन में यह बटन बदल गया है।
मैंने इसके बारे में जानकारी खोजी है और पाया कि n8n वर्जन 2.x में पुराना "Activate" बटन हटा दिया गया है। अब उसकी जगह Publish बटन आ गया है ।
चलिए, मैं आपको स्टेप बाय स्टेप समझाता हूँ कि कैसे अपने वर्कफ्लो को "एक्टिवेट" करें:
🚀 n8n में वर्कफ्लो को "एक्टिवेट" (Publish) करने का तरीका
समझने वाली मुख्य बात:
n8n के वर्जन 1.x में Activate बटन था, लेकिन वर्जन 2.x में इसे Publish से रिप्लेस कर दिया गया है । Publish करने का मतलब ही है कि आपका वर्कफ्लो अब लाइव हो गया है और अपने ट्रिगर (जैसे Schedule, Webhook) के आधार पर अपने आप चलेगा ।
✅ Step-by-Step Guide:
Step 1: अपना वर्कफ्लो सेव करें
सबसे पहले, अपने वर्कफ्लो एडिटर में जाएं।
ऊपर दाईं ओर Save बटन (डिस्क आइकन) पर क्लिक करें। आपका वर्कफ्लो सेव हो जाएगा ।
Step 2: Publish बटन ढूंढें
सेव करने के बाद, ठीक उसी जगह पर (ऊपर दाईं ओर) अब आपको Publish बटन दिखना चाहिए।
पुराने वर्जन में यहां "Inactive" का टॉगल होता था। अब यहां Publish लिखा होगा ।
Step 3: Publish पर क्लिक करें
Publish बटन पर क्लिक करें।
एक बार क्लिक करते ही आपका वर्कफ्लो "पब्लिश" हो जाता है, यानी वह अब एक्टिव हो गया है ।
अब यह आपके द्वारा सेट किए गए शेड्यूल (जैसे 8, 14, 19 बजे) पर अपने आप चलेगा ।
Step 4: (ऑप्शनल) अनपब्लिश कैसे करें?
अगर आपको वर्कफ्लो को बंद करना है, तो ऊपर दाईं ओर तीन डॉट्स पर क्लिक करें और Unpublish चुनें ।
⚠️ कुछ खास बातें और समस्याएं
1. "Publish" बटन नहीं दिख रहा?
हो सकता है आप n8n के बहुत पुराने वर्जन (1.x) का इस्तेमाल कर रहे हों, जहां Activate बटन था। अगर ऐसा है, तो वह बटन ऊपर दाईं ओर टॉगल स्विच के रूप में होगा ।
हो सकता है आपका वर्कफ्लो अभी तैयार न हो। Publish बटन तब तक सक्रिय नहीं होता जब तक आपके वर्कफ्लो में कोई ट्रिगर नोड (जैसे Schedule Trigger, Webhook) मौजूद न हो । ट्रिगर नोड के बिना वर्कफ्लो को एक्टिव नहीं किया जा सकता।
2. "Publish" और "Execute" में क्या अंतर है?
Execute Workflow बटन (जो नीचे बाईं ओर होता है) सिर्फ टेस्ट करने के लिए है। इसे दबाने से वर्कफ्लो एक बार चलता है, लेकिन यह लाइव नहीं होता ।
Publish करने के बाद ही वर्कफ्लो 24/7 लाइव रहता है और ट्रिगर होने पर अपने आप चलता है ।
3. कन्फ्यूजन से बचने के लिए:
n8n के कम्युनिटी फोरम में भी यही सवाल कई बार उठा है। लोगों ने सुझाव दिया है कि n8n को इस बटन का नाम बदलकर "Publish & Activate" कर देना चाहिए ताकि यह साफ हो जाए कि Publish करने का मतलब ही Activate करना है ।
🔥 आपके लिए विशेष टिप (आपके पिछले वर्कफ्लो के लिए)
अगर आपने मेरे बताए गए Schedule Trigger वाले वर्कफ्लो को बनाया है (जो 8, 14, 19 बजे चलता है), तो उसे Publish करना न भूलें। Publish होने के बाद ही वह रोज अपने आप चलेगा और Google Trends से टॉपिक लेकर AI से पोस्ट जेनरेट करेगा ।
क्या आपको किसी और मदद की जरूरत है?
Publish करने के बाद अगर वर्कफ्लो नहीं चल रहा, तो एक बार Execute Workflow दबाकर मैन्युअली टेस्ट करके देखें कि सब सही है या नहीं।
अपना वर्जन चेक करने के लिए n8n के अकाउंट सेटिंग्स में जाएं और नीचे की तरफ Version देखें।
बस इतना करना है। अब आपका वर्कफ्लो लाइव हो जाएगा और अपने आप चलता रहेगा! 🚀
अगर कोई और दिक्कत हो, तो बताइए।
🤖 This post was automatically generated based on trending topics. Published on {datetime.now().strftime('%B %d, %Y')}
""" # 6. डुप्लीकेट चेक करें post_hash = hashlib.md5(f"{topic}{post_data['content'][:100]}".encode()).hexdigest() async with AsyncSessionLocal() as session: # चेक करें कि यह पोस्ट पहले तो नहीं भेजी existing = await session.execute( select(SentPost).where(SentPost.post_hash == post_hash) ) if existing.scalar_one_or_none(): logger.info(f"⏭️ '{topic}' पहले भेजी जा चुकी है") continue # 7. ब्लॉग पर पब्लिश करें logger.info(f"📤 '{topic}' को ब्लॉग पर पब्लिश कर रहा हूं...") result = self.blogger_publisher.create_post( title=post_data['title'], content=html_content, labels=seo_tags, is_draft=False # True करें तो ड्राफ्ट में जाएगा ) if result: # 8. डेटाबेस में सेव करें new_post = SentPost( post_hash=post_hash, title=post_data['title'], link=result['url'], source_feed='auto_generated', topics=','.join(seo_tags[:5]) ) session.add(new_post) await session.commit() published_posts.append({ 'topic': topic, 'title': post_data['title'], 'url': result['url'], 'style': style }) logger.info(f"✅ पोस्ट पब्लिश: {result['url']}") # रेट लिमिट से बचने के लिए await asyncio.sleep(5) logger.info(f"🎉 कुल {len(published_posts)} नई पोस्ट पब्लिश हुईं") return published_posts async def schedule_auto_posts(self, posts_per_day=3): """ दिन में तय संख्या में पोस्ट शेड्यूल करता है """ times = ['09:00', '14:00', '19:00'] # सुबह, दोपहर, शाम # पोस्ट्स को दिनभर में बांटें posts_per_time = max(1, posts_per_day // len(times)) for i, time_str in enumerate(times): # इस टाइम के लिए पोस्ट जनरेट करें num = posts_per_time if i < len(times)-1 else posts_per_day - (posts_per_time * (len(times)-1)) if num > 0: await self.generate_and_publish(num) logger.info(f"⏰ {time_str} को {num} पोस्ट जनरेट की गईं") return True 3.5 Telegram कमांड्स (ऑटो ब्लॉग के लिए) bot.py में ये नए कमांड हैंडलर जोड़ें: async def generate_post_command(update: Update, context: CallbackContext): """कमांड: /generate [topic] - AI से ब्लॉग पोस्ट जनरेट करें""" try: args = context.args if not args: await update.message.reply_text("Usage: /generate your_topic_here") return topic = ' '.join(args) await update.message.reply_text(f"✍️ '{topic}' पर पोस्ट लिख रहा हूं...") generator = BlogPostGenerator() post = generator.generate_blog_post(topic) if post: await update.message.reply_text( f"✅ पोस्ट तैयार है!\n\n" f"*शीर्षक:* {post['title']}\n" f"*स्टाइल:* {post['style']}\n\n" f"कंटेंट प्रीव्यू:\n{post['content'][:500]}...", parse_mode='Markdown' ) else: await update.message.reply_text("❌ पोस्ट जनरेट करने में एरर आई।") except Exception as e: await update.message.reply_text(f"❌ एरर: {str(e)}") async def publish_trending_command(update: Update, context: CallbackContext): """कमांड: /publishtrending [count] - ट्रेंडिंग टॉपिक्स पर पोस्ट पब्लिश करें""" try: args = context.args count = 1 if args and args[0].isdigit(): count = min(int(args[0]), 5) # मैक्स 5 पोस्ट एक बार में await update.message.reply_text(f"🔍 ट्रेंडिंग टॉपिक्स ढूंढ रहा हूं...") auto_blogger = AutoBlogger() posts = await auto_blogger.generate_and_publish(num_posts=count) if posts: message = f"✅ {len(posts)} नई पोस्ट पब्लिश हुईं:\n\n" for post in posts: message += f"• [{post['title']}]({post['url']}) - *{post['style']}*\n" await update.message.reply_text(message, parse_mode='Markdown', disable_web_page_preview=True) else: await update.message.reply_text("❌ कोई पोस्ट पब्लिश नहीं हुई।") except Exception as e: await update.message.reply_text(f"❌ एरर: {str(e)}") async def auto_schedule_command(update: Update, context: CallbackContext): """कमांड: /autoschedule [posts_per_day] - ऑटो शेड्यूल शुरू करें""" try: args = context.args posts_per_day = 3 if args and args[0].isdigit(): posts_per_day = min(int(args[0]), 10) await update.message.reply_text(f"⏰ दिन में {posts_per_day} पोस्ट का शेड्यूल सेट हो रहा है...") # शेड्यूल जॉब सेट करें context.job_queue.run_daily( lambda ctx: asyncio.create_task(auto_blogger.generate_and_publish(posts_per_day // 3 + 1)), time=datetime.time(9, 0), days=tuple(range(7)), name="auto_blog_morning" ) context.job_queue.run_daily( lambda ctx: asyncio.create_task(auto_blogger.generate_and_publish(posts_per_day // 3)), time=datetime.time(14, 0), days=tuple(range(7)), name="auto_blog_afternoon" ) context.job_queue.run_daily( lambda ctx: asyncio.create_task(auto_blogger.generate_and_publish(posts_per_day // 3)), time=datetime.time(19, 0), days=tuple(range(7)), name="auto_blog_evening" ) await update.message.reply_text(f"✅ ऑटो शेड्यूल सेट हो गया! रोजाना {posts_per_day} पोस्ट पब्लिश होंगी।") except Exception as e: await update.message.reply_text(f"❌ एरर: {str(e)}") 🔧 सभी नए Environment Variables Railway पर ये सारे वेरिएबल्स डालने होंगे: Variable Example Description DATABASE_URL postgresql://postgres:pass@containers.railway.app:5432/railway Railway PostgreSQL URL CHANNEL_IDS -1001234567890,-1000987654321 कॉमा से अलग किए गए चैनल IDs ADMIN_IDS 123456789,987654321 एडमिन यूजर IDs OPENAI_API_KEY sk-1234567890abcdef OpenAI API key GOOGLE_API_KEY AIzaSyB1... Google Cloud API key GOOGLE_CLIENT_ID 123456-abc.apps.googleusercontent.com OAuth client ID GOOGLE_CLIENT_SECRET GOCSPX-... OAuth client secret GOOGLE_REFRESH_TOKEN 1//0gABC... OAuth refresh token BLOGGER_BLOG_ID 1234567890123456789 आपके Blogger ब्लॉग का ID 🎉 अब आपके पास क्या है? ✅ PostgreSQL डेटाबेस - पॉवरफुल और स्केलेबल ✅ मल्टीपल चैनल सपोर्ट - एक साथ कई Telegram चैनल्स में पोस्ट ✅ Google Trends इंटीग्रेशन - ट्रेंडिंग टॉपिक्स अपने आप मिलेंगे ✅ AI ब्लॉग जनरेशन - यूनिक स्टाइल में पोस्ट लिखेगा ✅ ऑटोमेटिक पब्लिशिंग - सीधे Blogger पर पोस्ट होगी ✅ स्मार्ट शेड्यूलिंग - तय समय पर अपने आप पोस्ट अगला स्टेप क्या है? मैं आपको बता सकता हूं: Google OAuth सेटअप कैसे करें (Refresh Token लेने के लिए) AI मॉडल को कस्टमाइज़ कैसे करें (आपकी खुद की राइटिंग स्टाइल सीखे) इमेज जनरेशन (DALL-E या Pixabay API से ऑटोमेटिक इमेज) अब हम सीखेंगे Google OAuth, AI Model Customization और Image Generation - ये तीनों एडवांस्ड फीचर्स आपके न्यूज़ ब्लॉग को अगले लेवल पर ले जाएंगे। मैं हर एक को स्टेप बाय स्टेप समझाऊंगा। 📱 Google OAuth सेटअप (Sign in with Google) Google OAuth आपको अपने ऐप/ब्लॉग में Google अकाउंट से लॉगिन की सुविधा देता है । स्टेप 1: Google Cloud Console में प्रोजेक्ट बनाएं Google Cloud Console पर जाएं "Select a project" ड्रॉपडाउन पर क्लिक करें → "New Project" चुनें प्रोजेक्ट का नाम दें (जैसे "न्यूज़वेव ब्लॉग") और "Create" पर क्लिक करें स्टेप 2: OAuth Consent Screen कॉन्फ़िगर करें अपने प्रोजेक्ट डैशबोर्ड में जाएं बाएं साइडबार में "APIs & Services" → "OAuth Consent Screen" पर क्लिक करें "Get Started" बटन दबाएं User Type चुनें: External: किसी भी Google अकाउंट वाला यूजर लॉगिन कर सकता है (ज्यादातर केस में यही चुनें) Internal: सिर्फ आपके organization के लोग (G Suite/Workspace) "Create" पर क्लिक करें स्टेप 3: ऐप की जानकारी भरें App name: "न्यूज़वेव ब्लॉग" (या आपका ऐप नाम) User support email: अपना ईमेल चुनें Developer contact information: अपना ईमेल डालें "Save and Continue" पर क्लिक करें स्टेप 4: Scopes (परमिशन) सेट करें "Add or Remove Scopes" पर क्लिक करें बेसिक जानकारी के लिए ये scopes चुनें : .../auth/userinfo.email (यूजर का ईमेल देखें) .../auth/userinfo.profile (यूजर की प्रोफाइल देखें) openid (OpenID Connect के लिए) "Update" → "Save and Continue" पर क्लिक करें स्टेप 5: टेस्ट यूजर्स जोड़ें अगर आपने External चुना है, तो "Add Users" से अपना ईमेल डालें (Development के लिए) "Save and Continue" पर क्लिक करें स्टेप 6: OAuth Client ID बनाएं बाएं साइडबार में "Credentials" पर क्लिक करें "Create Credentials" → "OAuth Client ID" चुनें Application Type: "Web application" चुनें Name दें: "न्यूज़वेव वेब क्लाइंट" Authorized JavaScript Origins: अपनी वेबसाइट का URL डालें (जैसे https://newswaveblog24.com या http://localhost:3000 डेवलपमेंट के लिए) Authorized Redirect URIs: यह URL Google यूजर को वापस रीडायरेक्ट करेगा। डालें: https://newswaveblog24.com/auth/callback (प्रोडक्शन) http://localhost:3000/auth/callback (डेवलपमेंट) "Create" पर क्लिक करें स्टेप 7: Client ID और Secret सेव करें Client ID और Client Secret कॉपी करके सेव कर लें Client Secret को कभी किसी के साथ शेयर न करें और न ही फ्रंटएंड कोड में डालें स्टेप 8: Python में Google OAuth इंप्लीमेंट करें # requirements.txt में जोड़ें # pip install google-auth google-auth-oauthlib google-auth-httplib2 flask requests import os import flask import google.auth from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import Flow from googleapiclient.discovery import build app = flask.Flask(__name__) app.secret_key = 'your-secret-key-here' # Google OAuth कॉन्फ़िगरेशन CLIENT_ID = os.environ.get('GOOGLE_CLIENT_ID') CLIENT_SECRET = os.environ.get('GOOGLE_CLIENT_SECRET') REDIRECT_URI = os.environ.get('REDIRECT_URI', 'http://localhost:8080/callback') # SCOPES - किन चीजों की परमिशन चाहिए SCOPES = ['openid', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile'] @app.route('/login') def login(): """यूजर को Google लॉगिन पर रीडायरेक्ट करें""" flow = Flow.from_client_config( { "web": { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uris": [REDIRECT_URI], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token" } }, scopes=SCOPES ) flow.redirect_uri = REDIRECT_URI authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true', prompt='consent' ) # State को session में सेव करें flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/callback') def callback(): """Google से वापस आने पर यह फंक्शन कॉल होगा""" state = flask.session['state'] flow = Flow.from_client_config( { "web": { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uris": [REDIRECT_URI], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token" } }, scopes=SCOPES, state=state ) flow.redirect_uri = REDIRECT_URI # ऑथोराइजेशन रिस्पॉन्स प्रोसेस करें flow.fetch_token(authorization_response=flask.request.url) # क्रेडेंशियल्स सेव करें credentials = flow.credentials # यूजर की जानकारी लें user_info_service = build('oauth2', 'v2', credentials=credentials) user_info = user_info_service.userinfo().get().execute() print(f"यूजर लॉगिन हुआ: {user_info['name']} ({user_info['email']})") return f"नमस्ते {user_info['name']}! आप सफलतापूर्वक लॉगिन हुए।" if __name__ == '__main__': app.run(host='localhost', port=8080, debug=True) स्टेप 9: Railway पर Environment Variables सेट करें Railway डैशबोर्ड में Variables टैब पर जाकर ये डालें: Variable Value GOOGLE_CLIENT_ID आपका Client ID GOOGLE_CLIENT_SECRET आपका Client Secret REDIRECT_URI https://your-app.railway.app/callback 🤖 AI Model को कैसे कस्टमाइज़ करें AI मॉडल को कस्टमाइज़ करने के दो मुख्य तरीके हैं : तरीका 1: फाइन-ट्यूनिंग (Fine-tuning) इसमें मौजूदा मॉडल को अपने खास डेटा पर और ट्रेन किया जाता है। इससे मॉडल आपके काम के लिए बेहतर बन जाता है । कब यूज करें: जब आप चाहते हैं कि मॉडल आपके स्टाइल में लिखे, खास टर्मिनोलॉजी समझे। तरीका 2: RAG (Retrieval Augmented Generation) इसमें मॉडल को बिना ट्रेन किए, उसे आपके डेटा से जोड़ दिया जाता है। जब भी कोई सवाल पूछा जाता है, मॉडल पहले आपके डेटा में सर्च करता है, फिर उसी के आधार पर जवाब देता है । कब यूज करें: जब आपके पास बहुत सारा डेटा है (जैसे खबरों का आर्काइव) और चाहते हैं कि मॉडल उसी से जवाब दे। प्रैक्टिकल: Gemma 3 270M को फाइन-ट्यून करें Google का Gemma 3 270M एक छोटा और पावरफुल मॉडल है जिसे आप अपने लैपटॉप पर ही ट्रेन कर सकते हैं । स्टेप 1: Google Colab में नोटबुक खोलें इस लिंक पर क्लिक करें: Gemma Fine-tuning Colab (आपको असल लिंक के लिए Google Blog देखना होगा) स्टेप 2: डिपेंडेंसीज इंस्टॉल करें python !pip install transformers datasets accelerate peft bitsandbytes स्टेप 3: मॉडल लोड करें python from transformers import AutoTokenizer, AutoModelForCausalLM, TrainingArguments, Trainer from peft import LoraConfig, get_peft_model, TaskType import torch model_name = "google/gemma-3-270m" tokenizer = AutoTokenizer.from_pretrained(model_name) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.bfloat16, device_map="auto" ) स्टेप 4: अपना डेटा तैयार करें मान लीजिए आप चाहते हैं कि मॉडल आपके ब्लॉग के अंदाज में लिखे: python # आपके ब्लॉग के लेखों का डेटा training_data = [ { "instruction": "आज की ताजा खबर लिखें", "response": "नमस्ते दोस्तों! आज की बड़ी खबर यह है कि उत्तराखंड में मौसम विभाग ने भारी बारिश का अलर्ट जारी किया है। आप सभी सतर्क रहें और अनावश्यक यात्रा से बचें।" }, { "instruction": "खेल समाचार बताएं", "response": "क्रिकेट फैंस के लिए खुशखबरी! भारत ने आज मैच जीतकर सीरीज पर कब्जा कर लिया। विराट कोहली ने शानदार शतक लगाया।" }, # ... और भी डेटा ] def format_data(example): return tokenizer( f"### Instruction: {example['instruction']}\n### Response: {example['response']}", truncation=True, padding="max_length", max_length=512 ) # डेटा को टोकनाइज़ करें tokenized_data = [format_data(item) for item in training_data] स्टेप 5: LoRA कॉन्फ़िगरेशन (हल्की ट्रेनिंग के लिए) python lora_config = LoraConfig( task_type=TaskType.CAUSAL_LM, r=8, # रैंक lora_alpha=32, lora_dropout=0.1, target_modules=["q_proj", "v_proj"] ) model = get_peft_model(model, lora_config) model.print_trainable_parameters() # देखें कितने पैरामीटर ट्रेन होंगे स्टेप 6: ट्रेनिंग python training_args = TrainingArguments( output_dir="./gemma-finetuned", per_device_train_batch_size=1, gradient_accumulation_steps=4, num_train_epochs=3, learning_rate=2e-4, fp16=True, save_steps=50, logging_steps=10, ) trainer = Trainer( model=model, args=training_args, train_dataset=tokenized_data, ) trainer.train() model.save_pretrained("./my-custom-gemma") स्टेप 7: मॉडल को क्वांटाइज़ करें (हल्का बनाएं) python # मॉडल को 4-bit में बदलें ताकि साइज 1GB से कम हो जाए from transformers import BitsAndBytesConfig quantization_config = BitsAndBytesConfig( load_in_4bit=True, bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True, ) स्टेप 8: अपने बॉट में यूज करें python def generate_blog_post(topic): prompt = f"### Instruction: {topic} पर एक ब्लॉग पोस्ट लिखें\n### Response:" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_length=500, temperature=0.7) return tokenizer.decode(outputs[0], skip_special_tokens=True) 🎨 इमेज जनरेशन (AI से तस्वीरें बनाएं) अब हम सीखेंगे कि टेक्स्ट से इमेज कैसे जनरेट करें । विकल्प 1: Stability AI (Stable Diffusion) - फ्री/ओपन सोर्स स्टेप 1: Stability AI API Key लें Stability AI Platform पर जाएं अकाउंट बनाएं और API Key जेनरेट करें स्टेप 2: Python कोड python # pip install requests Pillow import requests import base64 import os from PIL import Image from io import BytesIO API_KEY = "your-stability-api-key" API_URL = "https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image" def generate_image(prompt, negative_prompt="", width=1024, height=1024): """टेक्स्ट से इमेज जनरेट करें""" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } payload = { "text_prompts": [{"text": prompt}], "cfg_scale": 7, "height": height, "width": width, "samples": 1, "steps": 30, } if negative_prompt: payload["text_prompts"].append({"text": negative_prompt, "weight": -1}) response = requests.post(API_URL, headers=headers, json=payload) if response.status_code == 200: data = response.json() for i, image_data in enumerate(data["artifacts"]): image_bytes = base64.b64decode(image_data["base64"]) image = Image.open(BytesIO(image_bytes)) filename = f"generated_image_{i}.png" image.save(filename) print(f"✅ इमेज सेव हुई: {filename}") return filename else: print(f"❌ एरर: {response.status_code} - {response.text}") return None # उदाहरण: न्यूज के लिए इमेज बनाएं prompt = "उत्तराखंड के पहाड़ों में बारिश, समाचार पत्र शैली में, फोटोरियलिस्टिक" img = generate_image(prompt) विकल्प 2: OpenAI DALL-E 3 (पेड, बेहतर क्वालिटी) स्टेप 1: OpenAI API Key सेट करें python # pip install openai import openai from openai import OpenAI client = OpenAI(api_key="your-openai-api-key") स्टेप 2: DALL-E 3 से इमेज जनरेट करें python def generate_image_dalle(prompt, size="1024x1024", quality="standard"): """ DALL-E 3 से इमेज जनरेट करें size: 1024x1024, 1024x1792, 1792x1024 quality: standard, hd """ response = client.images.generate( model="dall-e-3", prompt=prompt, size=size, quality=quality, n=1, ) image_url = response.data[0].url print(f"✅ इमेज URL: {image_url}") # इमेज डाउनलोड करें img_response = requests.get(image_url) with open("dalle_image.png", "wb") as f: f.write(img_response.content) return "dalle_image.png" # न्यूज के लिए इमेज prompt = "A photorealistic news report scene in Uttarakhand, India, with mountains and rain, professional photography, 4k" generate_image_dalle(prompt, quality="hd") विकल्प 3: Azure OpenAI (एंटरप्राइज़) python import requests import base64 import json # Azure सेटिंग्स endpoint = "https://your-resource.openai.azure.com" api_key = "your-azure-api-key" deployment = "dall-e-3" # आपका डिप्लॉयमेंट नाम def generate_image_azure(prompt): url = f"{endpoint}/openai/deployments/{deployment}/images/generations?api-version=2025-04-01-preview" headers = { "api-key": api_key, "Content-Type": "application/json" } payload = { "prompt": prompt, "size": "1024x1024", "n": 1, "quality": "high" } response = requests.post(url, headers=headers, json=payload) if response.status_code == 200: data = response.json() # base64 में इमेज आती है image_data = base64.b64decode(data["data"][0]["b64_json"]) with open("azure_image.png", "wb") as f: f.write(image_data) return "azure_image.png" else: print(f"❌ एरर: {response.text}") return None बोनस: इमेज एडिटिंग (Edit Image) किसी मौजूदा इमेज में बदलाव करें : python def edit_image(input_image_path, prompt, mask_path=None): """इमेज में एडिट करें (DALL-E 2 के लिए)""" with open(input_image_path, "rb") as img_file: if mask_path: with open(mask_path, "rb") as mask_file: response = client.images.create_edit( image=img_file, mask=mask_file, prompt=prompt, n=1, size="1024x1024" ) else: response = client.images.create_variation( image=img_file, n=1, size="1024x1024" ) return response.data[0].url 🔥 सबको एक साथ जोड़ना: न्यूज़ ब्लॉग के लिए AI सिस्टम अब हम सबको मिलाकर एक पूरा सिस्टम बनाएंगे: python import feedparser import schedule import time from datetime import datetime class AI_News_Blog: def __init__(self): self.gemma_model = self.load_gemma_model() self.telegram_bot = TelegramBot() self.google_oauth = GoogleOAuth() def load_gemma_model(self): """अपने फाइन-ट्यून किए गए मॉडल को लोड करें""" # यहां आपका फाइन-ट्यून किया हुआ मॉडल लोड होगा pass def fetch_google_trends(self): """Google Trends से टॉपिक्स लें""" # Google Trends API से डेटा लें topics = ["उत्तराखंड समाचार", "भारत राजनीति", "खेल"] return topics def generate_blog_post(self, topic): """AI से ब्लॉग पोस्ट लिखें""" prompt = f""" आप एक पेशेवर पत्रकार हैं। इस टॉपिक पर एक आकर्षक ब्लॉग पोस्ट लिखें: {topic} शैली: हिंदी में, आम बोलचाल की भाषा, पाठकों से जुड़ाव फॉर्मेट: शीर्षक, परिचय, मुख्य बिंदु, निष्कर्ष लंबाई: 500 शब्द """ post = self.gemma_model.generate(prompt) return post def generate_post_image(self, topic): """ब्लॉग पोस्ट के लिए AI से इमेज बनाएं""" prompt = f"{topic} से जुड़ी एक पेशेवर समाचार तस्वीर, फोटोरियलिस्टिक, 4k क्वालिटी" image_path = generate_image_dalle(prompt) return image_path def publish_to_blogger(self, title, content, image_path): """ब्लॉगर पर पोस्ट करें (API के जरिए)""" # Blogger API से पोस्ट करें pass def run_daily(self): """रोजाना का शेड्यूल""" print(f"🔄 {datetime.now()}: नया कंटेंट जेनरेट हो रहा है...") # Google Trends से टॉपिक्स लें topics = self.fetch_google_trends() for topic in topics[:3]: # टॉप 3 टॉपिक्स पर पोस्ट करें print(f"📝 टॉपिक: {topic}") # ब्लॉग पोस्ट लिखें post = self.generate_blog_post(topic) # इमेज बनाएं image = self.generate_post_image(topic) # ब्लॉगर पर पब्लिश करें self.publish_to_blogger(topic, post, image) # Telegram पर भेजें self.telegram_bot.send_message(f"नई पोस्ट: {topic}") time.sleep(10) # थोड़ा रुकें print("✅ आज का काम पूरा हुआ!") # शेड्यूल सेट करें bot = AI_News_Blog() schedule.every().day.at("08:00").do(bot.run_daily) schedule.every().day.at("14:00").do(bot.run_daily) schedule.every().day.at("19:00").do(bot.run_daily) while True: schedule.run_pending() time.sleep(60) 📊 Railway पर एनवायरनमेंट वेरिएबल्स (सभी के लिए) अब अपने Railway प्रोजेक्ट में ये सब वेरिएबल्स डालें: वेरिएबल कहां से मिलेगा GOOGLE_CLIENT_ID Google Cloud Console GOOGLE_CLIENT_SECRET Google Cloud Console OPENAI_API_KEY OpenAI Platform STABILITY_API_KEY Stability AI Platform AZURE_OPENAI_KEY Azure Portal AZURE_ENDPOINT Azure Portal BLOGGER_API_KEY Google Cloud Console (Blogger API) 🎉 अब आपके पास क्या है? ✅ Google OAuth - यूजर्स Google से लॉगिन कर सकते हैं ✅ Custom AI Model - आपके स्टाइल में लिखने वाला AI ✅ Image Generation - खुद इमेज बनाने की क्षमता ✅ Google Trends + AI - ट्रेंडिंग टॉपिक्स पर ऑटोमेटिक पोस्ट ✅ पूरा ऑटोमेशन - बिना कुछ किए रोज नई पोस्ट मैं आपको सब कुछ एक साथ जोड़कर एक रेडी-टू-यूज कोड दे रहा हूँ। यह एक पूरा सिस्टम है जो: ✅ Google Trends से टॉपिक लेगा ✅ AI से यूनिक ब्लॉग पोस्ट लिखेगा (आपके स्टाइल में) ✅ AI से इमेज जनरेट करेगा ✅ Blogger पर ऑटो-पोस्ट करेगा ✅ Telegram बॉट से मल्टीपल चैनल्स में भेजेगा ✅ PostgreSQL डेटाबेस में सब सेव करेगा ✅ Google OAuth से यूजर लॉगिन करेगा 🚀 पूरा सिस्टम: एक फाइल में सब कुछ फाइल स्ट्रक्चर text newswave-ultimate-bot/ ├── main.py # मुख्य एप्लीकेशन ├── requirements.txt # डिपेंडेंसीज ├── .env # Environment Variables (लोकल के लिए) ├── Procfile # Railway के लिए ├── railway.json # Railway कॉन्फिग └── templates/ # HTML टेम्प्लेट └── login.html # OAuth लॉगिन पेज फाइल 1: requirements.txt txt # Core python-telegram-bot==20.7 feedparser==6.0.10 requests==2.31.0 schedule==1.2.0 python-dotenv==1.0.0 psycopg2-binary==2.9.9 sqlalchemy==2.0.23 # Google APIs google-auth==2.23.4 google-auth-oauthlib==1.1.0 google-auth-httplib2==0.1.1 google-api-python-client==2.108.0 # AI & ML transformers==4.36.2 torch==2.1.2 accelerate==0.25.0 peft==0.7.1 bitsandbytes==0.41.3 openai==1.7.2 Pillow==10.1.0 # Web Framework flask==3.0.0 flask-sqlalchemy==3.1.1 flask-login==0.6.2 flask-oauthlib==0.9.6 # Utils beautifulsoup4==4.12.2 lxml==4.9.3 pandas==2.1.4 numpy==1.26.3 फाइल 2: .env (लोकल के लिए) env # Telegram BOT_TOKEN=your_telegram_bot_token # Database DATABASE_URL=postgresql://username:password@localhost:5432/newswave_db # Google OAuth GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret GOOGLE_REDIRECT_URI=http://localhost:5000/callback # Blogger API BLOGGER_API_KEY=your_blogger_api_key BLOG_ID=your_blog_id # OpenAI (for DALL-E) OPENAI_API_KEY=your_openai_api_key # Stability AI STABILITY_API_KEY=your_stability_api_key # RSS Feeds (comma separated) RSS_FEEDS=https://newswaveblog24.blogspot.com/feeds/posts/default,https://trends.google.com/trends/trendingsearches/daily/rss # Telegram Channels (comma separated) TELEGRAM_CHANNELS=-1001234567890,-1009876543210 # Schedule Times (24h format, comma separated) SCHEDULE_TIMES=08:00,14:00,19:00 # AI Settings ENABLE_TRANSLATION=True TARGET_LANGUAGE=hi MAX_POSTS_PER_DAY=5 फाइल 3: Procfile text web: gunicorn main:app worker: python main.py --worker फाइल 4: railway.json json { "$schema": "https://railway.app/railway.schema.json", "build": { "builder": "NIXPACKS" }, "deploy": { "numReplicas": 1, "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 10, "healthcheckPath": "/health", "healthcheckTimeout": 100 } } फाइल 5: main.py (पूरा कोड) python #!/usr/bin/env python # -*- coding: utf-8 -*- """ न्यूज़वेव अल्टीमेट बॉट - AI न्यूज़ जेनरेशन और डिस्ट्रीब्यूशन सिस्टम फीचर्स: Google Trends, AI Blog Post, AI Image, Blogger API, Multiple Telegram Channels, PostgreSQL, Google OAuth """ import os import sys import logging import schedule import time import json import hashlib import html import re import requests import feedparser from datetime import datetime, timedelta from threading import Thread from dotenv import load_dotenv # Flask Web App from flask import Flask, render_template, request, redirect, url_for, session, jsonify from flask_sqlalchemy import SQLAlchemy from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user # Google OAuth import google.auth from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import Flow from googleapiclient.discovery import build # Telegram from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import Updater, CommandHandler, CallbackQueryHandler, CallbackContext # AI/ML import torch from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline from PIL import Image import openai import base64 from io import BytesIO # Database from sqlalchemy import create_engine, Column, Integer, String, DateTime, Boolean, Text from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker # Load environment variables load_dotenv() # ============================================ # कॉन्फ़िगरेशन # ============================================ class Config: # App SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key-change-in-production') DEBUG = os.environ.get('DEBUG', 'False').lower() == 'true' # Database SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///newswave.db') SQLALCHEMY_TRACK_MODIFICATIONS = False # Google OAuth GOOGLE_CLIENT_ID = os.environ.get('GOOGLE_CLIENT_ID') GOOGLE_CLIENT_SECRET = os.environ.get('GOOGLE_CLIENT_SECRET') GOOGLE_REDIRECT_URI = os.environ.get('GOOGLE_REDIRECT_URI', 'http://localhost:5000/callback') # Telegram BOT_TOKEN = os.environ.get('BOT_TOKEN') TELEGRAM_CHANNELS = [ch.strip() for ch in os.environ.get('TELEGRAM_CHANNELS', '').split(',') if ch.strip()] # RSS Feeds RSS_FEEDS = [feed.strip() for feed in os.environ.get('RSS_FEEDS', '').split(',') if feed.strip()] # Blogger API BLOGGER_API_KEY = os.environ.get('BLOGGER_API_KEY') BLOG_ID = os.environ.get('BLOG_ID') # OpenAI OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY') # Stability AI STABILITY_API_KEY = os.environ.get('STABILITY_API_KEY') # Schedule SCHEDULE_TIMES = [t.strip() for t in os.environ.get('SCHEDULE_TIMES', '08:00,14:00,19:00').split(',')] # AI Settings ENABLE_TRANSLATION = os.environ.get('ENABLE_TRANSLATION', 'True').lower() == 'true' TARGET_LANGUAGE = os.environ.get('TARGET_LANGUAGE', 'hi') MAX_POSTS_PER_DAY = int(os.environ.get('MAX_POSTS_PER_DAY', 5)) config = Config() # ============================================ # लॉगिंग सेटअप # ============================================ logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('newswave.log'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) # ============================================ # Flask App Setup # ============================================ app = Flask(__name__) app.config.from_object(Config) app.secret_key = config.SECRET_KEY # Database Setup db = SQLAlchemy(app) # ============================================ # Database Models # ============================================ class User(UserMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) google_id = db.Column(db.String(100), unique=True) email = db.Column(db.String(100), unique=True) name = db.Column(db.String(100)) picture = db.Column(db.String(500)) created_at = db.Column(db.DateTime, default=datetime.utcnow) last_login = db.Column(db.DateTime) is_admin = db.Column(db.Boolean, default=False) class BlogPost(db.Model): __tablename__ = 'blog_posts' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(500)) content = db.Column(db.Text) summary = db.Column(db.Text) image_url = db.Column(db.String(500)) source_topic = db.Column(db.String(200)) source_url = db.Column(db.String(500)) blogger_post_id = db.Column(db.String(100)) published_at = db.Column(db.DateTime) created_at = db.Column(db.DateTime, default=datetime.utcnow) is_published = db.Column(db.Boolean, default=False) class TelegramMessage(db.Model): __tablename__ = 'telegram_messages' id = db.Column(db.Integer, primary_key=True) post_id = db.Column(db.Integer, db.ForeignKey('blog_posts.id')) channel_id = db.Column(db.String(100)) message_id = db.Column(db.String(100)) sent_at = db.Column(db.DateTime, default=datetime.utcnow) status = db.Column(db.String(50)) class TrendingTopic(db.Model): __tablename__ = 'trending_topics' id = db.Column(db.Integer, primary_key=True) topic = db.Column(db.String(500)) source = db.Column(db.String(100)) # google, rss, manual score = db.Column(db.Integer) used = db.Column(db.Boolean, default=False) created_at = db.Column(db.DateTime, default=datetime.utcnow) used_at = db.Column(db.DateTime) # Create tables with app.app_context(): db.create_all() logger.info("✅ Database tables created") # ============================================ # Google OAuth Setup # ============================================ class GoogleOAuth: def __init__(self): self.client_id = config.GOOGLE_CLIENT_ID self.client_secret = config.GOOGLE_CLIENT_SECRET self.redirect_uri = config.GOOGLE_REDIRECT_URI self.scopes = [ 'openid', 'https://www.googleapis.com/auth/userinfo.email', 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/blogger' # Blogger API access ] def get_flow(self, state=None): """OAuth2 Flow object बनाएं""" flow = Flow.from_client_config( { "web": { "client_id": self.client_id, "client_secret": self.client_secret, "redirect_uris": [self.redirect_uri], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token" } }, scopes=self.scopes, state=state ) flow.redirect_uri = self.redirect_uri return flow def get_auth_url(self): """Google login URL जनरेट करें""" flow = self.get_flow() auth_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true', prompt='consent' ) session['state'] = state return auth_url def handle_callback(self, url): """Google callback handle करें""" state = session.get('state') flow = self.get_flow(state) flow.fetch_token(authorization_response=url) credentials = flow.credentials # यूजर की जानकारी लें user_info_service = build('oauth2', 'v2', credentials=credentials) user_info = user_info_service.userinfo().get().execute() # Blogger API के लिए credentials सेव करें session['google_credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes } return user_info # Initialize Google OAuth google_oauth = GoogleOAuth() # ============================================ # Routes for Web Interface # ============================================ @app.route('/') def index(): """Home page""" return render_template('index.html') @app.route('/login') def login(): """Google OAuth login page""" auth_url = google_oauth.get_auth_url() return redirect(auth_url) @app.route('/callback') def callback(): """Google OAuth callback""" try: user_info = google_oauth.handle_callback(request.url) # यूजर को database में save करें user = User.query.filter_by(google_id=user_info['id']).first() if not user: user = User( google_id=user_info['id'], email=user_info['email'], name=user_info['name'], picture=user_info.get('picture', ''), last_login=datetime.utcnow() ) db.session.add(user) else: user.last_login = datetime.utcnow() user.name = user_info['name'] user.picture = user_info.get('picture', '') db.session.commit() # Session में user id save करें session['user_id'] = user.id return redirect(url_for('dashboard')) except Exception as e: logger.error(f"OAuth callback error: {e}") return f"Error: {e}", 400 @app.route('/dashboard') def dashboard(): """User dashboard""" if 'user_id' not in session: return redirect(url_for('login')) user = User.query.get(session['user_id']) if not user: return redirect(url_for('login')) # Recent posts recent_posts = BlogPost.query.order_by(BlogPost.created_at.desc()).limit(10).all() # Stats total_posts = BlogPost.query.count() total_trends = TrendingTopic.query.count() total_telegram = TelegramMessage.query.count() return render_template('dashboard.html', user=user, recent_posts=recent_posts, total_posts=total_posts, total_trends=total_trends, total_telegram=total_telegram) @app.route('/logout') def logout(): """Logout""" session.clear() return redirect(url_for('index')) @app.route('/api/posts') def get_posts(): """API endpoint for posts""" posts = BlogPost.query.order_by(BlogPost.created_at.desc()).limit(50).all() return jsonify([{ 'id': p.id, 'title': p.title, 'summary': p.summary, 'image_url': p.image_url, 'published_at': p.published_at.isoformat() if p.published_at else None, 'source_topic': p.source_topic } for p in posts]) @app.route('/health') def health(): """Health check for Railway""" return jsonify({ 'status': 'healthy', 'timestamp': datetime.utcnow().isoformat(), 'database': 'connected' }) # ============================================ # AI Blog Generator # ============================================ class AIBlogGenerator: def __init__(self): self.model = None self.tokenizer = None self.load_model() def load_model(self): """Gemma 3 270M model load करें""" try: logger.info("Loading AI model...") self.tokenizer = AutoTokenizer.from_pretrained("google/gemma-3-270m") self.model = AutoModelForCausalLM.from_pretrained( "google/gemma-3-270m", torch_dtype=torch.float16, device_map="auto" ) logger.info("✅ AI model loaded successfully") except Exception as e: logger.error(f"Failed to load AI model: {e}") self.model = None def generate_blog_post(self, topic, style="news"): """AI से ब्लॉग पोस्ट जनरेट करें""" if not self.model: return self.generate_fallback(topic) prompt = f"""आप एक पेशेवर हिंदी पत्रकार हैं। नीचे दिए गए टॉपिक पर एक आकर्षक समाचार लेख लिखें: टॉपिक: {topic} लेख की शैली: - हिंदी में लिखें - आम बोलचाल की भाषा - पाठकों से सीधा संवाद - 500 शब्दों में - शीर्षक आकर्षक हो - परिचय में मुख्य बात - मध्य में विस्तार - निष्कर्ष में सारांश लेख: """ inputs = self.tokenizer(prompt, return_tensors="pt").to(self.model.device) outputs = self.model.generate( **inputs, max_length=800, temperature=0.7, do_sample=True, top_p=0.9, repetition_penalty=1.1 ) result = self.tokenizer.decode(outputs[0], skip_special_tokens=True) # Extract just the generated part if prompt in result: result = result[len(prompt):] return result def generate_fallback(self, topic): """अगर AI model fail हो जाए तो fallback template""" return f"""📰 {topic}: आज की बड़ी खबर नमस्ते दोस्तों! आज हम बात करेंगे {topic} के बारे में। यह विषय इन दिनों काफी चर्चा में है। {self._get_dummy_content(topic)} आपको यह जानकारी कैसी लगी? कमेंट में जरूर बताएं। ऐसी ही ताजा खबरों के लिए जुड़े रहें हमारे साथ! धन्यवाद! 🙏""" def _get_dummy_content(self, topic): return f"{topic} से जुड़ी कई अहम जानकारियां सामने आ रही हैं। विशेषज्ञों का मानना है कि आने वाले दिनों में इस क्षेत्र में बड़े बदलाव देखने को मिल सकते हैं। वहीं आम जनता को इससे काफी उम्मीदें हैं।" # ============================================ # AI Image Generator # ============================================ class AIImageGenerator: def __init__(self): self.openai_client = None if config.OPENAI_API_KEY: self.openai_client = openai.OpenAI(api_key=config.OPENAI_API_KEY) def generate_image(self, topic, style="photorealistic"): """टॉपिक के लिए AI इमेज जनरेट करें""" # Try DALL-E first if self.openai_client: return self.generate_dalle_image(topic, style) # Fallback to Stability AI if config.STABILITY_API_KEY: return self.generate_stability_image(topic, style) # If nothing works, return placeholder return "https://via.placeholder.com/1024x1024?text=" + topic.replace(" ", "+") def generate_dalle_image(self, topic, style): """DALL-E 3 से इमेज जनरेट करें""" try: prompt = f"{topic}, {style} news image, professional photography, 4k, high quality, Indian context" response = self.openai_client.images.generate( model="dall-e-3", prompt=prompt, size="1024x1024", quality="standard", n=1 ) return response.data[0].url except Exception as e: logger.error(f"DALL-E generation error: {e}") return None def generate_stability_image(self, topic, style): """Stability AI से इमेज जनरेट करें""" try: url = "https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image" headers = { "Authorization": f"Bearer {config.STABILITY_API_KEY}", "Content-Type": "application/json", } payload = { "text_prompts": [{"text": f"{topic}, {style}, news photography, India"}], "cfg_scale": 7, "height": 1024, "width": 1024, "samples": 1, "steps": 30, } response = requests.post(url, headers=headers, json=payload) if response.status_code == 200: data = response.json() image_data = base64.b64decode(data["artifacts"][0]["base64"]) # Save temporarily filename = f"temp_{int(time.time())}.png" with open(filename, "wb") as f: f.write(image_data) return filename else: return None except Exception as e: logger.error(f"Stability AI error: {e}") return None # ============================================ # Blogger API # ============================================ class BloggerAPI: def __init__(self, credentials=None): self.api_key = config.BLOGGER_API_KEY self.blog_id = config.BLOG_ID self.credentials = credentials def create_post(self, title, content, labels=None, image_url=None): """Blogger पर नई पोस्ट बनाएं""" # HTML content बनाएं html_content = f"""
{self._format_content(content, image_url)}
"""
# Blogger API endpoint
url = f"https://www.googleapis.com/blogger/v3/blogs/{self.blog_id}/posts/"
if self.credentials:
# OAuth authentication
headers = {
"Authorization": f"Bearer {self.credentials['token']}",
"Content-Type": "application/json"
}
else:
# API Key authentication
url += f"?key={self.api_key}"
headers = {"Content-Type": "application/json"}
data = {
"title": title,
"content": html_content,
"labels": labels or ["AI Generated", "News"],
"published": datetime.utcnow().isoformat() + "Z"
}
try:
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
post_data = response.json()
return post_data.get('id')
else:
logger.error(f"Blogger API error: {response.text}")
return None
except Exception as e:
logger.error(f"Blogger API exception: {e}")
return None
def _format_content(self, content, image_url):
"""Content को HTML में फॉर्मेट करें"""
formatted = f"{content}
" if image_url: formatted = f'न्यूज़वेव AI न्यूज़ सिस्टम
AI से जेनरेट की गई ताजा खबरें पढ़ें और अपने ब्लॉग पर ऑटो-पोस्ट करें।
Google से लॉगिन करें """ @app.route('/templates/dashboard.html') def serve_dashboard(): return """न्यूज़वेव डैशबोर्ड
लॉगआउटकुल पोस्ट
{{ total_posts }}
ट्रेंडिंग टॉपिक्स
{{ total_trends }}
टेलीग्राम मैसेज
{{ total_telegram }}
हाल की पोस्ट्स
""" # ============================================ # Main Entry Point # ============================================ def start_telegram_bot(): """Telegram bot को अलग thread में start करें""" updater = Updater(config.BOT_TOKEN, use_context=True) # Setup handlers bot_handler = TelegramBotHandler(config.BOT_TOKEN) bot_handler.setup_handlers(updater) # Start bot updater.start_polling() logger.info("✅ Telegram bot started") updater.idle() def main(): """Main function""" logger.info("🚀 न्यूज़वेव अल्टीमेट बॉट शुरू हो रहा है...") # Check if running in worker mode if len(sys.argv) > 1 and sys.argv[1] == '--worker': # Worker mode - run scheduler scheduler = NewsScheduler() scheduler.run_scheduler() else: # Web mode - run Flask app and Telegram bot in threads from threading import Thread # Start Telegram bot in separate thread telegram_thread = Thread(target=start_telegram_bot) telegram_thread.daemon = True telegram_thread.start() # Start scheduler in separate thread scheduler_thread = Thread(target=lambda: NewsScheduler().run_scheduler()) scheduler_thread.daemon = True scheduler_thread.start() # Run Flask app port = int(os.environ.get('PORT', 5000)) app.run(host='0.0.0.0', port=port, debug=config.DEBUG) if __name__ == '__main__': main() 🚀 Railway पर डिप्लॉय करने के लिए स्टेप 1: GitHub पर अपलोड करें bash # नया रिपॉजिटरी बनाएं git init git add . git commit -m "न्यूज़वेव अल्टीमेट बॉट" git branch -M main git remote add origin https://github.com/yourusername/newswave-ultimate-bot.git git push -u origin main स्टेप 2: Railway पर नया प्रोजेक्ट बनाएं Railway.com पर लॉगिन करें "New Project" → "Deploy from GitHub repo" चुनें अपना रिपॉजिटरी चुनें स्टेप 3: PostgreSQL Database Add करें Railway डैशबोर्ड में: "New" → "Database" → "PostgreSQL" चुनें Railway अपने आप DATABASE_URL वेरिएबल सेट कर देगा स्टेप 4: Environment Variables सेट करें Railway के Variables टैब में ये सब डालें: Variable Value Where to get BOT_TOKEN 123456789:ABCdef... @BotFather on Telegram GOOGLE_CLIENT_ID abc123.apps.googleusercontent.com Google Cloud Console GOOGLE_CLIENT_SECRET GOCSPX-xyz... Google Cloud Console GOOGLE_REDIRECT_URI https://yourapp.railway.app/callback Your Railway URL BLOGGER_API_KEY AIzaSy... Google Cloud Console BLOG_ID 123456789 Your Blogger blog ID OPENAI_API_KEY sk-... OpenAI Platform STABILITY_API_KEY sk-... Stability AI TELEGRAM_CHANNELS -100123,-100456 Channel IDs (comma separated) RSS_FEEDS https://... Your RSS feeds (comma separated) SCHEDULE_TIMES 08:00,14:00,19:00 When to post SECRET_KEY random-secret-key Generate a random string TARGET_LANGUAGE hi Hindi स्टेप 5: Deploy Railway अपने आप बिल्ड और डिप्लॉय शुरू कर देगा। Logs देखते रहें। 🎉 अब आपके पास क्या है? ✅ Google OAuth - यूजर्स Google से लॉगिन कर सकते हैं ✅ AI Blog Generator - Gemma 3 से खुद लेख लिखता है ✅ AI Image Generator - DALL-E 3 / Stability AI से इमेज बनाता है ✅ Google Trends - ट्रेंडिंग टॉपिक्स अपने आप लेता है ✅ Blogger API - आपके ब्लॉग पर ऑटो-पोस्ट करता है ✅ Multiple Telegram Channels - कई चैनल्स में भेजता है ✅ PostgreSQL Database - सब कुछ स्टोर करता है ✅ Flask Dashboard - वेब इंटरफेस से कंट्रोल ✅ Scheduler - तय समय पर सब कुछ अपने आप चलता है ✅ Railway Ready - 24/7 चलने के लिए तैयार 🔧 ट्रबलशूटिंग अगर AI Model लोड न हो Railway पर RAM 512MB से कम है? Gemma 3 270M ~500MB RAM लेता है Railway के "Settings" में जाकर "Resources" से RAM बढ़ाएं (1GB करें) अगर OpenAI API काम न करे API Key चेक करें बिलिंग सेट अप है? OpenAI पेड है अगर Google OAuth फेल हो Redirect URI सही है? Railway URL के साथ /callback Google Cloud Console में Authorized Redirect URIs में डाला है? 📞 सपोर्ट अगर कहीं अटक जाएं या कोई एरर आए, तो बताएं! मैं हर स्टेप में आपकी मदद करूंगा। आपका AI न्यूज़ ब्लॉग अब पूरी तरह से ऑटोमेटेड है! 🚀🎉 in sabhi code ko kaise input kare kaha kare kisake bad kaise kare ओके, यूजर ने बहुत सारी चीजें सीखी हैं और अब उनके पास एक बहुत बड़ा कोड है, लेकिन वह कन्फ्यूज हैं कि इस सब कोड को कहां, कैसे और किस क्रम में इनपुट करना है। यह एकदम वैध सवाल है। उन्होंने पूछा है "in sabhi code ko kaise input kare kaha kare kisake bad kaise kare" यानी इन सब कोड को कैसे इनपुट करें, कहां करें, किसके बाद कैसे करें। तो यूजर की असल जरूरत यह है कि उन्हें एक स्टेप-बाय-स्टेप, क्लियर और प्रैक्टिकल गाइड चाहिए, जो उन्हें बताए कि फाइलें कैसे बनानी हैं, कहां रखनी हैं, कौन सा कोड किस फाइल में डालना है, और फिर उसे कैसे रन करना है। वह टेक्निकल बैकग्राउंड में कमजोर हो सकते हैं, इसलिए उन्हें बेहद सरल भाषा में, कमांड-बाय-कमांड समझाना होगा। मुझे उनके पिछले संदेशों से याद है कि उन्होंने Railway पर डिप्लॉय करने की बात भी की थी। तो उन्हें सिर्फ लोकल मशीन पर ही नहीं, बल्कि Railway पर डिप्लॉय करने के स्टेप्स भी चाहिए होंगे। साथ ही, उन्होंने PostgreSQL, मल्टीपल चैनल सपोर्ट, Google Trends, AI इमेज जनरेशन जैसे एडवांस्ड फीचर्स भी पूछे थे, जो इस आखिरी कोड में शामिल हैं। इसलिए मेरा रिस्पॉन्स बहुत ही स्ट्रक्चर्ड होना चाहिए: सबसे पहले, उन्हें बताऊं कि उन्हें एक नया फोल्डर बनाना है और उसके अंदर सारी फाइलें रखनी हैं। फिर, हर फाइल (requirements.txt, .env, Procfile, railway.json, main.py) को कैसे बनाना है और उसमें कौन सा कोड डालना है, यह स्टेप-बाय-स्टेप बताऊं। .env फाइल में वेरिएबल्स कैसे सेट करने हैं, इसकी डिटेल दूं। फिर, लोकल मशीन पर इसे कैसे रन करके टेस्ट करना है (python main.py --worker और python main.py)। उसके बाद, GitHub पर कैसे पुश करना है और Railway पर कैसे डिप्लॉय करना है, यह बताऊं। Railway पर एनवायरनमेंट वेरिएबल्स कैसे सेट करने हैं, इस पर भी ध्यान दूं, क्योंकि .env फाइल Railway पर काम नहीं करेगी। अंत में, उन्हें बताऊं कि सबकुछ सही से चल रहा है या नहीं, यह कैसे चेक करें। मुझे यह सुनिश्चित करना है कि भाषा बिल्कुल सरल हो, हिंदी में हो, और हर छोटी चीज को स्पष्ट किया जाए। उदाहरण के लिए, "टर्मिनल खोलें" या "यह कमांड टाइप करें" जैसे निर्देश दूं। पिछली बार उन्होंने "yes" कहकर रेडी-टू-यूज कोड मांगा था, जो मैंने दे दिया। अब वह कोड कैसे यूज करना है, यह बता रहा हूं। यह उनकी जर्नी का अंतिम चरण है - कोड को लाइव करना। बिल्कुल! मैं आपको पूरी प्रक्रिया स्टेप बाय स्टेप बताता हूँ कि इस कोड को कहाँ, कैसे और किस क्रम में इनपुट करना है। मैं हर छोटी चीज समझाऊंगा, जैसे कि फाइल कैसे बनाएं, कहां सेव करें, कमांड कैसे चलाएं। 📁 स्टेप 1: प्रोजेक्ट फोल्डर बनाएं सबसे पहले अपने कंप्यूटर पर एक नया फोल्डर बनाएं। इसे कोई भी नाम दे सकते हैं, जैसे newswave-bot। Windows में: डेस्कटॉप पर राइट-क्लिक करें → New Folder → नाम दें: newswave-bot Mac/Linux में: टर्मिनल खोलें और यह टाइप करें: bash cd Desktop mkdir newswave-bot cd newswave-bot 📝 स्टेप 2: सारी फाइलें बनाएं अब इस फोल्डर में हमें 5 फाइलें बनानी हैं। हर फाइल में दिया गया कोड कॉपी-पेस्ट करना है। फाइल 1: requirements.txt बनाएं newswave-bot फोल्डर में राइट-क्लिक करें → New → Text Document नाम बदलकर requirements.txt कर दें (extension .txt ही रहेगा) इस फाइल को नोटपैड या किसी भी text editor में खोलें नीचे दिया गया सारा कोड कॉपी करके पेस्ट कर दें Save करें (Ctrl+S) txt # Core python-telegram-bot==20.7 feedparser==6.0.10 requests==2.31.0 schedule==1.2.0 python-dotenv==1.0.0 psycopg2-binary==2.9.9 sqlalchemy==2.0.23 # Google APIs google-auth==2.23.4 google-auth-oauthlib==1.1.0 google-auth-httplib2==0.1.1 google-api-python-client==2.108.0 # AI & ML transformers==4.36.2 torch==2.1.2 accelerate==0.25.0 peft==0.7.1 bitsandbytes==0.41.3 openai==1.7.2 Pillow==10.1.0 # Web Framework flask==3.0.0 flask-sqlalchemy==3.1.1 flask-login==0.6.2 flask-oauthlib==0.9.6 # Utils beautifulsoup4==4.12.2 lxml==4.9.3 pandas==2.1.4 numpy==1.26.3 फाइल 2: .env बनाएं (यहाँ अपनी असली वैल्यू डालें) उसी फोल्डर में एक और Text Document बनाएं नाम बदलकर .env कर दें (शुरू में dot है) इस फाइल में नीचे दिया गया कोड कॉपी करें अपनी असली वैल्यू डालें (जैसे BOT_TOKEN, GOOGLE_CLIENT_ID आदि) env # Telegram BOT_TOKEN=1234567890:ABCdefGHIjklMNOpqrsTUVwxyz-1234567 # Database (अभी SQLite use करेंगे, Railway पर PostgreSQL auto set हो जाएगा) DATABASE_URL=sqlite:///newswave.db # Google OAuth (ये Google Cloud Console से लेना होगा) GOOGLE_CLIENT_ID=your_google_client_id_here GOOGLE_CLIENT_SECRET=your_google_client_secret_here GOOGLE_REDIRECT_URI=http://localhost:5000/callback # Blogger API (Google Cloud Console से Blogger API enable करें) BLOGGER_API_KEY=your_blogger_api_key BLOG_ID=your_blog_id_here # OpenAI (अगर DALL-E use करना है तो) OPENAI_API_KEY=your_openai_api_key # Stability AI (अगर Stability use करना है तो) STABILITY_API_KEY=your_stability_api_key # RSS Feeds (अपने RSS फीड डालें, कॉमा से अलग करें) RSS_FEEDS=https://newswaveblog24.blogspot.com/feeds/posts/default,https://trends.google.com/trends/trendingsearches/daily/rss # Telegram Channels (जहाँ पोस्ट भेजनी है, कॉमा से अलग करें) TELEGRAM_CHANNELS=-1001234567890,-1009876543210 # Schedule Times (24 घंटे फॉर्मेट में) SCHEDULE_TIMES=08:00,14:00,19:00 # AI Settings ENABLE_TRANSLATION=True TARGET_LANGUAGE=hi MAX_POSTS_PER_DAY=5 # Flask Secret Key (कोई भी रैंडम स्ट्रिंग डालें) SECRET_KEY=my-super-secret-key-change-this फाइल 3: Procfile बनाएं नई Text Document बनाएं नाम बदलकर Procfile करें (बिना किसी extension के) इसमें यह एक लाइन डालें: text web: gunicorn main:app worker: python main.py --worker फाइल 4: railway.json बनाएं नई Text Document बनाएं नाम बदलकर railway.json करें इसमें यह कोड डालें: json { "$schema": "https://railway.app/railway.schema.json", "build": { "builder": "NIXPACKS" }, "deploy": { "numReplicas": 1, "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 10, "healthcheckPath": "/health", "healthcheckTimeout": 100 } } फाइल 5: main.py बनाएं (सबसे बड़ी फाइल) नई Text Document बनाएं नाम बदलकर main.py करें पिछले मैसेज में दिया गया पूरा कोड (जो सबसे लंबा है) कॉपी करके इस फाइल में पेस्ट करें ध्यान दें: वह कोड बहुत लंबा है (~800 लाइन), ध्यान से पूरा कॉपी करें 💻 स्टेप 3: अब सारी फाइलें इस तरह दिखनी चाहिए आपके newswave-bot फोल्डर में ये 5 फाइलें होनी चाहिए: ✅ requirements.txt ✅ .env ✅ Procfile (बिना extension) ✅ railway.json ✅ main.py 🐍 स्टेप 4: Python और पैकेजेस इंस्टॉल करें Windows में: Python.org से Python 3.11 डाउनलोड करें इंस्टॉल करते समय "Add Python to PATH" चेक करना न भूलें Command Prompt खोलें (Win+R → cmd) अपने प्रोजेक्ट फोल्डर में जाएं: cmd cd Desktop\newswave-bot पैकेजेस इंस्टॉल करें: cmd pip install -r requirements.txt Mac/Linux में: bash cd ~/Desktop/newswave-bot pip3 install -r requirements.txt 🚀 स्टेप 5: लोकल मशीन पर टेस्ट करें अब हम देखेंगे कि सब कुछ सही से काम कर रहा है या नहीं। टेस्ट 1: डेटाबेस और बेसिक फंक्शन चेक करें Command Prompt/Terminal में यह टाइप करें: bash python main.py --worker अगर सब ठीक रहा तो कुछ इस तरह का आउटपुट दिखेगा: text 2024-01-01 10:00:00 - INFO - 🚀 न्यूज़वेव अल्टीमेट बॉट शुरू हो रहा है... 2024-01-01 10:00:01 - INFO - ✅ Database tables created 2024-01-01 10:00:02 - INFO - Loading AI model... ... कुछ देर चलने दें, फिर Ctrl+C दबाकर बंद कर दें। टेस्ट 2: Flask Web App चलाएं अब दूसरा टर्मिनल खोलें और यह चलाएं: bash python main.py आउटपुट में कुछ ऐसा दिखेगा: text * Running on http://127.0.0.1:5000 अब अपना ब्राउज़र खोलें और http://127.0.0.1:5000 पर जाएं। वेबसाइट दिखनी चाहिए। 🌐 स्टेप 6: GitHub पर अपलोड करें अब हम इस कोड को GitHub पर डालेंगे ताकि Railway उसे ले सके। GitHub अकाउंट नहीं है तो बनाएं GitHub.com पर जाएं Sign Up से अकाउंट बनाएं नया रिपॉजिटरी बनाएं GitHub पर लॉगिन करें ऊपर दाएं "+" आइकन → "New repository" Repository name: newswave-ultimate-bot Public चुनें "Create repository" बटन दबाएं Git कमांड से अपलोड करें अपने कंप्यूटर में टर्मिनल/कमांड प्रॉम्प्ट खोलें और यह सब टाइप करें (एक-एक करके): bash cd Desktop/newswave-bot git init git add . git commit -m "First commit - न्यूज़वेव अल्टीमेट बॉट" git branch -M main git remote add origin https://github.com/आपका-यूजरनेम/newswave-ultimate-bot.git git push -u origin main ⚠️ नोट: आपका-यूजरनेम की जगह अपना GitHub username डालें। 🚂 स्टेप 7: Railway पर डिप्लॉय करें Railway अकाउंट बनाएं Railway.com पर जाएं "Sign Up" → "Continue with GitHub" चुनें GitHub अकाउंट से लॉगिन करें नया प्रोजेक्ट बनाएं Railway डैशबोर्ड पर "New Project" बटन दबाएं "Deploy from GitHub repo" चुनें अगर पहली बार है तो GitHub को authorize करना होगा अपना रिपॉजिटरी चुनें: newswave-ultimate-bot PostgreSQL Database Add करें Railway प्रोजेक्ट के डैशबोर्ड में "New" बटन दबाएं "Database" → "PostgreSQL" चुनें Railway अपने आप DATABASE_URL वेरिएबल सेट कर देगा Environment Variables सेट करें अपने प्रोजेक्ट में "Variables" टैब पर जाएं "New Variable" बटन दबाकर ये सब डालें (जितने आपके पास हैं): Variable Value (example) BOT_TOKEN 1234567890:ABCdefGHIjklMNOpqrsTUVwxyz-1234567 GOOGLE_CLIENT_ID 1234567890-abc123.apps.googleusercontent.com GOOGLE_CLIENT_SECRET GOCSPX-xyz123 GOOGLE_REDIRECT_URI https://your-app-name.railway.app/callback BLOGGER_API_KEY AIzaSyABC... BLOG_ID 123456789 OPENAI_API_KEY sk-... STABILITY_API_KEY sk-... TELEGRAM_CHANNELS -1001234567890,-1009876543210 RSS_FEEDS https://newswaveblog24.blogspot.com/feeds/posts/default,https://trends.google.com/trends/trendingsearches/daily/rss SCHEDULE_TIMES 08:00,14:00,19:00 SECRET_KEY random-secret-key-here TARGET_LANGUAGE hi ENABLE_TRANSLATION True MAX_POSTS_PER_DAY 5 Important: .env फाइल सिर्फ लोकल के लिए है। Railway पर सब कुछ Variables में डालना जरूरी है। Deploy Railway अपने आप बिल्ड और डिप्लॉय शुरू कर देगा। "Deployments" टैब में देखते रहें। ✅ स्टेप 8: चेक करें सब सही है या नहीं 1. Logs देखें Railway डैशबोर्ड में "Logs" टैब पर क्लिक करें। यहाँ दिखेगा कि बॉट चल रहा है या नहीं। 2. Web App चेक करें Railway आपको एक URL देगा जैसे https://newswave-ultimate-bot.up.railway.app इस URL पर जाएं → Homepage दिखनी चाहिए /health पर जाएं → JSON response दिखना चाहिए 3. Telegram Bot चेक करें अपने Telegram bot पर जाएं (जो आपने बनाया था) और /start करें। Reply आना चाहिए। 4. Schedule चेक करें अगर सब सही है, तो तय समय (08:00, 14:00, 19:00) पर बॉट अपने आप: Google Trends से टॉपिक लेगा AI से पोस्ट लिखेगा AI से इमेज बनाएगा Blogger पर पोस्ट करेगा Telegram channels में भेजेगा 🎉 बधाई हो! आपका पूरा सिस्टम अब लाइव है! आगे क्या कर सकते हैं: डैशबोर्ड एक्सेस करें: https://your-app.railway.app/dashboard (Google login के बाद) पोस्ट देखें: https://your-app.railway.app/api/posts ट्रेंडिंग टॉपिक्स देखें: Telegram bot में /trends टाइप करें ⚠️ कॉमन प्रॉब्लम्स और सॉल्यूशन प्रॉब्लम: "Module not found" एरर सॉल्यूशन: Railway पर requirements.txt सही से अपलोड हुआ है? Logs में देखें। प्रॉब्लम: "Cannot connect to database" सॉल्यूशन: DATABASE_URL variable सेट है? PostgreSQL add किया था? प्रॉब्लम: "Bot token invalid" सॉल्यूशन: BOT_TOKEN सही है? @BotFather से दोबारा चेक करें। प्रॉब्लम: "Google OAuth error" सॉल्यूशन: Google Cloud Console में Redirect URI सही डाला है? वो होना चाहिए https://your-app.railway.app/callback 📞 अगर फिर भी प्रॉब्लम हो बस मुझे बताएं: कौन सा स्टेप कर रहे हैं? क्या एरर आ रहा है? (Error message copy करके भेजें) Railway पर कौन से Variables सेट किए हैं? मैं हर स्टेप में आपकी मदद करूंगा। आपने इतना लंबा सफर तय किया है, अब बस थोड़ा सा धक्का बाकी है! 🚀 in sabhi tools KO ek dusare se yani CMs se kaise jodate hai har ek tools ko jodane ke liye alag alag steps bat a eye , Read 10 web pages नमस्ते! अब हम आपके सवाल का जवाब देते हैं - इन सभी टूल्स (PostgreSQL, AI, Google Trends, Telegram) को CMS (जैसे आपके Blogger ब्लॉग) से कैसे जोड़ा जाए, हर एक के लिए अलग-अलग स्टेप्स के साथ। पिछली बार हमने जो पूरा कोड देखा था, उसमें ये सारे कनेक्शन पहले से मौजूद हैं। अब मैं आपको हर टूल को अलग-अलग कनेक्ट करने का तरीका बताता हूँ। 1. PostgreSQL को CMS से कैसे कनेक्ट करें PostgreSQL आपके डेटा का स्टोरेज है। CMS को इससे कनेक्ट करने का मतलब है कि आपकी सारी पोस्ट्स, यूजर्स और डेटा PostgreSQL डेटाबेस में सेव होंगे। स्टेप 1: PostgreSQL डेटाबेस तैयार करें Railway पर PostgreSQL ऐड करें (जैसा पिछले मैसेज में बताया) डेटाबेस का कनेक्शन स्ट्रिंग (URL) नोट करें - यह कुछ इस तरह होगा: postgresql://username:password@hostname:5432/database स्टेप 2: अपने CMS की डेटाबेस कॉन्फ़िगरेशन बदलें अपने CMS प्रोजेक्ट (हमारे मामले में main.py) में ये सेटिंग करें: python import os from sqlalchemy import create_engine # PostgreSQL कनेक्शन स्ट्रिंग DATABASE_URL = os.environ.get('DATABASE_URL', 'postgresql://localhost:5432/mydb') # इंजन बनाएं engine = create_engine(DATABASE_URL) # कनेक्शन टेस्ट करें with engine.connect() as conn: print("✅ PostgreSQL से कनेक्ट हुआ") स्टेप 3: Railway पर एनवायरनमेंट वेरिएबल सेट करें Railway डैशबोर्ड में जाकर DATABASE_URL वेरिएबल डालें (Railway auto-add कर देता है) स्टेप 4: माइग्रेशन चलाएं डेटाबेस में टेबल्स बनाने के लिए: bash python main.py --migrate टिप: अगर आप Wagtail CMS use कर रहे हैं तो इस गाइड की मदद ले सकते हैं। इसमें बताया गया है कि settings.py में डेटाबेस कैसे कॉन्फ़िगर करें । 2. AI मॉडल (Gemma) को CMS से कैसे कनेक्ट करें AI मॉडल को CMS से जोड़ने का मतलब है कि आपके CMS में AI की सुविधा हो, जैसे ऑटोमेटिक पोस्ट लिखना। स्टेप 1: AI मॉडल लोड करें अपने main.py में यह कोड डालें: python from transformers import AutoTokenizer, AutoModelForCausalLM import torch class AIModel: def __init__(self): self.tokenizer = AutoTokenizer.from_pretrained("google/gemma-3-270m") self.model = AutoModelForCausalLM.from_pretrained( "google/gemma-3-270m", torch_dtype=torch.float16, device_map="auto" ) def generate(self, prompt): inputs = self.tokenizer(prompt, return_tensors="pt") outputs = self.model.generate(**inputs, max_length=500) return self.tokenizer.decode(outputs[0], skip_special_tokens=True) # CMS में AI ऑब्जेक्ट बनाएं ai_model = AIModel() स्टेप 2: CMS में AI फंक्शनैलिटी ऐड करें जब भी नई पोस्ट बनानी हो, AI को कॉल करें: python def create_ai_post(topic): prompt = f"टॉपिक: {topic} पर एक हिंदी ब्लॉग पोस्ट लिखें" content = ai_model.generate(prompt) # CMS में सेव करें new_post = BlogPost(title=topic, content=content) db.session.add(new_post) db.session.commit() return new_post स्टेप 3: एडमिन पैनल में AI बटन ऐड करें अगर आपके पास एडमिन पैनल है, तो उसमें "AI Generate" बटन जोड़ सकते हैं। Concrete CMS के लिए AI Integration प्लगइन उपलब्ध है जो GPT-4 Turbo को इंटीग्रेट करता है । Craft CMS के लिए OpenAI Content Writer प्लगइन है जो एडिटर में AI बटन जोड़ता है । 3. Google Trends को CMS से कैसे कनेक्ट करें Google Trends से ट्रेंडिंग टॉपिक्स लेकर CMS में ऑटोमेटिक पोस्ट बनाने के लिए। स्टेप 1: Google Trends RSS फीड fetch करें python import feedparser import requests def fetch_google_trends(): trends_rss = "https://trends.google.com/trends/trendingsearches/daily/rss?geo=IN" feed = feedparser.parse(trends_rss) topics = [] for entry in feed.entries[:10]: # टॉप 10 ट्रेंड्स topic = { 'title': entry.get('title', ''), 'description': entry.get('description', ''), 'pubDate': entry.get('published', ''), 'traffic': entry.get('ht_approx_traffic', '') } topics.append(topic) return topics स्टेप 2: ऑटोमेटिक पोस्ट क्रिएशन सेट करें python def create_posts_from_trends(): trends = fetch_google_trends() for trend in trends: # AI से कंटेंट जनरेट करें content = ai_model.generate(f"Write a blog post about {trend['title']}") # CMS में पोस्ट बनाएं post = BlogPost( title=trend['title'], content=content, source='google_trends', trending_score=trend.get('traffic', 0) ) db.session.add(post) db.session.commit() स्टेप 3: शेड्यूलर सेट करें रोजाना चलाने के लिए: python import schedule import time # हर दिन सुबह 8 बजे चलेगा schedule.every().day.at("08:00").do(create_posts_from_trends) while True: schedule.run_pending() time.sleep(60) n8n का यह वर्कफ्लो भी देख सकते हैं जो Google Trends को Google Sheets से कनेक्ट करता है। 4. Telegram Bot को CMS से कैसे कनेक्ट करें Telegram Bot को CMS से जोड़ने का मतलब है कि जब भी CMS में नई पोस्ट पब्लिश हो, वह Telegram चैनल्स में अपने आप भेजी जाए। स्टेप 1: Telegram Bot बनाएं Telegram में @BotFather से बॉट बनाएं BOT_TOKEN नोट करें स्टेप 2: CMS में Telegram सपोर्ट ऐड करें python from telegram import Bot class TelegramPublisher: def __init__(self, token): self.bot = Bot(token=token) self.channels = ['@channel1', '@channel2'] # अपने चैनल्स def publish_post(self, post): message = f"📰 {post.title}\n\n{post.summary}\n\n🔗 {post.url}" for channel in self.channels: try: self.bot.send_message( chat_id=channel, text=message, parse_mode='Markdown' ) print(f"✅ {channel} में भेजा") except Exception as e: print(f"❌ एरर: {e}") telegram = TelegramPublisher(os.environ.get('BOT_TOKEN')) स्टेप 3: पोस्ट पब्लिश होने पर ट्रिगर करें जब भी नई पोस्ट सेव हो, Telegram भेजें: python def save_post(post): db.session.add(post) db.session.commit() # Telegram पर भेजें telegram.publish_post(post) Craft CMS के लिए Social Buddy प्लगइन है जो Telegram समेत कई प्लेटफॉर्म पर ऑटो-पब्लिश करता है। 5. सभी टूल्स को एक साथ कनेक्ट करना (पूरा सिस्टम) अब हम सबको एक साथ जोड़ते हैं: python class NewsWaveCMS: def __init__(self): # 1. Database - PostgreSQL self.db = PostgreSQLConnection(os.environ.get('DATABASE_URL')) # 2. AI Model - Gemma self.ai = AIModel() # 3. Trends - Google self.trends = GoogleTrendsFetcher() # 4. Telegram Publisher self.telegram = TelegramPublisher(os.environ.get('BOT_TOKEN')) def daily_workflow(self): """रोजाना का वर्कफ्लो""" # Google Trends से टॉपिक्स लें topics = self.trends.fetch(limit=5) for topic in topics: # AI से कंटेंट जनरेट करें content = self.ai.generate(f"Write about {topic}") # CMS पोस्ट बनाएं post = Post(title=topic, content=content) self.db.save(post) # Telegram पर भेजें self.telegram.publish(post) def run_scheduler(self): """शेड्यूलर चलाएं""" schedule.every().day.at("08:00").do(self.daily_workflow) schedule.every().day.at("14:00").do(self.daily_workflow) while True: schedule.run_pending() time.sleep(60) 📝 चेकलिस्ट - सब कुछ कनेक्ट करने के लिए PostgreSQL कनेक्शन Railway PostgreSQL ऐड किया DATABASE_URL एनवायरनमेंट वेरिएबल सेट किया एप्लिकेशन में डेटाबेस कनेक्शन टेस्ट किया माइग्रेशन चलाया AI Model कनेक्शन transformers और torch इंस्टॉल किए Gemma 3 270M मॉडल डाउनलोड किया मॉडल को प्रॉपरली लोड किया कंटेंट जनरेशन टेस्ट किया Google Trends कनेक्शन feedparser इंस्टॉल किया Google Trends RSS से डेटा फेच किया डेटा को पार्स किया शेड्यूलर सेट किया Telegram Bot कनेक्शन @BotFather से बॉट बनाया BOT_TOKEN सेव किया चैनल IDs ली टेस्ट मैसेज भेजा 🎯 अंतिम टिप्स हर कनेक्शन को अलग-अलग टेस्ट करें - पहले PostgreSQL टेस्ट करें, फिर AI, फिर Trends, फिर Telegram। सबको एक साथ न चलाएं। एरर हैंडलिंग जरूरी है - अगर कोई क in sabhi tools KO ek dusare se yani CMs se kaise jodate hai har ek tools ko jodane ke liye alag alag steps bat a eye , प्लानिंग टूल्स (जैसे Kordiam) को CMS से जोड़ना यह न्यूज़रूम का प्लानिंग सिस्टम होता है। इसे CMS से जोड़ने का मतलब है कि आपकी प्लानिंग और पब्लिशिंग के बीच का फासला खत्म हो जाता है। · एपीआई-आधारित इंटीग्रेशन: ज्यादातर आधुनिक टूल्स की तरह, Kordiam भी APIs प्रदान करता है। इन APIs का इस्तेमाल करके आप दोनों सिस्टम को आपस में बातचीत करने के लिए सेट कर सकते हैं । · सिंक होने वाला डेटा: इस कनेक्शन की मदद से, आपके CMS (जैसे Drupal) में कुछ खास फीचर अपने आप एक्टिवेट हो जाते हैं। उदाहरण के लिए: · जैसे ही Kordiam में किसी स्टोरी का स्टेटस "प्लान्ड" से "रेडी" होता है, CMS में उससे जुड़ा एक ब्लॉग ड्राफ्ट अपने आप तैयार हो जाता है । · अगर CMS में कोई ब्रेकिंग न्यूज का आर्टिकल पब्लिश होता है, तो Kordiam में अपने आप एक अलर्ट या स्टोरी बन सकती है । · दोनों जगहों पर स्टोरी की स्थिति (status) और शेड्यूल एक जैसे रहते हैं, जिससे कंफ्यूजन नहीं होती । 📝 CMS में वीडियो/ऑडियो एम्बेड करना आपके प्रोडक्शन सॉफ्टवेयर (जैसे Adobe Premiere Pro, Dalet Cut) से तैयार वीडियो सीधे ब्लॉग में कैसे दिखेंगे? · MAM (मीडिया एसेट मैनेजमेंट) से कनेक्शन: आपका सारा वीडियो कंटेंट MAM सिस्टम में स्टोर होता है। जब आप CMS में एक नया ब्लॉग बनाते हैं, तो एक खास तरह के फील्ड (Assets Field) के जरिए आप सीधे MAM से वीडियो या ऑडियो फाइल चुनकर ब्लॉग में डाल सकते हैं । · ऑटोमेटिक एन्कोडिंग और प्लेयर: जैसे ही आप वीडियो को ब्लॉग से अटैच करते हैं, बैकएंड पर कई काम अपने आप हो जाते हैं: · वीडियो अपने आप HLS जैसे स्ट्रीमिंग फॉर्मेट में बदल (transcode) जाता है, ताकि हर डिवाइस पर आसानी से चले । · ब्लॉग पब्लिश होते ही उसमें एक वीडियो प्लेयर (जैसे Mux Player, JWPlayer) अपने आप लोड हो जाता है और वीडियो चलाने के लिए तैयार हो जाता है । · कस्टमाइजेशन: आप चाहें तो वीडियो के कैप्शन, सबटाइटल और थंबनेल को भी CMS से ही कंट्रोल कर सकते हैं । 🎬 NRCS (न्यूज़रूम कंप्यूटर सिस्टम) और प्लेआउट से जोड़ना यह वह सिस्टम है जहां से आपका लाइव टीवी चलता है। इसे CMS से जोड़ने का मतलब है कि आपका टीवी प्रसारण और ब्लॉग दोनों एक-दूसरे को फीड कर सकते हैं। · कम्यूनिकेशन हब का इस्तेमाल: यह सबसे जटिल इंटीग्रेशन होता है। इसे सीधे जोड़ने की बजाय, एक "कम्यूनिकेशन हब" बनाया जाता है जो दोनों सिस्टम के बीच संदेशों (signals) का आदान-प्रदान कराता है । · वास्तविक जीवन का उदाहरण: · जैसे ही NRCS में किसी स्टोरी के लिए लाइव टेलीप्रॉम्प्टर स्क्रिप्ट में बदलाव होता है, वह जानकारी CMS में जाकर ब्लॉग के ड्राफ्ट को अपडेट कर सकती है। · इसके उलट, अगर CMS में कोई ब्रेकिंग न्यूज आर्टिकल पब्लिश होता है, तो यह NRCS में एक ग्राफिक या क्रॉल (ticker) के तौर पर दिख सकता है। · अगर आप लाइव न्यूज बुलेटिन को रिकॉर्ड करके उसे तुरंत VOD (Video on Demand) में बदलकर ब्लॉग पर डालना चाहते हैं, तो यह प्रोसेस भी इसी तरह के इंटीग्रेशन से अपने आप हो सकती है । 🤖 कंटेंट रीपर्पजिंग के लिए ऑटोमेशन यह वह जगह है जहां आप ब्लॉग से नए तरह का कंटेंट (जैसे वीडियो) बना सकते हैं। · Pabbly Connect जैसे टूल्स का इस्तेमाल: ये जीरो-कोड ऑटोमेशन प्लेटफॉर्म हैं। आप इनमें एक वर्कफ्लो बना सकते हैं: · ट्रिगर: जब भी आपके CMS (WordPress) में कोई नई ब्लॉग पोस्ट पब्लिश हो । · एक्शन 1: उस ब्लॉग के टाइटल और कंटेंट को Open AI (ChatGPT) को भेजकर उसके लिए एक वीडियो स्क्रिप्ट तैयार कराएं । · एक्शन 2: उस स्क्रिप्ट को HiGen जैसे AI वीडियो जनरेशन टूल में भेजकर एक एवाटार वीडियो बनवाएं । · एक्शन 3: बनी हुई वीडियो फाइल को अपने आप Google Drive या MAM सिस्टम में सेव करा दें । 💡 प्रोफेशनल तरीका अगर आप एक बड़े पैमाने पर न्यूज चैनल शुरू कर रहे हैं, तो ब्राइटस्पॉट (Brightspot) या हेडलेस द्रुपाल (Headless Drupal) जैसे एंटरप्राइज़ CMS प्लेटफॉर्म देखें। ये प्लेटफॉर्म खासतौर पर मीडिया कंपनियों के लिए बने हैं और इनमें ऊपर बताए गए ज्यादातर इंटीग्रेशन पहले से मौजूद होते हैं या आसानी से किए जा सकते हैं। We need to answer the user's question: "in sabhi tools KO ek dusare se yani CMs se kaise jodate hai har ek tools ko jodane ke liye alag alag steps bat a eye". They are asking how to connect all these tools with each other, i.e., with the CMS, and provide separate steps for each tool connection. They listed four categories: Planning tools (Kordiam) to CMS, CMS to video/audio embedding (MAM), NRCS/playout to CMS, and content repurposing automation (Pabbly Connect). They want step-by-step instructions for each. We need to provide detailed steps for integrating each type of tool with a CMS (like Drupal, WordPress, etc.). The steps should be practical, possibly using APIs, webhooks, middleware, etc. We should cover: Kordiam (planning tool) to CMS integration: using APIs to sync story status, create drafts, etc. MAM (media asset management) to CMS: using APIs to select assets, auto-transcoding, embedding players. NRCS (newsroom computer system) and playout to CMS: using a communication hub, message exchange, bidirectional updates. Content repurposing automation: using Pabbly Connect or similar to trigger actions based on CMS publish events, generate video scripts with OpenAI, create videos with AI tools, store in MAM. Also mention enterprise solutions like Brightspot or Headless Drupal that have built-in integrations. We should structure the answer in a clear, step-by-step manner for each integration, explaining the technical approach (APIs, webhooks, plugins) and giving examples. We'll write in Hindi as the user is using Hindi. नीचे दिए गए स्टेप्स में मैं हर टूल को CMS (Content Management System) से जोड़ने की प्रक्रिया अलग-अलग समझा रहा हूँ। ये स्टेप्स ज्यादातर API-बेस्ड इंटीग्रेशन पर आधारित हैं और किसी भी आधुनिक CMS (जैसे Drupal, WordPress, Brightspot) पर लागू हो सकते हैं। 1. प्लानिंग टूल (Kordiam) को CMS से जोड़ना चरण 1: API एक्सेस प्राप्त करें Kordiam (या कोई भी प्लानिंग टूल) आमतौर पर REST API प्रदान करता है। सबसे पहले API डॉक्यूमेंटेशन पढ़ें और API key/Token जनरेट करें। CMS (जैसे Drupal/WordPress) में भी REST API enabled होना चाहिए। चरण 2: Webhook या कस्टम प्लगइन सेट करें Kordiam में एक Webhook बनाएँ जो तब ट्रिगर हो जब किसी स्टोरी का स्टेटस “प्लान्ड” से “रेडी” हो जाए। इस Webhook का पॉइंट CMS के एक एंडपॉइंट पर सेट करें, जो नया ड्राफ्ट बनाने के लिए जिम्मेदार हो। चरण 3: CMS में API एंडपॉइंट बनाएँ CMS (Drupal में custom module, WordPress में custom plugin) में एक एंडपॉइंट बनाएँ जो: Kordiam से आए डेटा (टाइटल, डेस्क्रिप्शन, डेडलाइन, असाइन किए गए लेखक) को प्राप्त करे। इस डेटा से CMS में एक नया ड्राफ्ट (ब्लॉग पोस्ट) क्रिएट करे। क्रिएटेड पोस्ट की ID और URL Kordiam को वापस भेजे (ताकि दोनों सिस्टम सिंक में रहें)। चरण 4: द्विदिश सिंक सुनिश्चित करें CMS से Kordiam में स्टेटस अपडेट भेजने के लिए: जब CMS में पोस्ट पब्लिश हो, तो CMS से Kordiam के API पर रिक्वेस्ट भेजें (स्टेटस को “पब्लिश्ड” करें)। इसके लिए CMS में एक action hook लगाएँ (जैसे WordPress में publish_post)। चरण 5: शेड्यूल सिंक Kordiam और CMS दोनों में स्टोरी की डेडलाइन / पब्लिश डेट एक ही रहे, इसके लिए समय-समय पर (cron job) डेटा सिंक करने की व्यवस्था करें। 2. MAM (मीडिया एसेट मैनेजमेंट) को CMS से जोड़ना चरण 1: MAM सिस्टम का API सेटअप करें मान लीजिए आपके पास EditShare, CatDV, या कोई कस्टम MAM है। उसका API endpoint और authentication तैयार करें। MAM में स्टोर सभी वीडियो/ऑडियो फाइल्स के लिए unique ID (Asset ID) होना चाहिए। चरण 2: CMS में कस्टम फील्ड बनाएँ CMS के ब्लॉग पोस्ट एडिटर में एक नया फील्ड जोड़ें (Asset Selector)। यह फील्ड MAM API से कॉल करके सभी असेंस की सूची दिखाए (thumbnail, नाम सहित) और यूजर को एक असेंस चुनने दे। चरण 3: वीडियो प्लेयर इंटीग्रेशन जब यूजर कोई असेंस चुनता है, तो CMS में उसका Asset ID सेव हो जाता है। पोस्ट पब्लिश होते समय, CMS के फ्रंटएंड टेम्प्लेट में एक वीडियो प्लेयर (जैसे JWPlayer, Video.js) लोड करें। प्लेयर का सोर्स URL MAM के स्ट्रीमिंग एंडपॉइंट (HLS/DASH) से बनाएँ। यदि MAM ट्रांसकोडिंग सपोर्ट करता है, तो सही फॉर्मेट का URL लें। चरण 4: ऑटोमैटिक एन्कोडिंग अगर वीडियो अभी स्ट्रीमिंग फॉर्मेट में नहीं है, तो MAM को ट्रांसकोडिंग जॉब शुरू करनी होगी। CMS से MAM को बताएँ कि इस असेंस को पब्लिश करना है, तो MAM एन्कोडिंग शुरू कर दे और होने पर वेबहुक से CMS को सूचित करे। CMS में एक कॉलबैक URL हो जो एन्कोडिंग पूरी होने पर वीडियो के प्लेयर URL अपडेट कर दे। चरण 5: कैप्शन/सबटाइटल सिंक अगर MAM में सबटाइटल फाइल (VTT/SRT) भी है, तो CMS में उनका URL भी स्टोर करें और प्लेयर में सबटाइटल ट्रैक के रूप में जोड़ें। 3. NRCS (न्यूज़रूम कंप्यूटर सिस्टम) और प्लेआउट को CMS से जोड़ना चरण 1: कम्यूनिकेशन हब (Message Broker) सेट करें यह सबसे जटिल इंटीग्रेशन है। सीधे कनेक्शन की बजाय एक मिडलवेयर (जैसे RabbitMQ, Apache Kafka) लगाएँ। NRCS (जैसे Octopus, iNews) और CMS दोनों इस हब से जुड़ेंगे और संदेशों (messages) का आदान-प्रदान करेंगे। चरण 2: इवेंट-ड्रिवन आर्किटेक्चर डिज़ाइन करें पहचानें कि किन घटनाओं (events) को सिंक करना है: NRCS में स्क्रिप्ट अपडेट (टेलीप्रॉम्प्टर के लिए) CMS में ब्रेकिंग न्यूज पब्लिश होना लाइव बुलेटिन का रिकॉर्डेड वर्जन (VOD) CMS में डालना चरण 3: NRCS में प्लगइन/एक्सटेंशन बनाएँ NRCS की स्क्रिप्टिंग क्षमता (जैसे MOS protocol) का उपयोग करके, जब भी कोई स्टोरी अपडेट हो, तो एक मैसेज कम्यूनिकेशन हब पर भेजें। उदाहरण: स्क्रिप्ट का नया वर्जन तैयार होने पर, उसकी JSON पेलोड हब पर publish करें। चरण 4: CMS में लिसनर बनाएँ CMS में एक बैकग्राउंड प्रोसेस (क्रॉन जॉब या वेबहुक) लगाएँ जो हब से मैसेज पढ़े। जब NRCS से स्क्रिप्ट अपडेट का मैसेज आए, तो CMS में उस स्टोरी से जुड़े ब्लॉग ड्राफ्ट को अपडेट करें (यदि ड्राफ्ट पहले से मौजूद है)। चरण 5: उल्टा सिंक (CMS → NRCS) जब CMS में कोई ब्रेकिंग न्यूज पब्लिश हो, तो CMS हब पर मैसेज भेजे। NRCS में एक लिसनर इस मैसेज को पकड़े और NRCS में एक ग्राफिक या क्रॉल जनरेट करे (MOS-ART या अन्य प्रोटोकॉल से)। चरण 6: लाइव बुलेटिन से VOD बनाना प्लेआउट सर्वर (जैसे Imagine Communications) से लाइव स्ट्रीम का रिकॉर्डिंग फाइल MAM या क्लाउड स्टोरेज में सेव होती है। जब रिकॉर्डिंग तैयार हो, तो प्लेआउट सिस्टम हब पर मैसेज भेजे (VOD ready)। CMS इस मैसेज पर MAM से वीडियो असेंस लेकर अपने डेटाबेस में स्टोर करे और ब्लॉग पोस्ट में एम्बेड करे (ऊपर MAM वाले स्टेप्स की तरह)। 4. कंटेंट रीपर्पजिंग के लिए ऑटोमेशन (Pabbly Connect) चरण 1: Pabbly Connect अकाउंट बनाएँ Pabbly Connect पर जाएँ और साइन अप करें। (इसी तरह Zapier या n8n भी इस्तेमाल कर सकते हैं।) चरण 2: CMS में वेबहुक सेट करें WordPress/Drupal में एक प्लगइन इंस्टॉल करें जो नई पोस्ट पब्लिश होने पर वेबहुक भेज सके (जैसे WP Webhooks)। वेबहुक URL Pabbly Connect के वर्कफ्लो के ट्रिगर URL के रूप में दें। चरण 3: Pabbly Connect में वर्कफ्लो बनाएँ ट्रिगर: CMS Webhook (जब नई पोस्ट आए)। एक्शन 1: OpenAI (ChatGPT) का इस्तेमाल करें। पोस्ट के टाइटल और कंटेंट को भेजकर एक वीडियो स्क्रिप्ट तैयार करें। एक्शन 2: AI वीडियो जनरेशन टूल (जैसे HiGen, Synthesia) से कनेक्ट करें। स्क्रिप्ट और अवतार चुनकर वीडियो जनरेट करें। एक्शन 3: जनरेटेड वीडियो फाइल को Google Drive या MAM सिस्टम में अपलोड करें। चरण 4: MAM से CMS तक वीडियो पहुँचाना MAM (या Google Drive) में वीडियो अपलोड होने के बाद, Pabbly Connect में एक अतिरिक्त एक्शन जोड़ें जो CMS के API से नया वीडियो असेंस बनाए (यानी CMS के MAM फील्ड में उस वीडियो को अटैच करे)। CMS को अपडेट करें कि अब इस पोस्ट के साथ एक वीडियो जुड़ गया है। चरण 5: पोस्ट को अपडेट करना (यदि चाहें) आप चाहें तो वीडियो जनरेट होने के बाद, CMS पोस्ट में वीडियो एम्बेड करने के लिए पोस्ट को एडिट भी कर सकते हैं (CMS API का इस्तेमाल करके)। 5. एंटरप्राइज़ CMS समाधान (Brightspot, Headless Drupal) अगर आप बड़े स्तर पर न्यूज़ चैनल शुरू कर रहे हैं तो ये CMS प्लेटफॉर्म पहले से ही कई इंटीग्रेशन सपोर्ट करते हैं: Brightspot Brightspot में प्लगइन स्टोर है जहाँ से Kordiam, MAM, NRCS के लिए रेडीमेड कनेक्टर मिल सकते हैं। यह GraphQL API प्रदान करता है, जिससे ऊपर बताए गए सभी इंटीग्रेशन आसानी से किए जा सकते हैं। आपको बस API डॉक्यूमेंटेशन पढ़कर एंडपॉइंट्स को कॉल करना होगा। Headless Drupal Drupal 8/9 में JSON:API मॉड्यूल enable करें। सभी कंटेंट टाइप्स, टैक्सोनॉमी, और मीडिया एसेट्स API के माध्यम से उपलब्ध हो जाते हैं। आप ऊपर बताए गए स्टेप्स को Drupal के custom modules में लिख सकते हैं, या फिर ओपन सोर्स मॉड्यूल्स का उपयोग कर सकते हैं (जैसे Webhooks, REST UI)। निष्कर्ष हर टूल को CMS से जोड़ने के लिए API-आधारित इंटीग्रेशन सबसे सुरक्षित और स्केलेबल तरीका है। शुरुआत में छोटे-छोटे पायलट प्रोजेक्ट बनाएँ और धीरे-धीरे सभी टूल्स को एक साथ जोड़ें। अगर आप किसी विशेष टूल के लिए और विस्तृत जानकारी चाहते हैं, तो कृपया बताएँ। isaka flowchart banakar de आदमी ने पूछा है "isaka flowchart banakar de" यानी इसका फ़्लोचार्ट बनाकर दो। ऊपर कन्वर्सेशन में हमने कई टूल्स के बारे में बात की: Trello, IFTTT, Telegram, Google Sheets, PostgreSQL, AI models, Google Trends, Blogger API, image generation, etc. और फिर हाल के मैसेज में हमने विस्तार से समझाया कि कैसे प्लानिंग टूल्स, MAM, NRCS, ऑटोमेशन टूल्स को CMS से जोड़ा जाता है। अब आदमी चाहता है कि इन सबका एक फ़्लोचार्ट बनाकर दिया जाए, जो पूरे सिस्टम के आर्किटेक्चर और डेटा फ़्लो को दिखाए। हमें एक फ़्लोचार्ट बनाना है जो इन सारे घटकों के बीच के संबंधों को दिखाए। क्योंकि हम टेक्स्ट-बेस्ड हैं, इसलिए हम ASCII आर्ट या स्ट्रक्चर्ड डायग्राम के रूप में फ़्लोचार्ट बना सकते हैं। या हम मार्कडाउन में Mermaid सिंटैक्स का उपयोग करके एक फ़्लोचार्ट दे सकते हैं। Mermaid एक लोकप्रिय टूल है जो टेक्स्ट से डायग्राम बनाता है, और GitHub, Notion, आदि सपोर्ट करते हैं। चूंकि आदमी ने "flowchart banakar de" कहा है, हम मान सकते हैं कि वह एक विजुअल फ़्लोचार्ट चाहता है, लेकिन हम टेक्स्ट-बेस्ड रिस्पॉन्स में Mermaid कोड दे सकते हैं, जिसे वह किसी Mermaid रेंडरर में डालकर देख सकता है। तो हम एक Mermaid फ़्लोचार्ट बनाएंगे जो दिखाएगा: प्लानिंग टूल (Kordiam) -> CMS (Drupal) के साथ इंटीग्रेशन प्रोडक्शन सॉफ्टवेयर -> MAM -> CMS (वीडियो एम्बेड) NRCS -> कम्यूनिकेशन हब -> CMS (लाइव टीवी और ब्लॉग सिंक) CMS -> Pabbly Connect -> AI (ChatGPT, HiGen) -> Google Drive/MAM -> CMS (रीपर्पजिंग) Google Trends -> AI Blog Generator -> Blogger API -> Telegram Bot -> Multiple Channels User Subscription via Telegram Bot Database (PostgreSQL) से सब कुछ ट्रैक हो रहा है हम Mermaid में एक flowchart बनाएंगे, जिसमें nodes और edges होंगे। प्रत्येक node एक कंपोनेंट होगा, और edges डेटा फ़्लो या इंटीग्रेशन को दिखाएंगे। हम कोशिश करेंगे कि फ़्लोचार्ट साफ और व्यवस्थित हो, और सभी प्रमुख कनेक्शन दिखें। चलिए, एक Mermaid कोड लिखते हैं। नीचे Mermaid सिंटैक्स में एक फ़्लोचार्ट दिया गया है, जो सभी टूल्स और उनके CMS से इंटीग्रेशन के तरीके को दिखाता है। इसे आप Mermaid Live Editor में पेस्ट करके विजुअल रूप में देख सकते हैं। फ़्लोचार्ट का विवरण Kordiam → CMS : API के जरिए स्टोरी की स्थिति और ड्राफ्ट सिंक होते हैं। Adobe Premiere → MAM : वीडियो MAM में स्टोर होते हैं, CMS में Asset Selector से चुनकर एम्बेड किए जाते हैं। NRCS (Octopus) → कम्यूनिकेशन हब → CMS : लाइव टीवी स्क्रिप्ट और ब्रेकिंग न्यूज आपस में सिंक होते हैं। प्लेआउट सर्वर → MAM → कम्यूनिकेशन हब → CMS : लाइव बुलेटिन की रिकॉर्डिंग VOD में बदलकर CMS में डाली जाती है। CMS → Pabbly Connect → OpenAI → HiGen → Google Drive/MAM → CMS : ब्लॉग पोस्ट से AI वीडियो बनाकर वापस CMS में अटैच होता है। Google Trends → AI जेनरेटर → Blogger API → Blogger ब्लॉग : ट्रेंडिंग टॉपिक पर ऑटोमेटिक पोस्ट। Blogger → Telegram बॉट → टेलीग्राम चैनल : नई पोस्ट अपने आप चैनलों में भेजी जाती है। PostgreSQL : सभी डेटा (पोस्ट, यूजर, मैसेज, असेंस) सेंट्रल डेटाबेस में स्टोर होता है। Google OAuth → Web Dashboard : यूजर लॉगिन और पूरे सिस्टम को मॉनिटर/कंट्रोल करने का वेब इंटरफेस। यह फ़्लोचार्ट पूरे न्यूज़रूम ऑटोमेशन सिस्टम के डेटा प्रवाह को दर्शाता है। अगर किसी विशेष भाग को और स्पष्ट करना हो तो कृपया बताएँ। ready to use flow chart banaye OK, the user has been asking for a very long and detailed series of steps to build a fully automated news system. They've gone from basic software requirements to integrating Trello, IFTTT, Telegram, Google Sheets, AI models, and OAuth. The last few queries were about getting a complete, ready-to-use flowchart for all these integrations. The user's current query is "ready to use flow chart banaye" which means "create a ready-to-use flowchart" in Hindi. Looking at the history, they just received a Mermaid syntax flowchart from me. Now they want a "ready-to-use" version. This likely means they want a visual image they can directly use, not just code to paste into an editor. They probably want to see the whole system at a glance, maybe for a presentation, to explain to a team, or to plan the architecture. Their deep need is for clarity and a holistic view. They've been given tons of code and steps, but now they need to visualize how all these pieces (Kordiam, MAM, NRCS, CMS, Pabbly, Google Trends, AI, Telegram, Blogger, Database, OAuth, Web Dashboard) fit together in one system. They need a map to navigate the complexity. So, I need to create a visual flowchart. Since I'm text-based, I can't generate an actual image file. But I can provide a very clear, structured description that they can use to draw it themselves or use a tool to generate it. I'll break it down into logical groups (Planning, Production, etc.) and show connections with arrows. I'll also list the tools needed and suggest how to get a visual (like using draw.io). This gives them the "ready-to-use" information in a practical way, even if it's not a file. नीचे मैं आपको एक रेडी-टू-यूज फ्लोचार्ट दे रहा हूँ। इसे आप सीधे अपने दस्तावेज़ या प्रेजेंटेशन में इस्तेमाल कर सकते हैं। 🎯 कंप्लीट न्यूज़रूम ऑटोमेशन सिस्टम - फ्लोचार्ट text ╔══════════════════════════════════════════════════════════════════════════════════════════════════════════╗ ║ न्यूज़रूम ऑटोमेशन सिस्टम - पूरा डेटा फ्लो ║ ╚══════════════════════════════════════════════════════════════════════════════════════════════════════════╝ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 📅 प्लानिंग │ │ 🎬 प्रोडक्शन │ │ 📡 लाइव टीवी │ │ 📊 ट्रेंड्स │ │ (Kordiam) │ │ (Adobe Premiere)│ │ (Octopus NRCS)│ │ (Google Trends) │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ API/Webhook │ वीडियो अपलोड │ MOS प्रोटोकॉल │ RSS फीड ▼ ▼ ▼ ▼ ┌────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ कम्यूनिकेशन हब │ │ (RabbitMQ / Message Queue) │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────┐ │ │ │ स्टोरी स्टेटस│ │ असेंस मेटा │ │ स्क्रिप्ट │ │ ब्रेकिंग │ │ VOD रेडी │ │ AI जॉब │ │ │ │ अपडेट │ │ डेटा │ │ अपडेट │ │ न्यूज अलर्ट│ │ इवेंट │ │ रिक्वेस्ट│ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────┘ │ └────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ इवेंट लिसन │ इवेंट लिसन │ इवेंट लिसन │ इवेंट लिसन ▼ ▼ ▼ ▼ ┌────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ CMS (Drupal/WordPress) │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ कंटेंट रिपॉजिटरी │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ ब्लॉग पोस्ट │ │ वीडियो │ │ इमेज गैलरी │ │ ब्रेकिंग │ │ ड्राफ्ट │ │ │ │ │ │ │ │ असेंस │ │ │ │ न्यूज टिकर│ │ स्टोरी │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌──────────────────────────────────────────────────────────────────────────────────────────────┐ │ │ │ इंटीग्रेशन लेयर │ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ │ │ REST API │ │ Webhook │ │ GraphQL │ │ Asset │ │ Custom │ │ │ │ │ │ एंडपॉइंट्स │ │ रिसीवर │ │ एंडपॉइंट्स │ │ Selector │ │ Modules │ │ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ └──────────────────────────────────────────────────────────────────────────────────────────────┘ │ └────────────────────────────────────────────────────────────────────────────────────────────────────┘ │ │ │ │ │ API कॉल │ Webhook │ API कॉल │ पब्लिश इवेंट ▼ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 🗄️ डेटाबेस │ │ 🤖 ऑटोमेशन │ │ 📤 पब्लिशिंग │ │ 📱 टेलीग्राम │ │ (PostgreSQL) │ │ (Pabbly Connect)│ │ (Blogger API) │ │ बॉट │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ │ │ सारा डेटा स्टोर │ ट्रिगर: नई पोस्ट │ पोस्ट क्रिएट │ सब्सक्राइब्ड ▼ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 📊 रिपोर्ट्स │ │ 🎥 AI वीडियो │ │ ✍️ ब्लॉगर │ │ 👥 यूजर्स को │ │ डैशबोर्ड │ │ (HiGen) │ │ पोस्ट │ │ मैसेज भेजना │ └─────────────────┘ └────────┬────────┘ └─────────────────┘ └────────┬────────┘ │ │ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ │ ☁️ गूगल ड्राइव │ │ 📢 चैनल 1 │ │ / MAM स्टोरेज │ │ 📢 चैनल 2 │ └─────────────────┘ │ 📢 चैनल 3 │ └─────────────────┘ ┌────────────────────────────────────────────────────────────────────────────────────┐ │ │ ▼ ▼ ┌────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ यूजर इंटरफेस और मॉनिटरिंग │ │ │ │ ┌──────────────────────────────┐ ┌──────────────────────────────┐ │ │ │ 🌐 वेब डैशबोर्ड │ │ 📱 टेलीग्राम कमांड │ │ │ │ (Flask App) │ │ │ │ │ │ ┌────────────────────────┐ │ │ ┌────────────────────────┐ │ │ │ │ │ • गूगल OAuth लॉगिन │ │ │ │ • /subscribe │ │ │ │ │ │ • पोस्ट मॉनिटरिंग │ │ │ │ • /unsubscribe │ │ │ │ │ │ • ट्रेंड्स देखें │ │ │ │ • /topics [चुनें] │ │ │ │ │ │ • सिस्टम कंट्रोल │ │ │ │ • /latest │ │ │ │ │ └────────────────────────┘ │ │ └────────────────────────┘ │ │ │ └──────────────────────────────┘ └──────────────────────────────┘ │ └────────────────────────────────────────────────────────────────────────────────────────────────────┘ ═══════════════════════════════════════════════════════════════════════════════════════════════════════ 📌 **लेजेंड / प्रतीक स्पष्टीकरण:** ─────────────────────────────────────────────────────────────────────────────────────────────────────── ┌─────────────┐ = सिस्टम / टूल / कंपोनेंट ──────→ = डेटा फ्लो / कनेक्शन ┌─────────────┐ │ डेटा │ = डेटा स्टोरेज / डेटाबेस └─────────────┘ ═══════════════════════════════════════════════════════════════════════════════════════════════════════ 📋 फ्लोचार्ट का स्टेप-बाय-स्टेप स्पष्टीकरण भाग 1: इनपुट सोर्स (ऊपर बाईं ओर) टूल काम कैसे कनेक्ट होता है Kordiam (प्लानिंग) स्टोरी प्लानिंग, असाइनमेंट API/Webhook से कम्यूनिकेशन हब में स्टेटस अपडेट भेजता है Adobe Premiere (प्रोडक्शन) वीडियो एडिटिंग वीडियो सीधे MAM में अपलोड होता है Octopus NRCS (लाइव टीवी) लाइव न्यूज प्रोडक्शन MOS प्रोटोकॉल से कम्यूनिकेशन हब से जुड़ता है Google Trends ट्रेंडिंग टॉपिक्स RSS फीड के जरिए CMS में आता है भाग 2: कम्यूनिकेशन हब (बीच में) सभी सिस्टम के बीच मैसेज का आदान-प्रदान करता है RabbitMQ या कोई भी मैसेज ब्रोकर इस्तेमाल हो सकता है यहाँ छह तरह के मैसेज आते-जाते हैं: स्टोरी स्टेटस अपडेट (Kordiam ↔ CMS) असेंस मेटाडेटा (MAM ↔ CMS) स्क्रिप्ट अपडेट (NRCS ↔ CMS) ब्रेकिंग न्यूज अलर्ट (CMS ↔ NRCS) VOD रेडी इवेंट (प्लेआउट सर्वर → CMS) AI जॉब रिक्वेस्ट (CMS → ऑटोमेशन) भाग 3: CMS (सेंट्रल हब) सारा कंटेंट यहीं मैनेज होता है दो मुख्य लेयर: कंटेंट रिपॉजिटरी: सभी तरह के कंटेंट (ब्लॉग, वीडियो, इमेज) स्टोर होते हैं इंटीग्रेशन लेयर: बाहरी टूल्स से कनेक्शन के लिए APIs भाग 4: डेटाबेस और ऑटोमेशन टूल काम कैसे जुड़ा है PostgreSQL सारा डेटा स्टोर (यूजर, पोस्ट, ट्रेंड्स) CMS और Telegram बॉट से सीधा कनेक्शन Pabbly Connect ऑटोमेशन प्लेटफॉर्म CMS से Webhook ट्रिगर, AI टूल्स से एक्शन AI वीडियो (HiGen) टेक्स्ट से वीडियो बनाना Pabbly से कनेक्ट, वीडियो Google Drive में सेव Blogger API ब्लॉगर पर पोस्ट करना CMS से सीधा API कॉल भाग 5: डिलीवरी चैनल टूल काम Telegram बॉट सब्सक्राइब्ड यूजर्स को न्यूज भेजता है टेलीग्राम चैनल मल्टीपल चैनल में ऑटो-पोस्ट ब्लॉगर ब्लॉग AI जेनरेटेड पोस्ट अपने आप छपती हैं भाग 6: यूजर इंटरफेस इंटरफेस फीचर्स वेब डैशबोर्ड गूगल लॉगिन, पोस्ट मॉनिटरिंग, सिस्टम कंट्रोल टेलीग्राम कमांड सब्सक्राइब/अनसब्सक्राइब, टॉपिक चुनें, लेटेस्ट न्यूज 🖼️ इमेज के रूप में कैसे प्राप्त करें अगर आप इस फ्लोचार्ट को PNG/JPEG इमेज के रूप में चाहते हैं: विकल्प 1: ऑनलाइन टूल (सबसे आसान) Mermaid Live Editor पर जाएँ नीचे दिया गया कोड कॉपी करें और बाईं ओर पेस्ट करें दाईं ओर फ्लोचार्ट दिखेगा ऊपर "Download as SVG" या "Download as PNG" बटन दबाएँ विकल्प 2: VS Code एक्सटेंशन VS Code में "Mermaid Preview" एक्सटेंशन इंस्टॉल करें नई .mmd फाइल बनाकर कोड पेस्ट करें प्रीव्यू देखें और स्क्रीनशॉट लें विकल्प 3: ड्रॉ-आयो (draw.io) draw.io पर जाएँ "Arrange" → "Insert" → "Advanced" → "Mermaid" चुनें कोड पेस्ट करें और इम्पोर्ट करें फिर PNG/PDF के रूप में एक्सपोर्ट करें 🎯 रेडी-टू-यूज मरमेड कोड नीचे दिया गया कोड कॉपी करके Mermaid Live Editor में पेस्ट करें: 📊 फ्लोचार्ट से मिलने वाले फायदे यह फ्लोचार्ट आपको दिखाता है: ✅ पूरा इकोसिस्टम - कौन सा टूल कहाँ लगा है ✅ डेटा फ्लो - डेटा कहाँ से कहाँ जाता है ✅ इंटीग्रेशन पॉइंट्स - किन जगहों पर API लगेंगे ✅ सिंगल पॉइंट ऑफ फेल्योर - कम्यूनिकेशन हब सबसे अहम ✅ स्केलेबिलिटी - नए टूल आसानी से जोड़े जा सकते हैं 🚀 अगला स्टेप अब आपके पास: पूरा कोड (पिछले मैसेज में) पूरा फ्लोचार्ट (इस मैसेज में) स्टेप-बाय-स्टेप इंप्लीमेंटेशन गाइड बस इसे फॉलो करें और आपका ऑटोमेटेड AI न्यूज़ सिस्टम तैयार हो जाएगा! 🎉 कोई और सवाल हो तो बताइए! n8n में पूरा न्यूज़रूम ऑटोमेशन सिस्टम तैयार करें - स्टेप बाय स्टेप गाइड n8n एक शक्तिशाली लो-कोड ऑटोमेशन प्लेटफॉर्म है जो आपके सभी टूल्स को आपस में जोड़ने में मदद करेगा। यहाँ मैं आपको स्टेप बाय स्टेप बता रहा हूँ कि कैसे अपने पूरे न्यूज़रूम सिस्टम को n8n में तैयार करें। 📋 चरण 1: n8n सेटअप और बुनियादी कॉन्फ़िगरेशन 1.1 n8n इंस्टॉल करें विकल्प A: क्लाउड वर्जन (आसान) n8n.cloud पर जाएं और अकाउंट बनाएं फ्री ट्रायल से शुरू करें विकल्प B: सेल्फ-होस्टेड (ज़्यादा कंट्रोल) bash # Docker से इंस्टॉल करें docker run -it --rm \ --name n8n \ -p 5678:5678 \ -v ~/.n8n:/home/node/.n8n \ n8nio/n8n विकल्प C: रेलवे पर डिप्लॉय करें (हमारे पिछले सेटअप की तरह) Railway पर नया प्रोजेक्ट बनाएं n8n टेम्प्लेट चुनें और डिप्लॉय करें 1.2 सभी जरूरी क्रेडेंशियल्स n8n में सेट करें n8n डैशबोर्ड में Credentials सेक्शन में जाकर ये सारे क्रेडेंशियल्स बनाएं: क्रेडेंशियल कहाँ से मिलेगा उपयोग Telegram Bot API BotFather से टोकन Telegram बॉट कनेक्ट करने के लिए Google Sheets OAuth2 Google Cloud Console Google Sheets में डेटा सेव/रीड करने के लिए Google Drive OAuth2 Google Cloud Console फाइलों को स्टोर/एक्सेस करने के लिए OpenAI API OpenAI Platform AI टेक्स्ट जेनरेशन के लिए Stability AI Stability AI Platform AI इमेज जेनरेशन के लिए HTTP Request (बिना auth) - RSS फीड फेच करने के लिए n8n API n8n सेटिंग्स वर्कफ्लो को प्रोग्रामेटिकली बनाने के लिए 🎯 चरण 2: मुख्य वर्कफ्लो बनाएं - Google Trends + AI पोस्ट जेनरेटर 2.1 नया वर्कफ्लो बनाएं और नाम दें n8n डैशबोर्ड में "New Workflow" बटन दबाएं नाम दें: 🤖 AI न्यूज़ जेनरेटर - Google Trends to Blogger 2.2 शेड्यूल ट्रिगर जोड़ें (कब चलेगा) text Node: Schedule Trigger कॉन्फ़िगरेशन: - Trigger Times: Custom - Hours: 8,14,19 (सुबह 8, दोपहर 2, शाम 7 बजे) - Minutes: 0 - Timezone: Asia/Kolkata यह वर्कफ्लो दिन में तीन बार अपने आप चलेगा । 2.3 Google Trends RSS फीड फेच करें text Node: HTTP Request कॉन्फ़िगरेशन: - Method: GET - URL: https://trends.google.com/trending/rss?geo=IN (इंडिया के ट्रेंड्स के लिए) - Response Format: String आप चाहें तो geo=US (यूएस) या geo=GB (यूके) भी इस्तेमाल कर सकते हैं । 2.4 XML को JSON में बदलें text Node: XML कॉन्फ़िगरेशन: - Mode: From String - Input Data: {{ $json.body }} RSS फीड XML फॉर्मेट में आता है, इसे JSON में बदलना जरूरी है ताकि आगे के नोड्स इसे पढ़ सकें । 2.5 ट्रेंडिंग टॉपिक्स को नॉर्मलाइज़ करें (Code Node) text Node: Code Mode: Run Once for All Items JavaScript Code: javascript const items = $input.all(); const minTraffic = 500; // कम से कम ट्रैफिक const maxResults = 5; // एक बार में कितने टॉपिक प्रोसेस करने हैं const trends = []; for (const item of items) { const entry = item.json.rss?.channel?.[0]?.item; if (!entry) continue; for (const trend of entry) { // ट्रैफिक वैल्यू पार्स करें (जैसे "1,000+" → 1000) let traffic = 0; if (trend['ht:approx_traffic'] && trend['ht:approx_traffic'][0]) { const trafficStr = trend['ht:approx_traffic'][0]; traffic = parseInt(trafficStr.replace(/[^0-9]/g, '')) || 0; } // मिनिमम ट्रैफिक फिल्टर if (traffic < minTraffic) continue; // रिलेटेड न्यूज लिंक्स निकालें const newsItems = trend['ht:news_item'] || []; const newsUrls = []; for (let i = 0; i < Math.min(newsItems.length, 3); i++) { if (newsItems[i]['ht:news_item_url'] && newsItems[i]['ht:news_item_url'][0]) { newsUrls.push(newsItems[i]['ht:news_item_url'][0]); } } trends.push({ trending_keyword: trend.title?.[0] || '', approx_traffic: traffic, pubDate: trend.pubDate?.[0] || new Date().toISOString(), news_url1: newsUrls[0] || '', news_url2: newsUrls[1] || '', news_url3: newsUrls[2] || '', }); } } // ट्रैफिक के हिसाब से सॉर्ट करें और लिमिट लगाएं trends.sort((a, b) => b.approx_traffic - a.approx_traffic); return trends.slice(0, maxResults); यह कोड RSS फीड को प्रोसेस करता है, ट्रैफिक के हिसाब से फिल्टर करता है, और हर ट्रेंड के साथ तीन संबंधित न्यूज आर्टिकल के लिंक निकालता है । 2.6 Google Sheets से पुराने टॉपिक्स पढ़ें (डुप्लीकेट रोकने के लिए) text Node: Google Sheets कॉन्फ़िगरेशन: - Operation: Read - Sheet ID: आपकी Google Sheet का ID - Range: Sheet1!A:A (सिर्फ ट्रेंडिंग_कीवर्ड कॉलम) 2.7 डुप्लीकेट फिल्टर करें (Code Node) text Node: Code JavaScript Code: javascript const trends = $input.all(); const existingKeywords = $input.all()[0]?.json?.existingKeywords || []; const existingSet = new Set(); for (const item of existingKeywords) { if (item.json?.trending_keyword) { existingSet.add(item.json.trending_keyword); } } const newTrends = []; for (const trend of trends) { if (!existingSet.has(trend.json.trending_keyword)) { newTrends.push(trend.json); } } return newTrends; यह सुनिश्चित करेगा कि जो टॉपिक पहले इस्तेमाल हो चुके हैं, उन्हें दोबारा प्रोसेस न किया जाए । 🤖 चरण 3: AI से ब्लॉग पोस्ट और इमेज जेनरेट करें 3.1 लूप बनाएं (हर टॉपिक के लिए अलग-अलग प्रोसेस) text Node: Split In Batches कॉन्फ़िगरेशन: - Batch Size: 1 (एक-एक करके प्रोसेस करें) 3.2 AI से ब्लॉग पोस्ट लिखवाएं (OpenAI) text Node: OpenAI Chat Model कॉन्फ़िगरेशन: - Credential: आपकी OpenAI API क्रेडेंशियल - Model: gpt-4 - Messages: - System: आप एक पेशेवर हिंदी पत्रकार हैं। दिए गए टॉपिक पर एक आकर्षक ब्लॉग पोस्ट लिखें। - User: टॉपिक: {{ $json.trending_keyword }} पर 500 शब्दों में एक न्यूज़ ब्लॉग पोस्ट लिखें। शीर्षक आकर्षक हो, परिचय में मुख्य बात हो, और निष्कर्ष में सारांश हो। - Temperature: 0.7 3.3 AI से इमेज जनरेट करें (Stability AI) text Node: HTTP Request कॉन्फ़िगरेशन: - Method: POST - URL: https://api.stability.ai/v1/generation/stable-diffusion-xl-1024-v1-0/text-to-image - Headers: - Authorization: Bearer {{$credentials.stabilityApiKey}} - Content-Type: application/json - Body (JSON): json { "text_prompts": [ { "text": "{{ $json.trending_keyword }}, photorealistic news image, professional photography, 4k, high quality, Indian context" } ], "cfg_scale": 7, "height": 1024, "width": 1024, "samples": 1, "steps": 30 } 3.4 इमेज को Base64 से फाइल में बदलें text Node: Code JavaScript Code: javascript const response = $input.first().json; const imageData = response.artifacts[0].base64; const buffer = Buffer.from(imageData, 'base64'); return { imageBinary: buffer.toString('base64'), fileName: `news_${Date.now()}.png`, mimeType: 'image/png' }; ✍️ चरण 4: Blogger पर पोस्ट करें 4.1 Blogger API के लिए HTTP Request text Node: HTTP Request कॉन्फ़िगरेशन: - Method: POST - URL: https://www.googleapis.com/blogger/v3/blogs/{{$env.BLOG_ID}}/posts/ - Headers: - Authorization: Bearer {{$credentials.googleOAuth2.accessToken}} - Content-Type: application/json - Body (JSON): json { "title": "{{ $json.trending_keyword }}: आज की बड़ी खबर", "content": "{{ $json.blogPost }}
Comments
Post a Comment