<div align="center">

# `ping` 🏓

Easily ping (wake) an idle Heroku App from slumber.

[![Build Status](](
[![contributions welcome](](


<br />

## Why? 🤷

We have _several_ demo/example/tutorial Apps deployed to Heroku. <br />
Apps on the "free" tier
go to sleep after **30 minutes** of inactivity. <br />

In order to wake them,
we wrote a few lines of code that can be added to any
Elixir/Phoenix App and invoked as an image
in the `` of the project that links to the App.
So the app is ready to go by the time the person
_reading_ the `` clicks on the link. 🔗

We had implemented the "wake from sleep" endpoint
several times in our Heroku Apps,
most recently in our
After copy-pasting the code a couple of times,
we decided to make it a DRY reusable package
that we can use in our _next_ app(s)!

<br />

## What? 💡

An easy way for us to wake our Heroku demo apps.

> Note: our use case for this module is "just in time" waking of Heroku dynos. <br />
If you need your "Free" Heroku app to be _always_ awake
or awake during specific times of day,
consider _combining_ the `ping` package with a CRON job.
You can use a _free_ service such as:
as described by [Mahdhi Rezvi]( in:

<br />

## Who? 👤

This package is for anyone building
an Elixir/Phoenix app deployed to Heroku.

<br />

# How? 💻

Add `ping` to your Phoenix App
and use it to wake your Heroku App in 4 easy steps:

<br />

## 1. Installation 📝

Install by adding `ping` to your list of dependencies in `mix.exs`:

def deps do
    {:ping, "~> 1.1.0"},


<br />

## 2. Create a `get /ping` Route in your `router.ex`

Open the `router.ex` file of your Phoenix project
and add the following route to your default pipeline:

get "/ping", PingController, :ping


<br />

## 3. Create the `ping/2` Function in your Controller

defmodule AppWeb.PingController do
  use AppWeb, :controller

  # see:
  def ping(conn, params) do
    Ping.render_pixel(conn, params)


<br />

You can either create a brand new controller,
or use an existing one if you prefer. <br />
We've created a new controller for clarity/separation.

### 3.b Create the Corresponding Test (Optional+Recommended)

Create the corresponding test file
to keep your Test coverage complete:

defmodule AppWeb.PingControllerTest do
  use AppWeb.ConnCase

  test "GET /ping (GIF) renders 1x1 pixel", %{conn: conn} do
    conn = get(conn, Routes.ping_path(conn, :ping))
    assert conn.status == 200
    assert conn.state == :sent
    assert conn.resp_body =~ <<71, 73, 70, 56, 57>>


## 4. Add a `GIF` to the `` of the Heroku App

Add an image linking to the endpoint of the App
to the `` file:


e.g: [pull/5/files](


> The GIF is a _transparent_ 1x1 pixel,
so it's both minimal in size
to minimise response time
and _invisible_ to the person.
The idea is just to make the most basic HTTP request
to the Heroku app in order to wake it.
We don't actually care what is returned.
But we don't want it to `404`
so the person reading the ``
doesn't see an error in their console/browser.

Docs available at
But there's really not much to it.