Observable Flying Objects


Matt Roumaya


April 18, 2023

Random UFO Report

tl;dr - 🛸 Refresh the page to see a random UFO report! 🛸

  • Some fields may show as undefined or null because this is a quick write-up and I’m busy! :)

  • If you have any suggestions or would like to get started with Observable, or want to connect in general, definitely email me.


NUFORC Bot is/was a Twitter bot that scrapes UFO sightings data from the NUFORC Data Bank and tweets out a summary (and image if one was provided). The bot has ~700 followers and not much engagement, but it has definitely been a fun way to learn about web scraping, bot building, and CRON jobs via GitHub Actions (repo is here).

Recently, the World’s Smartest Man pulled the plug on Twitter’s API access for a wide range of developers, including NUFORC Bot. For some reason, NUFORC Bot is now back up and running, but it seems like it will be short-lived.

After the hostile takeover, I stopped using my personal account on Twitter, deleted the app, and planned to just let NUFORC Bot ride off into the sunset. Now that the sunset is quickly approaching, I’ve been trying to think of a way to reproduce a similar effect to the tweet using the data I have already collected.

Having been a subscriber to hrbrmstr’s Daily Drop for a while, I’ve seen a ton of amazing Observable notebooks, and thought that this could be a fun project to learn Observable and see . The impending demise of NUFORC Bot was as good an excuse as any to hack together an Observable notebook that can do everything that NUFORC Bot did + MORE 👽.

Import From Observable

It’s kind of amazing how little code is needed to create the random report above.

  1. Importing two functions from my Observable Notebook
  2. Reading data with d3. This could also be done in R but is more concise in a single chunk, and I’m planning to use ojs_define() in a later post.
import { selectRandom, addHeader } from "@mroumaya/random-ufo"
ufoReport = d3.csv('https://raw.githubusercontent.com/mattroumaya/mufonbot/master/data_raw/links.csv')
ufo = addHeader(selectRandom(ufoReport));
  1. The only other code that’s needed is some HTML to display the NUFORC report data. Observable has a Hypertext Literal implementation that I definitely didn’t leverage correctly, but looks like this:
htl.html`<h3 class='header'></h3>
<div class="date"></div>

<div class="shape"></div>

<div class="duration"></div>

<a class="report-link">Link to Report</a>
<a class="raw-link">Link to Image</a>
<div class="summary"></div>
<img id="ufo-img" style="height: 500px">