0

Locally, my Twitter bot runs fine but when I deploy it on Heroku it crashes with this error. Locally, everything is fine and when I run it, it tweets, likes and even retweets but on heroku it says it has crashed.

2022-08-23T10:13:38.309984+00:00 app[worker.1]:     api.update_status(get_quote())
2022-08-23T10:13:38.309993+00:00 app[worker.1]:   File "/app/app.py", line 59, in get_quote
2022-08-23T10:13:38.310053+00:00 app[worker.1]:     read_f = json.load(f)
2022-08-23T10:13:38.310062+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/json/__init__.py", line 293, in load
2022-08-23T10:13:38.310195+00:00 app[worker.1]:     return loads(fp.read(),
2022-08-23T10:13:38.310198+00:00 app[worker.1]:   File "/app/.heroku/python/lib/python3.9/codecs.py", line 322, in decode
2022-08-23T10:13:38.310309+00:00 app[worker.1]:     (result, consumed) = self._buffer_decode(data, self.errors, final)
2022-08-23T10:13:38.310322+00:00 app[worker.1]: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 12: invalid start byte
2022-08-23T10:13:38.453938+00:00 heroku[worker.1]: Process exited with status 1
2022-08-23T10:13:38.552988+00:00 heroku[worker.1]: State changed from up to crashed

Here is the local source code

from gc import collect
import json
import random
import re
import tweepy
from dotenv import load_dotenv
import os
import time
from bs4 import BeautifulSoup
import requests

load_dotenv()

appkey = os.environ['APPKEY']
app_secret = os.environ['APP_SECRET']
acces_token = os.environ['ACCESS_TOKEN']
access_token_secret = os.environ['ACCESS_TOKEN_SECRET']

auth = tweepy.OAuth1UserHandler(appkey, app_secret, acces_token, access_token_secret)

api = tweepy.API(auth, wait_on_rate_limit=True)
user = api.verify_credentials()

def quotes_scraper():
    collection = list()
    TAGS = ["science","humor","life", "knowledge","motivational", "inspirational", "truth", "philosophy"  ] #tags
    

    for tag in TAGS:
        url = f"https://www.goodreads.com/quotes/tag/{tag}" 
        page = requests.get(url)
        soup = BeautifulSoup(page.content, "html.parser") #gets the html of the page
        raw_data = soup.find_all(class_ ="quoteText") #finds elements with class quoteText
        

        for quote in raw_data:
            quote_text = quote.contents[0].strip()
            author = quote.find(class_="authorOrTitle").text.strip()
            data = {
                "quote": quote_text, 
                "author": author,
                "genre": tag
            }
            collection.append(data)

    #creates a file and adds quotes to that file       
    with open("quotes3.json", "w") as qfile:
        json.dump(collection, qfile, ensure_ascii=False)
    return collection



#get a quote from a quotes file
def get_quote():
    f = open('quotes3.json')
    read_f = json.load(f)
    random_quote = random.choice(read_f) #Gets a random quote from all quotes

    author = random_quote['author']
    quote_text = f"{random_quote['quote']}"
    tweet = re.sub("[^A-Za-z0-9.,:;' ]","",quote_text)
    ftweet= tweet +" - " +author +" #Inspiration_of_the_day"

        
    while True:
        if len(ftweet) <=280:
            return ftweet


def tweet():
    api.update_status(get_quote())
    print(get_quote())


def like_and_retweet():
    for tweet in tweepy.Cursor(api.home_timeline).items(10):
        if tweet.user.id != user.id:
            if not tweet.favorited:
                try:
                    api.create_favorite(tweet.id)
                    print(f"liked {tweet.user.name}")
                except tweepy.errors.TweepyException as e:
                    print(e)


            if not tweet.retweeted:
                try:
                    api.retweet(tweet.id)
                    print(f"retweet {tweet.user.name}")
                except tweepy.errors.TweepyException as e:
                    print(e)

def run_tm(st, end):
    random_time = random.randint(st, end)
    return random_time


def run():
    while True:
        tweet()
        time.sleep(10)
        like_and_retweet()
        time.sleep(run_tm(60*60*4,60*60*10))

if __name__ == "__main__":
    run()

What can I do to correct this error and make the app run on Heroku? What could be causing this error?

  • Bots are malicious! what kind of bot is this? I'm joking, I had this same problem..but my case was different. This is pointing at a character encoding problem. https://stackoverflow.com/questions/21129020/how-to-fix-unicodedecodeerror-ascii-codec-cant-decode-byte – Conor Aug 23 '22 at 10:45
  • The beginning statement had me freaking out. It's just a Twitter bot. – kana natasha Aug 23 '22 at 11:26
  • I find it weird that it runs fine locally and even tweets but on Heroku it doesn't. I've tried adding encoding="utf-8" but the error still persits – kana natasha Aug 23 '22 at 11:39
  • are you using a runtime.txt file in your project directory? if not, make "runtime.txt" put it in your project directory and paste "python-3.9.13" in it. this will force Heroku to deploy with this version, it might fix the problem. – Conor Aug 23 '22 at 12:15
  • try with these other runtime versions if that one still kicks off the same problem: https://devcenter.heroku.com/articles/python-support#supported-runtimes – Conor Aug 23 '22 at 12:16

0 Answers0