File size: 6,357 Bytes
5e0e3eb 12a002e b2b218d 5e0e3eb 12a002e b2b218d 12a002e b2b218d 5e0e3eb 12a002e 5e0e3eb ab7fa87 5e0e3eb 12a002e 5e0e3eb 12a002e b2b218d ddf7731 b2b218d ddf7731 b2b218d 12a002e 5e0e3eb b2b218d 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e b2b218d 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb b2b218d 5e0e3eb 12a002e 5e0e3eb 12a002e 5e0e3eb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
import os
import logging
import asyncio
import nest_asyncio
import requests
from hugchat import hugchat
from hugchat.login import Login
# Import Telegram bot components
from telegram import Update, Bot
from telegram.ext import Application, CommandHandler, MessageHandler, filters, CallbackContext
# -------------------------
# Load environment variables
# -------------------------
# Expected environment variables:
# TELEGRAM_BOT_TOKEN - Telegram bot token
# WEBHOOK_DOMAIN - your-space.hf.space
# HF_EMAIL and HF_PASSWORD
TELEGRAM_BOT_TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
if not TELEGRAM_BOT_TOKEN:
raise ValueError("Missing TELEGRAM_BOT_TOKEN environment variable.")
WEBHOOK_DOMAIN = os.getenv("WEBHOOK_DOMAIN")
if not WEBHOOK_DOMAIN:
raise ValueError("Missing WEBHOOK_DOMAIN environment variable.")
HF_EMAIL = os.getenv("HF_EMAIL")
if not HF_EMAIL:
raise ValueError("Missing HF_EMAIL environment variable.")
HF_PASSWORD = os.getenv("HF_PASSWORD")
if not HF_PASSWORD:
raise ValueError("Missing HF_PASSWORD environment variable.")
# -------------------------
# Configure logging
# -------------------------
logging.basicConfig(format="%(asctime)s - %(levelname)s - %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)
# -------------------------
# Set up Hugging Chat integration
# -------------------------
# Logs into Hugging Face or uses a fallback to get cookies.
try:
logger.info("Logging into Hugging Face using provided credentials.")
sign = Login(HF_EMAIL, HF_PASSWORD)
cookies = sign.login()
print("cookies: ", cookies)
except Exception as e:
logger.error(f"Error in Logging-into Hugging Chat: {e}")
logger.info("Using fallback method to get cookies.")
cookies = requests.get("https://huggingface.co/chat/").cookies
# Create a ChatBot instance from the hugchat library.
chatbot = hugchat.ChatBot(cookies=cookies.get_dict())
# -------------------------
# Helper Functions
# -------------------------
def detect_language(user_input: str) -> str:
"""
Detect language using langid.
Returns 'hebrew' if Hebrew, 'english' if English, otherwise 'unsupported'.
"""
try:
import langid
lang, _ = langid.classify(user_input)
if lang == "he":
return "hebrew"
elif lang == "en":
return "english"
else:
return "unsupported"
except Exception as e:
logger.error(f"Language detection error: {e}")
return "unsupported"
def generate_response_sync(message: str) -> str:
"""
Generate a response using Hugging Chat in a synchronous manner.
This function is blocking; we'll run it in an executor.
"""
language = detect_language(message)
if language == "hebrew":
prompt = "תענה בקצרה אבל תשתף את תהליך קבלת ההחלטות שלך, " + message
elif language == "english":
prompt = "keep it short but tell your decision making process, " + message
else:
return "Sorry, I only support Hebrew and English."
response_queue = ""
full_response = ""
try:
# The huggingchat.ChatBot.chat() method returns a generator (streaming tokens)
for resp in chatbot.chat(prompt, _stream_yield_all=True):
if resp and "token" in resp:
response_queue += resp["token"]
# Flush the response if it's long (optional, here we accumulate)
full_response = response_queue
return full_response
except Exception as e:
logger.error(f"Error generating response via Hugging Chat: {e}")
return "Error: Could not generate response."
async def generate_response(message: str) -> str:
"""
Asynchronous wrapper around generate_response_sync using run_in_executor.
"""
loop = asyncio.get_event_loop()
response = await loop.run_in_executor(None, generate_response_sync, message)
return response
# -------------------------
# Telegram Bot Handlers
# -------------------------
async def start(update: Update, context: CallbackContext):
"""
Handler for the /start command.
"""
await update.message.reply_text("Hello! Tell me your decision-making issue, and I'll try to help.")
logger.info("Received /start command.")
async def handle_message(update: Update, context: CallbackContext):
"""
Handler for incoming text messages.
It generates a response using the Hugging Chat integration.
"""
user_text = update.message.text
logger.info(f"Received message: {user_text}")
response_text = await generate_response(user_text)
logger.info(f"Generated response: {response_text}")
await update.message.reply_text(response_text)
# -------------------------
# Webhook Configuration for Telegram
# -------------------------
# Construct the full webhook URL.
# We use the bot token as the URL path for uniqueness.
WEBHOOK_URL = f"https://{WEBHOOK_DOMAIN}/{TELEGRAM_BOT_TOKEN}"
# -------------------------
# Main function to run the Telegram Bot using Webhook mode
# -------------------------
async def main():
# Build the Telegram Application.
application = Application.builder().token(TELEGRAM_BOT_TOKEN).build()
# Add handlers.
application.add_handler(CommandHandler("start", start))
application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
logger.info("Starting bot in webhook mode...")
print("Starting bot in webhook mode...")
# Run the bot using webhook mode.
await application.run_webhook(
listen="0.0.0.0", # Listen on all interfaces.
port=7860, # Port to listen on – must match the exposed port in Dockerfile.
url_path=TELEGRAM_BOT_TOKEN, # Use the bot token as the URL path.
webhook_url=WEBHOOK_URL # Full webhook URL that Telegram will call.
)
# -------------------------
# Run the main function (handling event loop issues)
# -------------------------
if __name__ == "__main__":
# Apply nest_asyncio to support nested event loops (useful in HF Spaces).
nest_asyncio.apply()
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
except Exception as e:
logger.error(f"Error in main loop: {e}")
print(f"Error in main loop: {e}")
|