update
This commit is contained in:
+33
-11
@@ -25,6 +25,8 @@ LOG_FILE = "/home/shane/foodie_automator/logs/foodie_engagement_tweet.log"
|
|||||||
LOG_PRUNE_DAYS = 30
|
LOG_PRUNE_DAYS = 30
|
||||||
MAX_RETRIES = 3
|
MAX_RETRIES = 3
|
||||||
RETRY_BACKOFF = 2
|
RETRY_BACKOFF = 2
|
||||||
|
URL = "https://insiderfoodie.com"
|
||||||
|
URL_SHORTENED_LENGTH = 23 # Twitter's shortened URL length
|
||||||
|
|
||||||
def setup_logging():
|
def setup_logging():
|
||||||
"""Initialize logging with pruning of old logs."""
|
"""Initialize logging with pruning of old logs."""
|
||||||
@@ -191,7 +193,7 @@ def generate_engagement_tweet(author):
|
|||||||
f"Generate an engagement tweet for {author_handle} asking a question about {theme} to engage the public. "
|
f"Generate an engagement tweet for {author_handle} asking a question about {theme} to engage the public. "
|
||||||
f"Keep it under 230 characters to ensure room for the URL. "
|
f"Keep it under 230 characters to ensure room for the URL. "
|
||||||
f"Use {persona_config['tone']}. "
|
f"Use {persona_config['tone']}. "
|
||||||
f"Include a call to action to follow {author_handle} or like the tweet, and mention InsiderFoodie.com with a link to https://insiderfoodie.com. "
|
f"Include a call to action to follow {author_handle} or like the tweet, followed by the URL {URL} (do not mention InsiderFoodie.com separately in the text). "
|
||||||
f"Avoid using the word 'elevate'—use more humanized language like 'level up' or 'bring to life'. "
|
f"Avoid using the word 'elevate'—use more humanized language like 'level up' or 'bring to life'. "
|
||||||
f"Do not include emojis, hashtags, or reward-driven incentives (e.g., giveaways). "
|
f"Do not include emojis, hashtags, or reward-driven incentives (e.g., giveaways). "
|
||||||
f"Return only the tweet text."
|
f"Return only the tweet text."
|
||||||
@@ -205,15 +207,32 @@ def generate_engagement_tweet(author):
|
|||||||
{"role": "system", "content": "You are a social media expert crafting engaging tweets."},
|
{"role": "system", "content": "You are a social media expert crafting engaging tweets."},
|
||||||
{"role": "user", "content": prompt}
|
{"role": "user", "content": prompt}
|
||||||
],
|
],
|
||||||
max_tokens=80, # Reduced to ensure shorter tweets
|
max_tokens=80,
|
||||||
temperature=0.7
|
temperature=0.7
|
||||||
)
|
)
|
||||||
tweet = response.choices[0].message.content.strip()
|
tweet = response.choices[0].message.content.strip()
|
||||||
# Ensure tweet length is within limits (accounting for URL)
|
# Check for duplicate URLs and remove if present
|
||||||
url_length = 23 # Twitter shortens URLs
|
url_count = tweet.lower().count(URL.lower())
|
||||||
if len(tweet) > (280 - url_length):
|
if url_count > 1:
|
||||||
tweet = tweet[:(280 - url_length - 3)] + "..."
|
logging.warning(f"Generated tweet for {username} contains duplicate URLs: {tweet}")
|
||||||
logging.debug(f"Generated engagement tweet for {username}: {tweet}")
|
# Keep only the last occurrence of the URL
|
||||||
|
last_url_pos = tweet.rfind(URL)
|
||||||
|
tweet = tweet[:last_url_pos].replace(URL, "").strip() + " " + URL
|
||||||
|
logging.debug(f"Revised tweet after removing duplicate URL: {tweet}")
|
||||||
|
|
||||||
|
# Ensure the URL is at the end of the tweet
|
||||||
|
if not tweet.endswith(URL):
|
||||||
|
tweet = tweet.replace(URL, "").strip() + " " + URL
|
||||||
|
|
||||||
|
# Calculate tweet length considering Twitter's URL shortening
|
||||||
|
tweet_without_url = tweet.replace(URL, "")
|
||||||
|
total_length = len(tweet_without_url) + URL_SHORTENED_LENGTH
|
||||||
|
if total_length > 280:
|
||||||
|
logging.warning(f"Tweet for {username} exceeds 280 characters ({total_length}), truncating")
|
||||||
|
tweet_without_url = tweet_without_url[:(280 - URL_SHORTENED_LENGTH - 3)]
|
||||||
|
tweet = tweet_without_url + "..." + " " + URL
|
||||||
|
total_length = len(tweet_without_url) + 3 + URL_SHORTENED_LENGTH
|
||||||
|
logging.debug(f"Final tweet for {username} (length {total_length}): {tweet}")
|
||||||
return tweet
|
return tweet
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.warning(f"Failed to generate engagement tweet for {username} (attempt {attempt + 1}): {e}")
|
logging.warning(f"Failed to generate engagement tweet for {username} (attempt {attempt + 1}): {e}")
|
||||||
@@ -222,11 +241,14 @@ def generate_engagement_tweet(author):
|
|||||||
else:
|
else:
|
||||||
logging.error(f"Failed to generate engagement tweet after {MAX_RETRIES} attempts")
|
logging.error(f"Failed to generate engagement tweet after {MAX_RETRIES} attempts")
|
||||||
fallback = (
|
fallback = (
|
||||||
f"What's the hottest {theme}? Share and follow {author_handle} for more on InsiderFoodie.com! "
|
f"What's the hottest {theme}? Share and follow {author_handle} for more! {URL}"
|
||||||
f"https://insiderfoodie.com"
|
|
||||||
)
|
)
|
||||||
if len(fallback) > (280 - url_length):
|
# Ensure fallback tweet is within length limits
|
||||||
fallback = fallback[:(280 - url_length - 3)] + "..."
|
tweet_without_url = fallback.replace(URL, "")
|
||||||
|
total_length = len(tweet_without_url) + URL_SHORTENED_LENGTH
|
||||||
|
if total_length > 280:
|
||||||
|
tweet_without_url = tweet_without_url[:(280 - URL_SHORTENED_LENGTH - 3)]
|
||||||
|
fallback = tweet_without_url + "..." + " " + URL
|
||||||
logging.info(f"Using fallback engagement tweet: {fallback}")
|
logging.info(f"Using fallback engagement tweet: {fallback}")
|
||||||
return fallback
|
return fallback
|
||||||
return None
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user