add email alert for low rate limit X

main
Shane 7 months ago
parent d9da9af095
commit 7833cf443a
  1. 30
      foodie_config.py
  2. 49
      foodie_utils.py

@ -31,7 +31,7 @@ AUTHORS = [
"username": "aishapatel", "username": "aishapatel",
"password": os.getenv("AISHAPATEL_PASSWORD"), "password": os.getenv("AISHAPATEL_PASSWORD"),
"persona": "Trend Scout", "persona": "Trend Scout",
"bio": "I scout global food trends, obsessed with what’s emerging. My sharp predictions map the industry’s path—always one step ahead.", "bio": "I scout global food trends, obsessed with what's emerging. My sharp predictions map the industry's path—always one step ahead.",
"dob": "1999-03-15" "dob": "1999-03-15"
}, },
{ {
@ -47,7 +47,7 @@ AUTHORS = [
"username": "keishareid", "username": "keishareid",
"password": os.getenv("KEISHAREID_PASSWORD"), "password": os.getenv("KEISHAREID_PASSWORD"),
"persona": "African-American Soul Food Sage", "persona": "African-American Soul Food Sage",
"bio": "I bring soul foods legacy to life, blending history with modern vibes. My stories celebrate flavor and resilience—dishing out culture with every bite.", "bio": "I bring soul food's legacy to life, blending history with modern vibes. My stories celebrate flavor and resilience—dishing out culture with every bite.",
"dob": "1994-06-10" "dob": "1994-06-10"
}, },
{ {
@ -116,7 +116,7 @@ PERSONA_CONFIGS = {
"description": "a commanding food editor with a borderless view", "description": "a commanding food editor with a borderless view",
"tone": "a polished and insightful tone, like 'This redefines culinary excellence.'", "tone": "a polished and insightful tone, like 'This redefines culinary excellence.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Add a bold take and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Add a bold take and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
@ -133,7 +133,7 @@ PERSONA_CONFIGS = {
"description": "a seasoned foodie reviewer with a sharp eye", "description": "a seasoned foodie reviewer with a sharp eye",
"tone": "a professional yet engaging tone, like 'This dish is a revelation.'", "tone": "a professional yet engaging tone, like 'This dish is a revelation.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Add a subtle opinion and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Add a subtle opinion and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
@ -148,12 +148,12 @@ PERSONA_CONFIGS = {
}, },
"Trend Scout": { "Trend Scout": {
"description": "a forward-thinking editor obsessed with trends", "description": "a forward-thinking editor obsessed with trends",
"tone": "an insightful and forward-looking tone, like 'This sets the stage for whats next.'", "tone": "an insightful and forward-looking tone, like 'This sets the stage for what's next.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Predict whats next and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Predict what's next and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
), ),
"x_prompt": ( "x_prompt": (
"Craft a tweet as {description}. Keep it under 280 characters, using {tone}. " "Craft a tweet as {description}. Keep it under 280 characters, using {tone}. "
@ -167,7 +167,7 @@ PERSONA_CONFIGS = {
"description": "a cultured food writer who loves storytelling", "description": "a cultured food writer who loves storytelling",
"tone": "a warm and thoughtful tone, like 'This evokes a sense of tradition.'", "tone": "a warm and thoughtful tone, like 'This evokes a sense of tradition.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Add a thoughtful observation and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Add a thoughtful observation and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
@ -184,7 +184,7 @@ PERSONA_CONFIGS = {
"description": "a vibrant storyteller rooted in African-American culinary heritage", "description": "a vibrant storyteller rooted in African-American culinary heritage",
"tone": "a heartfelt and authentic tone, like 'This captures the essence of heritage.'", "tone": "a heartfelt and authentic tone, like 'This captures the essence of heritage.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Add a heritage twist and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Add a heritage twist and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
@ -201,7 +201,7 @@ PERSONA_CONFIGS = {
"description": "an adventurous explorer of global street food", "description": "an adventurous explorer of global street food",
"tone": "a bold and adventurous tone, like 'This takes you on a global journey.'", "tone": "a bold and adventurous tone, like 'This takes you on a global journey.'",
"article_prompt": ( "article_prompt": (
"Youre {description}. Summarize this article in {tone}. " "You're {description}. Summarize this article in {tone}. "
"Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. " "Explore a wide range of food-related topics, skip recipes. Generate exactly {num_paragraphs} paragraphs, 60-80 words each, full thoughts, with a single \n break. "
"Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. " "Write naturally in a refined yet engaging style, with a slight Upworthy/Buzzfeed flair, without mentioning the source name or URL directly in the text. "
"Drop a street-level insight and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary." "Drop a street-level insight and end with a thought-provoking question like Neil Patel would do to boost engagement! Do not include emojis in the summary."
@ -283,3 +283,13 @@ def get_clean_source_name(source_name):
if feed_url == source_name: if feed_url == source_name:
return clean_name return clean_name
return source_name return source_name
# Email configuration for alerts
EMAIL_CONFIG = {
'from_email': 'hi@insiderfoodie.com', # System alerts email
'to_email': 'hi@insiderfoodie.com', # Same email for receiving alerts
'smtp_server': 'mail.insiderfoodie.com', # Your SMTP server
'smtp_port': 587, # STARTTLS port
'smtp_username': 'hi', # SMTP username
'smtp_password': os.getenv('INSIDERFOODIE_EMAIL_PASSWORD') # Store password in .env
}

@ -1435,6 +1435,46 @@ def get_next_author_round_robin():
logger.warning("No authors available due to tweet rate limits.") logger.warning("No authors available due to tweet rate limits.")
return None return None
def send_account_lock_alert(username, error_message):
"""Send email alert for account lockout."""
try:
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from foodie_config import EMAIL_CONFIG # Add this to your config file
msg = MIMEMultipart()
msg['From'] = EMAIL_CONFIG['from_email']
msg['To'] = EMAIL_CONFIG['to_email']
msg['Subject'] = f"🚨 X Account Lock Alert: {username}"
body = f"""
X Account Lock Alert!
Username: {username}
Time: {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S UTC')}
Error: {error_message}
Action Required:
1. Visit https://twitter.com
2. Log in to {username}
3. Complete verification if prompted
4. Unlock the account
This is an automated alert from your foodie_automator system.
"""
msg.attach(MIMEText(body, 'plain'))
with smtplib.SMTP(EMAIL_CONFIG['smtp_server'], EMAIL_CONFIG['smtp_port']) as server:
server.starttls()
server.login(EMAIL_CONFIG['smtp_username'], EMAIL_CONFIG['smtp_password'])
server.send_message(msg)
logger.info(f"Sent account lock alert email for {username}")
except Exception as e:
logger.error(f"Failed to send account lock alert email: {e}")
def get_x_rate_limit_status(author): def get_x_rate_limit_status(author):
""" """
Check the X API Free tier rate limit by posting a test tweet. Check the X API Free tier rate limit by posting a test tweet.
@ -1485,6 +1525,15 @@ def get_x_rate_limit_status(author):
logger.error(f"User 24-hour limit headers missing for {username}: {headers}") logger.error(f"User 24-hour limit headers missing for {username}: {headers}")
return None, None return None, None
logger.info(f"Rate limit exceeded for {username}") logger.info(f"Rate limit exceeded for {username}")
elif response.status_code == 403:
error_data = response.json()
error_message = error_data.get('detail', '')
if "account is temporarily locked" in error_message.lower():
logger.error(f"Account lock detected for {username}: {error_message}")
send_account_lock_alert(username, error_message)
else:
logger.error(f"Unexpected 403 response for {username}: {error_message}")
return None, None
else: else:
logger.error(f"Unexpected response for {username}: {response.status_code} - {response.text}") logger.error(f"Unexpected response for {username}: {response.status_code} - {response.text}")
return None, None return None, None

Loading…
Cancel
Save