Skip to content

LiamOsler/local-aircraft-reddit-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Halifax, Nova Scotia Aircraft Spotting Reddit Bot

Requirements:

Node.js

Packages:

node-cron https://github.com/kelektiv/node-cron

axios https://github.com/axios/axios

Data:

Open Sky aircraft https://opensky-network.org/datasets/metadata/

Setup:

If you use NPM:

npm init

npm install uuid node-cron axios reddit

or

npm install uuid node-cron axios reddit

Configuration:

First, create a file called app.js

Then, require node-cron in your app.js file

const cron = require('node-cron');

Let's look at some basic node-cron usage:

By default, node-cron's standard input runs every minute:

cron.schedule('* * * * *', () => {
    console.log('running a task every minute');
});

If we wanted to use node-cron to run a task every 10 seconds by using */n where n is the number of seconds as shown in this example, for some high-frequency flight position logging, you can do like this:

cron.schedule('*/10 * * * * *', () => {
    console.log('running a task ten seconds');
});

Every ten minutes:

cron.schedule('* */10 * * * *', () => {
    console.log('running a task ten minutes');
});

etc...

Or conversely, if to log at infrequently, you can set node-cron to run a job at a specific time of day, for instance at midnight:

cron.schedule('0 0 * * * *', () => {
    console.log('running a task every day at midnight');
});

Settings credentials:

Credentials are stored in credentials.json: Edit these values to those given to you when you create a Reddit Script App

{
    "username": "your_username",
    "password": "your_password",
    "appId": "your_appId",
    "appSecret": "your_appSecret",
    "userAgent": "your_userAgent"
}

They are called in the code here:

let credentialData = fs.readFileSync('credentials.json');
let credentials = JSON.parse(credentialData);

const reddit = new Reddit({
    username: credentials.username,
    password: credentials.password,
    appId: credentials.appId,
    appSecret: credentials.appSecret,
    userAgent: credentials.userAgent
  })

The source code:

const cron = require('node-cron');
const axios = require('axios');
const Reddit = require('reddit');
const fs = require('fs');

var data = fs.readFileSync('data.csv')
    .toString() // convert Buffer to string
    .split('\n') // split string to lines
    .map(e => e.trim()) // remove white spaces for each line
    .map(e => e.split(',').map(e => e.trim())); // split each line to array


let credentialData = fs.readFileSync('credentials.json');
let credentials = JSON.parse(credentialData);
const reddit = new Reddit({
    username: credentials.username,
    password: credentials.password,
    appId: credentials.appId,
    appSecret: credentials.appSecret,
    userAgent: credentials.userAgent
  })


async function redditPost(state, details, status) {
    let postText = "EMPTY";
    if(status == "enter"){
        console.log(details);
            if(state[1] != ''){
                if(details[5] != '""'){
                    postTitle = "Aircraft callsign " + state[1] + " has entered Halifax airspace - "+ details[13].replace(/['"]+/g, '') + " " +details[4].replace(/['"]+/g, '') + "." ;
                }
                else{
                    postTitle = "Aircraft callsign " + state[1] + " has entered Halifax airspace."
                }

                if(details[14] != '""'){
                    let airline = details[14].replace(/['"]+/g, '');
                }

                postText  = "Aircraft callsign " + state[1] + "- "+ details[13].replace(/['"]+/g, '') + " " +details[4].replace(/['"]+/g, '')  + " has entered Halifax airspace."
                            +"\n"
                            +"\n"
                            +"Altitude: " + Math.trunc(state[13]) +"m"
                            +"\n"
                            +"\n"
                            +"Velocity: " + Math.trunc(state[9]*3.6) +"km/h"
                            +"\n"
                            +"\n"
                            +"[OpenSky Database entry for this aircraft](https://opensky-network.org/aircraft-profile?icao24="+state[0]+")"
                            +"\n"
                            +"\n"
                            +"[FlightRadar24 Map Link](http://flightradar24.com/"+state[1]+")"
                            +"\n"
                            +"\n"
                            +"Data via the [OpenSky API](https://openskynetwork.github.io/opensky-api/)"
                        }
            else{
                postTitle = "Aircraft with unknown callsign (icao24 transponder code: " + state[0] + ") has entered Halifax airspace."
                postText =  "Aircraft with unknown callsign (icao24 transponder code: " + state[0] + ") has entered Halifax airspace."
                            +"\n"
                            +"\n"
                            +"Altitude: " + Math.trunc(state[13]) +"m"
                            +"\n"
                            +"\n"
                            +"Velocity: " + Math.trunc(state[9]*3.6) +"km/h"
                            +"\n"
                            +"\n"
                            +"[OpenSky Database entry for this aircraft](https://opensky-network.org/aircraft-profile?icao24="+state[0]+")"
                            +"\n"
                            +"\n"
                            +"[ADS-B Exchange link for this aircraft](https://globe.adsbexchange.com/?icao="+state[0]+")"
                            +"\n"
                            +"\n"
                            +"Post Data via the [OpenSky API](https://openskynetwork.github.io/opensky-api/)"
            }
    }
    if(status == "exit"){
        postText = "Aircraft callsign " + state[1]  + " has left Halifax airspace."
    }
    const res = await reddit.post('/api/submit', {
        sr: 'HalifaxSkyWatchers',
        kind: 'self',
        resubmit: true,
        title: postTitle,
        text: postText
      })
      console.log(res)
  }

let aircrafts = [];
let recents = [];

cron.schedule('*/10 * * * * *', () => {
    axios
    .get('https://opensky-network.org/api/states/all?lamin=44.00&&lomin=-64.00&lamax=45.00&lomax=-63.00')
    .then(res => {
            if(!res.data.states){
                console.log("No aircraft overhead");
            }
            else{
                for(let state of res.data.states){
                    let newAircraft = true;
                    for(let aircraft of aircrafts){
                        if(aircraft[0] == state[0]){
                            newAircraft = false;
                        }
                    }
                    if(newAircraft){
                         console.log("ICAO " + state[0] + " has entered Halifax airspace.");

                        aircrafts.push(state);

                        let newRecent = true;
                        for(let recent of recents){
                            if(recent[0] == state[0]){
                                newRecent = false;
                            }
                        }
                        if(newRecent){
                            for(aircraft of data){
                                if(aircraft[0].replace(/['"]+/g, '') == state[0]){
                                    console.log("match");
                                    redditPost(state, aircraft, "enter")
                                }
                            }
                            recents.push(state)
                            recents[recents.length - 1].date = Date.now();
                        }
                        else{
                            console.log("Known Aircraft")
                        }
                        for(let i = 0; i < recents.length; i ++){
                            if(Date.now() - recents[i].date > 1000 * 60 * 60){
                                recents.splice(i);
                            }
                        }
                    }
                }

                for(let i = 0; i < aircrafts.length; i++){
                    let aircraft = aircrafts[i];
                    let removeAircraft = true;
                    for(let state of res.data.states){
                        if(aircraft[0] == state[0]){
                            removeAircraft = false;
                        }
                    }
                    if(removeAircraft){
                        console.log("ICAO " + aircrafts[i][0] + " has left Halifax airspace.");
                        aircrafts.splice(i);
                    }
                }
            }
        })
        .catch(error => {
            console.error(error)
        })
});

About

Local Aircraft Reddit Bot

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published