Projects

I enjoy building side projects to continue learning about technology. Below are my latest:

  • Instead of boring lorem ipsum, use Lorem Quotesum

    |
    Lorem Quotesum

    Lorem Ipsum is dummy/placeholder text that has been the printing and typesetting standard since the 1500s. Unfortuntately, it’s also really boring.

    Sometimes you want boring Latin text that no one understands, such as when presenting to a client with no sense of humor. In that case, definitely go with lorem ipsum.

    But sometimes you’re allowed to have a little more fun. In that case, don’t settle for the same old boring lorem ipsum. Instead, use Lorem Quotesum and bring some humor and joy back to your work.

    Lorem Quotesum screenshot

  • The Shared Slides Clicker Had a Good Ride

    |
    Shared Slides Clicker

    A little over 3 years ago, we all went remote due to the pandemic and work life changed dramatically overnight. One thing we found ourselves doing was a lot more shared, remote presentations. With this came the constant need to ask the person sharing the slides to go to the “Next slide please”. This repeated phrase was like nails on a chalkboard to me, so in October 2020 I released the Shared Slides Clicker extension to allow people to easily, remotely share control of a Google Slides presentation over Google Meet. No longer did people need to say “Next slide please”.

    While I was proud of my solution, I knew that asking people to install a whole Chrome extension for this was not an ideal solution. I submitted feedback to Google to ask them to add this capability into Google Meet. I wanted them to make my extension obsolete. My extension even encouraged users to make the same request to Google.

    Well after almost 3 years, Google is finally adding this capability to Google Meet. Coming soon, Google Meet will allow you to add in “co-presenters” when you are sharing a Google Slides presentation.

    co-presenters

  • Bring order to your library of audiobooks

    |
    Audiobook Locker

    Is your audiobook collection out of control? Perhaps you forgot to cancel your Audible subscription and finally got around to using up all your credits (and then downloaded your books to your computer)? Or perhaps you’ve been buying DRM-free audiobooks from Librivox or Downpour? Regardless, when it comes time to pick the next audiobook to read, you’re faced with a mountain of folders with no good way to organize them.

    Audibook Locker is a cross-platform desktop app that shows you your books in a beautiful layout and gives you the power to:

    • sort alphabetically or chronologically (e.g., to find the books you’ve most recently added to your library)
    • browse your audiobooks by title, author, series, or genre
    • add tags to help categorize your books and browse by tag
    • mark books as either Finished or Unread and filter by status

    Screenshot

  • Take the pain out of weekly meal planning

    |
    Simple Weekly Meal Planner
    Cover

    I bet you can relate to the above image.

    And of course, this only get harder once you have kids and can’t just eat cereal or soup for dinner every night.

    I wanted a simple tool that would let me plan my meals for the week before I went grocery shopping so I would know what to buy at the store and what not to.

    I didn’t need a tool that made me pay for meal suggestions or gave me pre-built meal plans that were full of recipes that my family wouldn’t eat. I know what my family likes and I know what I like. I just need a way to organize and plan it. Sadly, none of the tools out there fit the bill, so I made my own.

    Introducing the Simple Weekly Meal Planner.

    The Simple Weekly Meal Planner is free and very straightforward. You add your meals and what ingredients they each include. Then each week you select for each day what meal you want to have. The app will generate a grocery list for you to take to the store to ensure you buy all the ingredients you need. That’s it. As the label says on the tin, simple.

  • Shared Slides Clicker Ups and Downs

    |
    Shared Slides Clicker
    Cover

    It’s been over 2 years since the start of the great WFH experiment created by the Covid-19 pandemic. And it’s been over 20 months since I released the Shared Slides Clicker browser extension to make presenting remotely using Google Slides and Meet more bearable. Read more about that here.

    More recently, we’ve seen many businesses shift to encouraging more return to office (RTO) for their employees. Whether this is good or bad is not the topic of this post (go to HN if you want to read about that). I was curious whether RTO would reduce the usage of the Shared Slides Clicker.

    Turns out it’s had a huge impact! Check out the usage over time in the graph above and read on to learn more.

  • How to upgrade from Api.ai to Dialogflow v2 using Firebase Cloud Functions

    |
    Api.ai to Dialogflow

    TL;DR

    You can add Dialogflow v2 chatbot integration to a website for free using Firebase Cloud Functions, but there are a few tricks you need to know about. Read the details below or just check out the code.

    Details

    DialogFlow logo

    Four years ago, I thought it would be fun to add a chatbot to my website. I had been playing with Chatbot integration at work, and I realized it could be a fun way to add some interactivity to this personal site.

    Back then, Dialogflow was called Api.ai and it offered a really easy way to set up a chatbot agent and integrate it into a website via simple REST calls. They even provided a client-side JS library to help. So I entered some info about me to the chatbot agent, added a nice UI on top of the integration (thanks to Botui), slapped it all together on my website and promptly moved on to other things.

    Over the years, Google bought Api.ai, they renamed it to Dialogflow, they deprecated a lot of Api.ai code, and most recently they shut down the client-side library altogether. That meant that suddenly my blog’s chatbot integration wasn’t working anymore! 😱

    Logo

    I assumed there would be a drop-in replacement with the new API, dubbed Dialogflow v2. But it turns out that Google has adopted a new authentication approach which precludes a simple client-side integration. So fixing this was going to be harder than I thought. Dialogflow now only offers a server-side Node.js library for integration purposes (in addition to other server-side language integrations like C++ and Java). So how was I going to integrate my static, 100% client-side website with Dialogflow?

    After much pondering, I realized that Firebase Cloud Functions could be the perfect intermediary between Dialogflow and my website.

    Read on to see how I migrated Api.ai to Dialogflow with the help of Cloud Functions.

  • Please, stop saying "next slide please"

    |
    Shared Slides Clicker
    Cover

    If your company is working at home because of COVID-19 and you all use Google Slides and Google Meet, then you’re probably used to hearing “next slide please” whenever multiple presenters need to jointly present to a group. This isn’t an issue with Zoom because it allows others to share control of their screen. Microsoft Teams also lets participants share control. But not Google Meet.

    I looked for an extension for Google Meet that would solve this problem, but I couldn’t find anything, so I had to build one! Hence my latest project: the Shared Slides Clicker Chrome Extension.

  • Cramming Appian into a Browser Extension

    |
    Appian Browser Extension
    Cover

    I’ve been at Appian for a long, long, long time. But I still remember clearly the day over 10 years ago when we first introduced our plug-in extension framework to allow outside developers to extend the Appian platform using OSGI Java code. The Appian community loved it and our employees (myself included), customers and partners have created thousands of plug-ins to make Appian even more powerful.

    My colleague and I recently decided to extend Appian and make it more powerful in a totally new way, by building a browser extension. Let me explain more and describe some of the things we learned along the way.

    A few years ago, Appian started adding more extension points to the product. Appian now gives developers multiple methods of integration, including embedding Appian in other web apps using Embedded Interfaces.

    Integration architecture Appian's various integration methods

    I was part of the team that worked on Embedded Interfaces, and it actually went through multiple revisions to ensure it was fast, secure, didn’t leak memory or CSS styles, and was customizable to match the look and feel of the embedding web app. It has become a huge success with customers who want to replace parts of their existing web portals piecemeal with Appian. It also turned out to be the key to building a browser extension for Appian.

    Last year my colleague Matthew Goldberg and I were wistfully discussing how much we wished there was an Appian browser extension so we could access our Appian tasks and data quickly from our browser. We soon realized we could build one ourself by leveraging Embedded Interfaces. And since Appian gives everyone in Engineering 10% of our work time to persue side projects, the Appian Browser Extension was soon born!

    Read on to learn more, or check it out yourself.

  • Powering Mattermost Interactive Buttons using Firebase

    |
    Mattermost on Fire

    At Appian, we use Mattermost for our internal worksplace messaging. It’s like Slack, but open-source and IT-friendly. The project recently released a new feature called Interactive Message Buttons which allow developers to add, as the name implies, interactive buttons to messages. See Mattermost’s example below. Cool right?

    gif

    The most obvious use case for interactive buttons is for creating a quick poll (e.g., asking people to vote on a specific question or topic). It’s so obvious that it’s the demo integration which Mattermost has on their website. Their implementation, however, is written in Python and it’s fairly bare-bones, limited to just a Yes or No answer. That’s not my cup of tea. I wanted something a little more powerful but also something that could run against a serverless backend, ideally written in Javascript.

    So I built a /poll implementation from scratch in Javascript using Firebase Cloud Functions and Firebase Realtime Database. I call it 🔥 MattermostOnFire 🔥

  • How to Test Firebase Cloud Functions using Jest

    |
    Firebase Cloud Functions and Jest
    Cover

    The Firebase Cloud Functions Unit Testing documentation and quickstart samples only show how to write unit tests for Firebase Cloud Functions using Mocha with Sinon and Chai. And the quickstarts don’t even do a thorough job of demonstrating how to write unit tests.

    I prefer to use Jest for unit tests. For others who feel the same, and for those who want to see more examples of how to unit test Firebase Cloud Functions, I wanted to help. I’ve created a Github repo that demonstrates how to replace the existing Mocha tests with Jest tests and how to write new Jest tests for the quickstarts that didn’t have tests.