Skip to main content

Quickstart Guide

Get your Shopify changelog monitoring service up and running in just a few steps.

Prerequisites

Before you begin, ensure you have:
Keep your Google Chat webhook URL secure. Anyone with access to this URL can send messages to your chat space.

Installation

1

Clone or download the repository

Get the source code on your local machine:
git clone <repository-url>
cd shopify-rss-feed-gchat
2

Install dependencies

Use Bun to install the required packages:
bun install
This installs:
  • hono - Fast web framework for routing
  • rss-parser - RSS feed parsing library
3

Configure environment variables

Create a .env file in the project root:
WEBHOOK_URL=your-google-chat-webhook-url-here
Replace your-google-chat-webhook-url-here with your actual Google Chat webhook URL.
Bun automatically loads .env files, so no additional configuration is needed.

Running Locally

Start the development server with hot reloading:
bun run dev
The server will start on the default port (typically http://localhost:3000).
The --hot flag enables automatic reloading when you modify source files.

Testing the Endpoints

Health Check

Verify the server is running:
curl http://localhost:3000/healthcheck
Expected response:
Running!

Trigger RSS Feed Check

Manually trigger the RSS feed processing:
curl http://localhost:3000/get-rss-feed
Expected response:
Done!
This endpoint will:
  1. Fetch the Shopify changelog RSS feed
  2. Filter for new items (published after yesterday)
  3. Send formatted notifications to your Google Chat space
  4. Update the last processed date
On first run, the service processes items from the last 24 hours. Subsequent runs only process items newer than the last execution.

Understanding the Code

Server Setup (server.ts)

The main server file uses Hono for routing:
server.ts
import { Hono } from "hono";
import { handleRSSFeed } from "./rss-handler.js";

const app = new Hono();

app.get("/healthcheck", (c) => {
  return c.text("Running!");
});

app.get("/get-rss-feed", async (c) => {
  await handleRSSFeed();
  return c.text("Done!", 200);
});

export default app;

RSS Handler (rss-handler.ts)

The core logic handles feed fetching, filtering, and Google Chat integration:
rss-handler.ts
export async function handleRSSFeed() {
  const feed = await getRSSFeed();
  const newItems = await filterNewItems(feed);

  if (newItems.length > 0) {
    await sendToGchat(newItems);
    await updateProcessedState(newItems);
  } else {
    console.log("No new items to process");
  }
}

Fetching the RSS Feed

rss-handler.ts
const RSS_FEED_URL = "https://shopify.dev/changelog/feed.xml";

async function getRSSFeed() {
  return await parser.parseURL(RSS_FEED_URL);
}

Filtering New Items

The service tracks processed items by date:
rss-handler.ts
async function filterNewItems(
  feed: Awaited<ReturnType<typeof getRSSFeed>>
): Promise<typeof feed.items> {
  const state = await getProcessedState();
  const lastProcessedDate = new Date(state.lastProcessedDate);

  // Filter items that are newer than the last processed date
  const newItems = feed.items.filter((item) => {
    const itemDate = item.isoDate || item.pubDate;
    if (!itemDate) return false;

    const itemDateObj = new Date(itemDate);
    return itemDateObj > lastProcessedDate;
  });

  // Sort by date (newest first)
  newItems.sort((a, b) => {
    const dateA = new Date(a.isoDate || a.pubDate || 0).getTime();
    const dateB = new Date(b.isoDate || b.pubDate || 0).getTime();
    return dateB - dateA;
  });

  return newItems;
}

Sending to Google Chat

The service formats items as rich cards:
rss-handler.ts
async function sendToGchat(
  items: Awaited<ReturnType<typeof getRSSFeed>>["items"]
) {
  const webhookUrl = process.env.WEBHOOK_URL;
  if (!webhookUrl) {
    throw new Error("WEBHOOK_URL environment variable is not set");
  }

  const cardMessage = {
    cardsV2: [
      {
        card: {
          header: {
            title: "Shopify Changelog Updates",
            subtitle: dateSubtitle,
            imageUrl: getImageUrl(),
          },
          sections: [
            {
              widgets: listWidgets,
            },
          ],
        },
      },
    ],
  };

  const response = await fetch(webhookUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(cardMessage),
  });
}

Deploying to Vercel

1

Install Vercel CLI (optional)

bun install -g vercel
2

Deploy to Vercel

vercel
Follow the prompts to link your project and deploy.
3

Configure environment variables

In the Vercel dashboard, add your environment variable:
WEBHOOK_URL=your-google-chat-webhook-url-here
4

Verify cron configuration

The vercel.json file automatically configures a daily cron job:
vercel.json
{
  "crons": [
    {
      "path": "/get-rss-feed",
      "schedule": "0 0 * * *"
    }
  ]
}
This runs the RSS feed check every day at midnight UTC.

Customization Options

Change the RSS Feed URL

Modify the RSS_FEED_URL constant in rss-handler.ts:
rss-handler.ts
const RSS_FEED_URL = "https://your-custom-feed.xml";

Adjust Cron Schedule

Update the schedule in vercel.json using cron syntax:
vercel.json
{
  "crons": [
    {
      "path": "/get-rss-feed",
      "schedule": "0 */6 * * *"  // Every 6 hours
    }
  ]
}

Customize Message Format

Modify the sendToGchat function in rss-handler.ts to change card appearance, colors, or structure.

Troubleshooting

No messages received

  1. Verify your WEBHOOK_URL is correct
  2. Check that new items exist in the RSS feed
  3. Review server logs for errors: console.log statements in rss-handler.ts

”WEBHOOK_URL environment variable is not set” error

  • Ensure .env file exists in the project root
  • Verify the variable name is exactly WEBHOOK_URL
  • For Vercel deployments, set the environment variable in the dashboard

Failed to send to Google Chat

  • Verify the webhook URL is valid and hasn’t been revoked
  • Check Google Chat webhook status and logs
  • Ensure the webhook space still exists
If you regenerate your Google Chat webhook, you must update the WEBHOOK_URL environment variable.

Next Steps

Your Shopify changelog monitoring service is now running! Consider:
  • Setting up monitoring and alerting for the Vercel deployment
  • Adding multiple webhook URLs for different chat spaces
  • Implementing persistent state storage (database) for larger deployments
  • Customizing notification formats based on changelog categories

View Source Code

Explore the complete source code on GitHub

Build docs developers (and LLMs) love