3
\$\begingroup\$

This program constantly sends an https request to Reddit's API for new comments.

Using a PostgreSQL Database containing Regular Expressions, find comments of interest and notify about them using faye.

When run locally, the information is sent to localhost:8080, otherwise data is sent to a heroku application.

Full code can be found here.

app.js - Entry point of program

// Local files
require('./DatabaseFetch.js')();
require('./CommonTools.js')();
const CommentSearchProcessor = require('./CommentFinder.js');
const RedditClientImport = require('./RedditClient.js');

const pg = require('pg');

const secondsTimeToWaitBetweenPostingSameCommentToASubreddit = 60 * 30;
const intervalToWaitInMillisecondsBetweenReadingComments = 1100;
const intervalToWaitBeforeSendingIdleMessage = 30;
const commentCacheSize = 2000;
const dissallowedSubreddits = ['suicidewatch', 'depression' ];
const userIgnoreList = ['agree-with-you'];

var lastMessageSentAt = new Date().getTime();

const clientConnection = isLocal() ? 'http://localhost:8000/' : 'http://reddit-agree-with-you.herokuapp.com/';

const faye = require('faye');
const client = new faye.Client(clientConnection);

var CommentFinder;
var redditClient = new RedditClientImport();

let commentHistory = GetUniqueArray(3000);
let subredditModsList = GetUniqueArray(3000);

console.log('is local?: ' + isLocal());
console.log('connecting to: ' + clientConnection);
console.log('Database URL: ' + process.env.DATABASE_URL);

if (!process.env.DATABASE_URL) {
  throw 'Please set process.env.DATABASE_URL! e.g SET DATABASE_URL=postgres://.....';
}

// Execute 
GetCommentSearchObjectsFromDatabase(pg, process.env.DATABASE_URL, function(commentSearchObjects) {
    CommentFinder = new CommentSearchProcessor(commentSearchObjects, commentCacheSize);
    console.log('starting...');
    start();
});

function start()
{
    client.publish('/messages', {message: 'starting up.'});

    setInterval(function() {
        redditClient.getCommentsFromSubreddit(RedditClientImport.MAX_NUM_POSTS, 'all', 'comments', function(comments) {
            comments.forEach(
                comment => {
                    var replyMessage = CommentFinder.searchComment(comment);

                    if (replyMessage)
                    {
                        // filter by disallowed subreddits
                        if (dissallowedSubreddits.includes(comment.subreddit.toLowerCase()))
                        {
                            console.log('Ignoring comment, disallowed subreddit found for comment: ');
                            console.log(comment);
                        }
                        else
                        {
                            processComment(comment, replyMessage);
                        }
                    }
                });
        });

        if (GetSecondsSinceTimeInSeconds(lastMessageSentAt) > intervalToWaitBeforeSendingIdleMessage)
        {
            console.log('sending inactive message');
            client.publish('/messages', {inactive: '1'});
            lastMessageSentAt = new Date().getTime();
        }
    }, intervalToWaitInMillisecondsBetweenReadingComments);
}

function processComment(comment, replyMessage)
{
    // So we don't spam a subreddit with the same message
    let timeThisReplyWasLastSubmittedOnThisSubreddit = {id: (comment.subreddit +  ':' + replyMessage), created: comment.created };
    let thisSubredditModList = {id: comment.subreddit};

    if (subredditModsList.includes(thisSubredditModList))
    {
        if (subredditModsList.get(thisSubredditModList).modList.includes(comment.author))
        {
            console.log('Modderator comment!!! :' + comment.author + ' comment: ' + comment.body);
            return;
        }
    }
    else
    {
        redditClient.getSubredditModList(thisSubredditModList.id, function(modList) { 
            thisSubredditModList.modList = modList;
            subredditModsList.push(thisSubredditModList);
            console.log('pushed: ' + thisSubredditModList.id);
            processComment(comment, replyMessage);
            return;
        });
    }

    if (userIgnoreList.includes(comment.author))
    {
        console.log('Skipping comment, is posted by: ' + comment.author + ' comment: ' + comment.body);
        return;
    }

    console.log('continue...');

    if (!commentHistory.includes(timeThisReplyWasLastSubmittedOnThisSubreddit))
    {
        publishComment(comment, replyMessage);
        commentHistory.push(timeThisReplyWasLastSubmittedOnThisSubreddit);
    }
    else
    {
        var existingComment = commentHistory.get(timeThisReplyWasLastSubmittedOnThisSubreddit);

        if (GetSecondsSinceUTCTimestamp(existingComment.created) > secondsTimeToWaitBetweenPostingSameCommentToASubreddit)
        {
            publishComment(comment, replyMessage);
            commentHistory.push(timeThisReplyWasLastSubmittedOnThisSubreddit);
        }
        else 
        {
            console.log('skipping comment, we\'ve already posted to this subreddit recently!');
            console.log(comment);
            console.log(commentHistory);
        }
    }
}

function publishComment(comment, replyMessage)
{
    console.log('posting comment');
    client.publish('/messages', {comment: comment, reply: replyMessage});
    lastMessageSentAt = new Date().getTime();
    console.log(comment);
    console.log('reply: ' + replyMessage);
}

/**
 * Checks if this program is currently running locally
 * We do this by checking if 'heroku' property is found in 'process.env._'
*/
function isLocal()
{
    return !(process.env._ && process.env._.indexOf("heroku"));
}

Table layout for "RegexpComment":

|subredditmatch|commentmatch|replymessage|id|
|--------------|------------|------------|--|

'SubredditMatch' - A regular expression containing Subreddits to find comments on. E.G '.*' for all
'commentMatch'   - A regular expression for the comment. For example '^hello (.*)' would find all comments starting with 'hello'
'replyMessage'   - The comment reply
'id'             - the primary key, auto incremented
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.