Serverless for Vampires

Ok, as a quick warning, this is a pretty stupid demo. I mean, I know that’s my thing - I’m the person who makes demos with cats. But this really pushes it a bit too far. I was bored a week or so ago and found an interesting API, the Sunrise Sunset API. This is a free API that returns sunrise and sunset times for a specific location. So obviously I saw that and thought it would be the perfect kind of service for vampires.

I mean - imagine you’re nice and comfy in your incredibly gothic tomb, you’ve woken up from a nice nap, and aren’t really sure what time it is.

Horrible cell signal here Pro Tip: Don’t google for ‘vampire crypt’ at work. Source

Or perhaps you know the time, but aren’t sure if the sun has risen yet. This is where the API comes in hand. Working with the API is pretty simple - for basic options you simply pass in a longitude and latitude. I began by building this OpenWhisk action:

const rp = require('request-promise');

function main(args) {

    if(!args.lat || !args.lng) {
        return { error:'Parameters lat and lng are required.' };
    }

    return new Promise((resolve, reject) => {
        let now = new Date();
        let url = `https://api.sunrise-sunset.org/json?lat=${args.lat}&lng=${args.lng}&formatted=0`;
        let options = {
            uri:url,
            json:true
        };

        rp(options).then(result => {
            let data = result.results;
            /*
            if now < data.sunrise || now > data.sunset
            */
            let sunrise = new Date(data.sunrise);
            let sunset = new Date(data.sunset);
            
            resolve({result:(now < sunrise || now > sunset)});
        }).catch(err => {
            reject({error:err});
        });

    });

}

From top to bottom - I do a bit of basic parameter validation and then just pass off a request to the API. Once I’ve got the result, I compare the current time to the sunrise and sunset times for the location. If the current time is after before sunrise or after sunset then I return true. I named this action isVampireSafe, so true means yes, it is perfectly for vampires to come out, have a good time, etc.

I put this up on OpenWhisk and enabled it as a web action and with that, I was completely done with my vampire-safety API. This basically took me ten minutes or so and I’ve already done a public service for monsters everywhere.

On the client side, I wrote up a quick application with a bit of minimal HTML and JavaScript. Here’s the HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width">
        <style>
            body {
                background-color:black;
            }

            h1, div {
                color: red;
            }
        </style>
    </head>
    <body>

        <h1>Vampire Safe?</h1>

        <div id="status"></div>

        <script src="client.js"></script>
    </body>
</html>

As you can see, just a simple H1 label and an empty div. Forgive me for the inline style. And here is the JavaScript:

let $status;
const API = 'https://openwhisk.ng.bluemix.net/api/v1/web/rcamden@us.ibm.com_My%20Space/safeToDelete/isVampireSafe.json';
const GOOD = `<p>It is totally safe to be outside as a vampire. Happy Hunting!</p>`;
const BAD = `<p>Sorry, the sun is up. Stay indoors!</p>`;

document.addEventListener('DOMContentLoaded', init, false);
function init() {

    $status = document.querySelector('#status');

    //First, get location
    navigator.geolocation.getCurrentPosition(gotLoc,locErr);

}

function locErr(e) {
    console.log('location error', e);
    $status.innerHTML = `
    <p>
    You need to let this app know your location in order for it to work. Or maybe you did
    and somethig else went wrong. I'm truly sorry.
    </p>`;
}

function gotLoc(pos) {
    console.log('position',pos.coords);

    fetch(API+'?lat='+pos.coords.latitude+'&lng='+pos.coords.longitude).then((res) => {
        return res.json();
    }).then((res) => {
        console.log(res);
        if(res.result === true) {
            $status.innerHTML=GOOD;
        } else {
            $status.innerHTML=BAD;
        }
    });
}

This just boils down to a quick Geolocation call and then a Fetch off to my API. Once I get my results I update the HTML. Here’s a screen shot of it in action (note, it is currently 1:49PM my time and about 200 degrees).

Vampire Safe

Of course, if I wanted to get really precise, I could do a weather check as well and allow vampires to exit if it is cloudy/stormy outside, but that would be a silly waste of time of course.

Want to try it yourself? You can visit the online location here: https://cfjedimaster.github.io/Serverless-Examples/vampire/client.html

Like This?

If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can also subscribe to the email feed to get notified of new posts.

Want to read more like this?