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;
};