Skip to content

Database

In this example we will use Redis DB to manage state.

Main code

Manage subscriptions with Redis.

src/index.ts
import { getRedisClient } from "./lib/redis.js"; 
import { run, HandlerContext } from "@xmtp/message-kit";
import { startCron } from "./lib/cron.js";
 
//Tracks conversation steps
const inMemoryCacheStep = new Map<string, number>();
 
//List of words to stop or unsubscribe.
const stopWords = ["stop", "unsubscribe", "cancel", "list"];
 
const redisClient = await getRedisClient(); 
startCron(redisClient);
 
run(async (context: HandlerContext) => {
  const {
    message: {
      content: { content: text },
      typeId,
      sender,
    },
  } = context;
 
  if (typeId !== "text") {
    /* If the input is not text do nothing */
    return;
  }
 
  const lowerContent = text?.toLowerCase();
 
  //Handles unsubscribe and resets step
  if (stopWords.some((word) => lowerContent.includes(word))) {
    inMemoryCacheStep.set(sender.address, 0);
    await redisClient.del(sender.address); 
    await context.reply(
      "You are now unsubscribed. You will no longer receive updates!.",
    );
  }
 
  const cacheStep = inMemoryCacheStep.get(sender.address) || 0;
  let message = "";
  if (cacheStep === 0) {
    message = "Welcome! Choose an option:\n1. Info\n2. Subscribe";
    // Move to the next step
    inMemoryCacheStep.set(sender.address, cacheStep + 1);
  } else if (cacheStep === 1) {
    if (text === "1") {
      message = "Here is the info.";
    } else if (text === "2") {
      await redisClient.set(sender.address, "subscribed"); 
      message =
        "You are now subscribed. You will receive updates.\n\ntype 'stop' to unsubscribe";
      //reset the app to the initial step
      inMemoryCacheStep.set(sender.address, 0);
    } else {
      message = "Invalid option. Please choose 1 for Info or 2 to Subscribe.";
      // Keep the same step to allow for re-entry
    }
  } else {
    message = "Invalid option. Please start again.";
    inMemoryCacheStep.set(sender.address, 0);
  }
 
  //Send the message
  await context.reply(message);
});

Redis middleware

Install dependencies

cmd
yarn add @redis/client

Copy paste the following code in your lib/redis.ts file.

src/lib/redis.ts
import { createClient } from "@redis/client";
 
export const getRedisClient = async () => {
  const client = createClient({
    url: process.env.REDIS_CONNECTION_STRING,
  });
 
  client.on("error", (err) => {
    console.error("Redis client error:", err);
  });
 
  await client.connect();
  return client;
};