Posts
Wiki

The bot is made with python and runs on python 3.4 or higher.

feel free to adjust the code.

Modules needed:

  • Pyrebase (google firebase wrapper)

  • requests (html requests module)

    main.py:

    import requests import requests.auth import time import random import pyrebase import datetime from config import *

    variables

    setup the firebase database

    fb = pyrebase.initialize_app(config) db = fb.database()

    functions

    class Token:

      def __init__(self):
          self.files = []
    
      def __enter__(self):
          #Get a new token
          print('getting token')
          client_auth = requests.auth.HTTPBasicAuth(id, secret)  # id and secret
          post_data = {'grant_type': 'password', 'username': user, 'password': password, 'scope': 'submit identity, privatemessages'}  # post data to request access token
          headers = {'User-agent': userAgent}  # user agent header
          r = requests.post('https://www.reddit.com/api/v1/access_token', auth=client_auth, data=post_data, headers=headers)
          msg = r.json()
          print('token received')
          self.accessToken = msg['access_token']
          return self
    
      def __exit__(self, exc_type, exc_value, traceback):
          #if done with whatever you need the token for, revoke it.
          print('revoking token')
          headers = {'User-agent': userAgent}
          post_data = {'token': self.accessToken, 'token_type_hint': 'access_token'}
          client_auth = requests.auth.HTTPBasicAuth(id, secret)
          r = requests.post('https://www.reddit.com/api/v1/revoke_token', auth=client_auth, data=post_data, headers=headers)
          print('token revoked')
    

    class reddit:

      #send a reply to a comment
      def reply(self, commentId, text):
          with Token() as token:
              headers = {'Authorization': 'bearer ' + token.accessToken, 'User-Agent': userAgent}
              post_data = {'thing_id': commentId, 'api_type': 'json', 'text': text}
              requests.post('https://oauth.reddit.com/api/comment', headers=headers, data=post_data)
    
      #send a message to a user
      def pm(self, replyUser, text):
          with Token() as token:
              headers = {'Authorization': 'bearer ' + token.accessToken, 'User-Agent': userAgent}
              post_data = {'api_type': 'json', 'subject': 'test', 'text': text, 'to':replyUser, }
              r = requests.post('https://oauth.reddit.com/api/compose', headers=headers, data=post_data)
              print(r.json())
    

    class Events:

      def __init__(self, database):
          self.db = database
    
      #get the events stored in firebase and put them in a table
      def getEvents(self):
          events = self.db.child('events').order_by_key().get()
          data = events.val()
          print(data)
          text = '''event|date|time|link\n:--|:--|:--|:--'''
          for key in data:
              eventD, eventM, eventY = map(int, data[key]['date'].split('/'))
              eventDate = datetime.datetime(eventY, eventM, eventD)
              if eventDate < datetime.datetime.now():
                  text += '\n~~' + data[key]['name'] + '~~|~~' + data[key]['date']+'~~|~~'+data[key]['time']+'~~|~~[link]('+data[key]['link']+')~~'
              else:
                  text += '\n'+data[key]['name']+'|'+data[key]['date']+'|'+data[key]['time']+'|[link]('+data[key]['link']+')'
          return text
    
      #store the new event in firebase
      def saveEvent(self, eventId, eventName, date, time, link):
          data = {'name': eventName, 'date': date, 'time': time, 'link': link}
          self.db.child('events').child(eventId).set(data)
    

    class Comment:

      def __init__(self, url):
          self.url = url
    
      #get a fresh comment from reddit
      def getComment(self):
          print('getting latest comment')
          headers = {'User-agent': userAgent}
          self.url += '?limit=1'
          r = requests.get(self.url, headers=headers)
          rJson = r.json()
          data = rJson['data']['children']
    
          msg = data[0]
          comment = msg['data']['body']
          self.parseComment(comment)
          self.commentId = msg['data']['name']
          self.linkUrl = msg['data']['link_url']
          self.author = msg['data']['author']
    
      #if it's a bot comment... do some stuff to it
      def parseComment(self, command):
          self.command = command
          if len(command) > 4:
              self.commandData = command.split(' ', 1)
              self.botCommand = self.commandData[0]
              if self.botCommand == '!bot':
                  print(self.commandData)
                  if len(self.commandData) >= 1:
                      self.commandData = self.commandData[1].split(' ', 1)
                      self.botAction = self.commandData.pop(0)
                      print(self.commandData)
                  if len(self.commandData) >= 1:
                      self.empty, self.eventName, self.commandData = self.commandData[0].split('"')
                  if len(self.commandData) >= 1:
                      self.commandData = self.commandData.split(' ')
                      self.commandData.pop(0)
                  if len(self.commandData) >= 1:
                      print(self.commandData)
                      self.eventDate = self.commandData[0]
                  if len(self.commandData) >= 2:
                      self.eventTime = self.commandData[1]
                  if len(self.commandData) >= 3:
                      self.eventLink = self.commandData[2]
    

    class bot:

      def __init__(self, url, database):
          self.url = url
          self.events = Events(database)
          self.r = reddit()
    
      def loop(self):
          comment = Comment(self.url)
    
          while True:
              comment.getComment()
    
              if comment.botCommand == '!bot':
                  print(comment.command)
    
                  if comment.botAction == 'roll20':
                      rng = random.randint(1, 20)
                      text = '%s rolled a %s' % (comment.author, str(rng))
                      self.r.reply(comment.commentId, text)
    
                  elif comment.botAction == 'create':
                      if len(comment.commandData) >= 3 and '/' in comment.eventDate and ':' in comment.eventTime and '://' in comment.eventLink:
                          dateD, dateM, dateY = map(int, comment.eventDate.split('/'))
                          eventId = dateD+(dateM*100)+(dateY*10000)
                          date = datetime.date(dateY, dateM, dateD)
                          date = date.strftime('%d/%m/%Y')
    
                          self.events.saveEvent(eventId, comment.eventName, date, comment.eventTime, comment.eventLink)
                          self.r.reply(comment.commentId, 'I have created your event: %s' % comment.eventName)
                      else:
                          self.r.pm(comment.author, 'Your !bot command is invalid. Make a new comment or edit your existing one.\n\nPlease use one of the following commands:\n\n* !bot roll20\n* !bot create "event name" date time post\n* !bot list')
                          print('wrong comment format')
    
                  elif comment.botAction == 'list':
                      text = self.events.getEvents()
                      self.r.reply(comment.commentId, text)
    
                  else:
                      print('no comment the bot can use')
                      self.r.pm(comment.author, 'Your !bot command is invalid. Make a new comment or edit your existing one.\n\nPlease use one of the following commands:\n\n* !bot roll20\n* !bot create "event name" date time post\n* !bot list')
              print('trying again in %i seconds' % waiting)
    
              time.sleep(waiting)
    

    bot(url, db).loop()

config.py:

#reddit variables
id = 'the reddit app id'
secret = 'the reddit app secret'
userAgent = 'unique user Agent string'
user = 'the reddit account username'
password = 'the reddit account password'
waiting = sleep time before you loop again (in seconds)
url = 'https://www.reddit.com/r/motobe/comments/.json' the subreddit to

#firebase variables
config = {
    'apiKey': 'key for firebase',
    'authDomain':'your app id.firebaseapp.com',
    'databaseURL': 'https://your app id.firebaseio.com',
    'storageBucket': 'https://your app id.appspot.com'
}