Slack Bot writing to a database

The code for this blog is located here as version 0.2. So in the last blog i got a slack app to read and write to a channel. While this worked we did have some issues. One of them being every time we asked slack for the history of the channel we would get the entire history. Today we are going to set up a database that record the last timestamp that slack gave us.

First thing we need a database. I like to use sqlalchemy in python for all my database needs. Because all i care about it storing the timestamp that is the only field i’m going to put in my database.

from sqlalchemy import Column, ForeignKey, Integer, String, Date, DateTime, TIMESTAMP
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine

Base = declarative_base()


class Message(Base):
    __tablename__ = 'message'
    id = Column(Integer, primary_key=True)
    timestamp = Column(TIMESTAMP, nullable=False)


engine = create_engine('sqlite:///db.db')
Base.metadata.create_all(engine)

Now with the datebase script square away all we need to do is run the script above for the database to be created. Now we need to put something in the datebase. Before i did that i start moving some of the common task we were doing in to their own function. First function is a post_message function. We give it a, Slack_client, and a channel name, and it will post a message in to the channel. (Right now i’ve hardcoded the message in the channel, but i will move that as a parameter later).

def post_message(slack_client, mychannel):
    slack_client.chat_postMessage(
        channel='#' + mychannel,
        text="This is a message")

Next i created 2 database helper function

  1. add_ts_to_db. This function add a new timestamp to our database
  2. get_latest_ts_from_db. This function return the latest timestamp that we stored. We will use this number as our cutting point. We want to get all message after this time stamp.
def add_ts_to_db(timestamp):
    """
    Add a new Timestamp to the database
    :param timestamp: the time stamp to add to the database
    """
    if session.query(Message).filter_by(timestamp=timestamp).count():
        return
    new_ts = Message(timestamp=timestamp)
    session.add(new_ts)
    session.commit()


def get_latest_ts_from_db():
    """
    Get the latest TS in the database
    :return: the TS object with the latest time stamp
    """
    obj = session.query(Message).order_by(Message.timestamp.desc()).first()
    return obj

With this in place i wrote some quick code that every 2 seconds will post a message in slack (using the post_message function). Then grab the history based off the oldest timestamp in our database. And then print just the oldest message from database.

# DB Setup variables
engine = create_engine('sqlite:///db.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()

logging.basicConfig()
slack_client = slack.WebClient(token=token)
id = None
mychannel = 'test-channel'
list = slack_client.channels_list()

for each in list.data.get('channels'):
    if each.get('name') == mychannel:
        id = each.get('id')
while True:
    post_message(slack_client, mychannel)
    if id:
        ts = get_latest_ts_from_db()
        if ts is not None:
            ts = ts.timestamp.timestamp()
            l = slack_client.channels_history(channel=id, oldest=str(ts) + '01', inclusive="false")
            for each in l['messages']:
                add_ts_to_db(datetime.datetime.fromtimestamp(float(each['ts'])))
                print(each)
        else:
            l = slack_client.channels_history(channel=id, inclusive="false")
            for each in l['messages']:
                add_ts_to_db(datetime.datetime.fromtimestamp(float(each['ts'])))
    time.sleep(2)

And with that i have a script that can

  • Post a message to Slack
  • Read the latest message from Slack
  • Remember the last message it saw in slack

Next Steps will be to clean up the code, add user and karma totals to the database, and parse the text to add and remove karma, and print how much karma the user has.

Leave a comment

Blog at WordPress.com.

Up ↑