DEV Community

Cover image for Part 3: Developing stock-checker app
Jonathan Harrison
Jonathan Harrison

Posted on

1 1

Part 3: Developing stock-checker app

This post is part of a series detailing my journey with golang from learning the language to entering the DigitalOcean App Platform Hackathon.

The app I built can be found on GitHub.

Part 3 details:

  • golang packages used to build stock-checker
  • docker setup for both development and production
  • Integrating with Twilio SMS API

Overview

stock-checker is a golang app that spawns a task every hour to check whether any of the following UK retailers have an Xbox Series X console in stock:

This is done using a web automation library that navigates each site in a headless chromium browser.

If the app determines stock is available, a text message is sent using Twilio to the configured mobile number.

golang packages

A number of different packages were used to build this app which are detailed in this section.

These packages were discovered on Awesome Go.

Web Automation - go-rod/rod

rod is a high-level driver for the DevTools Protocol.

This package is used to navigate the various retailer's sites to find the Xbox Series X console listing. Once found, it checks whether the console is in or out of stock.

Notable features include:

Configuration - spf13/viper

Viper is a configuration package that supports reading configuration files in various formats, as well as from environment variables.

This is being used to control:

  • The scheduler interval
  • Debug settings for rod
  • Enables/disables sending notifications and the secrets used to communicate with Twilio.

I used an envfile to define the app's configuration. Originally, I tried using a YAML file but due to a couple of issues, I had to swap the file format.

To help others, here are the issues I ran into when using YAML:

  • GitHub Issue: If you want to override a YAML subobject property with an environment variable, you have to name the variable using the following format: PREFIX_SECURE.KEY. DigitalOcean App Platform environment variables do not support . in the name.
  • GitHub Issue: If you want to override a YAML subobject property with an environment variable and unmarshal that object to a struct, this isn't currently possible. This is because viper.UnmarshalKey doesn't take account of environment variables.

Scheduler - go-co-op/gocron

goCron is a scheduling package that lets you run functions periodically at a pre-determined interval.

This is being used to run a task once an hour that checks the various retailers and if applicable, sends a notification.

docker support

To simplify running the app on DigitalOcean, I added docker support which this section covers.

Dockerfile

This amazing JetBrains blog post series greatly inspired the Dockerfile created for this project.

Using multi-stage builds it provides both a development image with debugging support and a production image.

# Builder
FROM golang:1.15.6-buster AS builder
COPY . /src
WORKDIR /src
RUN go get github.com/go-delve/delve/cmd/dlv
RUN go build -gcflags="all=-N -l" -o app-dev
RUN go build -o app

# Base runner
FROM debian:10.7 AS base-runner
RUN apt-get update && apt-get install -y \
    ca-certificates \
    chromium \
    && rm -rf /var/lib/apt/lists/*

# Dev runner
FROM base-runner AS dev-runner
WORKDIR /server
COPY config.env /server
COPY --from=builder /src/app-dev /server/app
COPY --from=builder /go/bin/dlv /server
EXPOSE 40000
CMD ["/server/dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/server/app"]

# Prod runner
FROM base-runner AS prod-runner
WORKDIR /server
COPY config.env /server
COPY --from=builder /src/app /server
CMD ["./app"]
Enter fullscreen mode Exit fullscreen mode

docker-compose

To assist with development, this docker-compose file starts a development container with debugging enabled and enables a few rod debug options via environment variables.

version: "3.9"

services:
  app:
    build:
      context: ./..
      target: dev-runner 
    security_opt:
      - seccomp:unconfined
    cap_add:
      - SYS_PTRACE
    container_name: stock-checker-$USER

    ports:
      - "40000:40000" # DEBUG

    environment:
      - SC_ROD_TRACE=true
      - SC_ROD_PAGEPOOLSIZE=1
Enter fullscreen mode Exit fullscreen mode

Remote debugging using VS Code

To remote debug the app within docker, we need to create a launch configuration by following this guide.

The resulting config looks like this:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch and debug in Docker",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "cwd": "${workspaceFolder}",
            "port": 40000,
            "host": "127.0.0.1",
            // This corresponds to the directory the app is built in
            "remotePath": "/src"
        },
    ]
}
Enter fullscreen mode Exit fullscreen mode

Integrating with Twilio

Twilio is being used to send a SMS when the app detects a Xbox Series X console is in stock.

Originally, I was going to use saintpete/twilio-go which I discovered here. However I ran into issues with this package due to incompatible package versions.

In the end, I went with a simpler approach and ended up following this blog post to integrate with their SMS API directly.

Next

That's it for this post.

In the final part, I will detail my DigitalOcean App Platform Hackathon submission as well as deploying to DigitalOcean.

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more