binrsbot / app.py
rbinrs's picture
Update app.py
68dd40a verified
Raw
History Blame Contribute Delete
16.7 kB
import os
import time
import logging
import requests
from telegram import Update, ChatAction
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
from telegram.error import NetworkError, TimedOut
# Configure logging
logging.basicConfig(
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO
)
logger = logging.getLogger(__name__)
# Get bot token from environment variable
BOT_TOKEN = os.environ.get('TELEGRAM_BOT_TOKEN', '7954256043:AAGtQ1Gskf3Hku_Zn2OLYWHsPg51P9T2TuQ')
# Proxy configuration (optional)
PROXY_URL = os.environ.get('PROXY_URL', '')
def hello(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
intro_text = """
🤖 Greetings human!
🤗 I'm a bot hosted on @binrsbot.
🦾 Try me.
✉️ Send me a text to start and I shall generate a response to complete it text!
‼️ PS: Responses are generated by WormGPT AI model and are not my own. I'm not conscious (yet).
👨‍💻 Coded By: Telegram: @rbinrs and @binrsbot
"""
update.message.reply_text(intro_text)
def help_command(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /help is issued."""
help_text = """
📚 *Help Menu*
/start - Start the bot and see intro
/help - Show this help message
💡 *How to use:*
Simply send me any text and I'll generate a response to complete it using AI!
🔧 *Features:*
• AI-powered text completion
• Fast responses
• 24/7 availability
❓ *Need help?*
Contact: @rbinrs or @binrsbot
"""
update.message.reply_text(help_text, parse_mode='Markdown')
def get_gpt_response(text):
"""Get response from your Hugging Face Space."""
try:
logger.info(f"Getting GPT response for: {text[:50]}...")
# Make request to your Hugging Face Space
r = requests.post(
url="https://hf.space/embed/rbinrs/binrsbot/+/api/predict/",
json={"data": [text]},
timeout=15
)
if r.status_code == 200:
response = r.json()
if "data" in response and len(response["data"]) > 0:
return response["data"][0]
else:
logger.error("Invalid response format from GPT API")
return "Sorry, I received an invalid response from my AI brain. Please try again."
else:
logger.error(f"GPT API returned status code: {r.status_code}")
return f"Sorry, my AI brain is having issues (Error {r.status_code}). Please try again later."
except requests.exceptions.Timeout:
logger.error("Timeout when calling GPT API")
return "Sorry, my AI brain is taking too long to respond. Please try again."
except requests.exceptions.ConnectionError:
logger.error("Connection error when calling GPT API")
return "Sorry, I can't connect to my AI brain right now. Please try again later."
except requests.exceptions.RequestException as e:
logger.error(f"Request error when calling GPT API: {e}")
return "Sorry, I'm having trouble connecting to my AI brain. Please try again later."
except Exception as e:
logger.error(f"Unexpected error getting GPT response: {e}")
return "Sorry, something unexpected happened. Please try again later."
def respond_to_user(update: Update, context: CallbackContext):
"""Respond to user messages."""
try:
# Show typing action
update.message.chat.send_action(action=ChatAction.TYPING)
# Get user message
user_text = update.message.text
logger.info(f"Received message from user {update.message.from_user.id}: {user_text[:50]}...")
# Get AI response
response_text = get_gpt_response(user_text)
# Send response
update.message.reply_text(response_text)
logger.info("Response sent successfully")
except Exception as e:
logger.error(f"Error responding to user: {e}")
try:
update.message.reply_text("Sorry, something went wrong while processing your message. Please try again.")
except:
logger.error("Could not send error message to user")
def error_handler(update: Update, context: CallbackContext):
"""Log Errors caused by Updates."""
logger.warning(f'Update "{update}" caused error "{context.error}"')
def test_direct_connectivity():
"""Test direct connectivity to Telegram API."""
logger.info("Testing direct connectivity to Telegram API...")
try:
response = requests.get('https://api.telegram.org', timeout=5)
if response.status_code == 200:
logger.info("✓ Direct connection to Telegram API works")
return True
else:
logger.error(f"✗ Telegram API returned status code: {response.status_code}")
return False
except requests.exceptions.RequestException as e:
logger.error(f"✗ Cannot reach Telegram API directly: {e}")
return False
def test_proxy_connectivity():
"""Test connectivity to Telegram API via proxy."""
if not PROXY_URL:
logger.info("No proxy URL provided, skipping proxy test")
return False
logger.info(f"Testing connectivity via proxy: {PROXY_URL}")
try:
proxies = {
'http': PROXY_URL,
'https': PROXY_URL
}
response = requests.get('https://api.telegram.org', timeout=5, proxies=proxies)
if response.status_code == 200:
logger.info("✓ Connection to Telegram API via proxy works")
return True
else:
logger.error(f"✗ Telegram API via proxy returned status code: {response.status_code}")
return False
except requests.exceptions.RequestException as e:
logger.error(f"✗ Cannot reach Telegram API via proxy: {e}")
return False
def start_bot_with_retry(updater, max_retries=5, initial_delay=5):
"""Start the bot with retry logic."""
delay = initial_delay
for attempt in range(max_retries):
try:
logger.info(f"Attempt {attempt + 1} to start bot...")
updater.start_polling(drop_pending_updates=True)
logger.info("✓ Bot started successfully!")
return True
except NetworkError as e:
logger.error(f"Network error (attempt {attempt + 1}): {e}")
if attempt < max_retries - 1:
logger.info(f"Retrying in {delay} seconds...")
time.sleep(delay)
delay *= 2 # Exponential backoff
else:
logger.error("Max retries reached. Giving up.")
return False
except Exception as e:
logger.error(f"Unexpected error: {e}")
return False
def main():
"""Start the bot."""
logger.info("🚀 Starting AI Assistant Bot...")
# Test connectivity methods
direct_connectivity = test_direct_connectivity()
proxy_connectivity = test_proxy_connectivity() if PROXY_URL else False
# Determine connection method
if direct_connectivity:
logger.info("✅ Using direct connection to Telegram API")
request_kwargs = {}
elif proxy_connectivity:
logger.info("✅ Using proxy connection to Telegram API")
request_kwargs = {
'proxy_url': PROXY_URL,
'urllib3_proxy_kwargs': {
'assert_hostname': False,
'cert_reqs': 'ssl.CERT_NONE'
}
}
else:
logger.error("❌ All connectivity tests failed - cannot start bot")
logger.info("🔄 Starting in offline mode (web interface only)")
# Start a simple web server to show the bot is running
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/')
def index():
return render_template_string("""
<!DOCTYPE html>
<html>
<head>
<title>AI Assistant Bot</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
}
.status {
padding: 10px;
border-radius: 5px;
margin: 10px 0;
}
.error {
background-color: #ffebee;
color: #c62828;
}
.info {
background-color: #e3f2fd;
color: #1565c0;
}
.test-form {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
input[type="text"] {
width: 70%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 8px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.response {
margin-top: 15px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
white-space: pre-wrap;
}
</style>
</head>
<body>
<div class="container">
<h1>🤖 AI Assistant Bot</h1>
<div class="status error">
<strong>⚠️ Bot Status:</strong> Cannot connect to Telegram API
</div>
<div class="status info">
<strong>ℹ️ Issue:</strong> Network restrictions in this environment prevent direct connection to Telegram's servers.
</div>
<div class="test-form">
<h3>🧪 Test AI Response</h3>
<p>You can test the AI response functionality here:</p>
<form method="post" action="/test">
<input type="text" name="text" placeholder="Enter some text..." required>
<button type="submit">Get AI Response</button>
</form>
{% if response %}
<div class="response">
<strong>AI Response:</strong><br>
{{ response }}
</div>
{% endif %}
</div>
<div class="status info">
<strong>💡 Solutions:</strong>
<ul>
<li>Try using a different hosting service that allows outbound connections</li>
<li>Set up a proxy server and add PROXY_URL environment variable</li>
<li>Contact Hugging Face support about network restrictions</li>
</ul>
</div>
</div>
</body>
</html>
""")
@app.route('/test', methods=['POST'])
def test_ai():
text = request.form.get('text', '')
response = get_gpt_response(text)
return render_template_string("""
<!DOCTYPE html>
<html>
<head>
<title>AI Assistant Bot</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
h1 {
color: #333;
}
.status {
padding: 10px;
border-radius: 5px;
margin: 10px 0;
}
.error {
background-color: #ffebee;
color: #c62828;
}
.info {
background-color: #e3f2fd;
color: #1565c0;
}
.test-form {
margin-top: 20px;
padding: 15px;
border: 1px solid #ddd;
border-radius: 5px;
}
input[type="text"] {
width: 70%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 8px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.response {
margin-top: 15px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 5px;
white-space: pre-wrap;
}
</style>
</head>
<body>
<div class="container">
<h1>🤖 AI Assistant Bot</h1>
<div class="status error">
<strong>⚠️ Bot Status:</strong> Cannot connect to Telegram API
</div>
<div class="test-form">
<h3>🧪 Test AI Response</h3>
<form method="post" action="/test">
<input type="text" name="text" placeholder="Enter some text..." required>
<button type="submit">Get AI Response</button>
</form>
<div class="response">
<strong>AI Response:</strong><br>
{{ response }}
</div>
</div>
<p><a href="/">← Back to main page</a></p>
</div>
</body>
</html>
""", response=response)
app.run(host='0.0.0.0', port=7860)
return
# Create the Updater with appropriate connection settings
updater = Updater(
token=BOT_TOKEN,
use_context=True,
request_kwargs=request_kwargs
)
dispatcher = updater.dispatcher
# Register handlers
dispatcher.add_handler(CommandHandler("start", hello))
dispatcher.add_handler(CommandHandler("help", help_command))
dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, respond_to_user))
# Log all errors
dispatcher.add_error_handler(error_handler)
# Start the Bot with retry logic
if start_bot_with_retry(updater):
logger.info("✅ Bot is running...")
# Run the bot until you press Ctrl-C
updater.idle()
else:
logger.error("❌ Failed to start bot after multiple attempts")
if __name__ == '__main__':
main()