Session Plugin
Session plugin for GramIO.
Installation
npm install @gramio/sessionyarn add @gramio/sessionpnpm add @gramio/sessionbun install @gramio/sessionUsage
import { Bot } from "gramio";
import { session } from "@gramio/session";
const bot = new Bot(process.env.BOT_TOKEN as string)
.extend(
session({
key: "sessionKey",
initial: () => ({ apple: 1 }),
})
)
.on("message", (context) => {
context.send(`apple count is ${++context.sessionKey.apple}`);
})
.onStart(console.log);
bot.start();You can use this plugin with any storage (Read more)
Redis example
import { Bot } from "gramio";
import { session } from "@gramio/session";
import { redisStorage } from "@gramio/storage-redis";
const bot = new Bot(process.env.BOT_TOKEN as string)
.extend(
session({
key: "sessionKey",
initial: () => ({ apple: 1 }),
storage: redisStorage(),
})
)
.on("message", (context) => {
context.send(`apple count is ${++context.sessionKey.apple}`);
})
.onStart(console.log);
bot.start();Lazy Sessions
By default the session is loaded from storage on every update, even if the handler never reads it. Enabling lazy: true defers the load until the session is actually accessed, which can significantly reduce unnecessary storage reads on high-traffic bots.
import { Bot } from "gramio";
import { session } from "@gramio/session";
const bot = new Bot(process.env.BOT_TOKEN as string)
.extend(
session({
key: "sessionKey",
lazy: true,
initial: () => ({ count: 0 }),
})
)
.on("message", async (context) => {
// Storage is not read until here:
const s = await context.sessionKey;
s.count++;
await context.send(`count: ${s.count}`);
});In lazy mode context.sessionKey is a Promise — always await it before accessing data.
Session Clearing
Call $clear() on the session object to delete it from storage and reset to the initial state on the next access.
bot.on("message", async (context) => {
if (context.text === "/reset") {
await context.sessionKey.$clear();
}
});In lazy mode, resolve the promise first:
bot.on("message", async (context) => {
if (context.text === "/reset") {
const s = await context.sessionKey;
await s.$clear();
}
});Custom Session Keys
Sessions are keyed by senderId by default. Use getSessionKey to change the scoping strategy.
// Per-chat session
session({
getSessionKey: (ctx) => `chat:${ctx.chatId}`,
initial: () => ({ topic: "" }),
})
// Per-user-per-chat session
session({
getSessionKey: (ctx) => `${ctx.senderId}:${ctx.chatId}`,
initial: () => ({ preferences: {} }),
})TypeScript
Session data is automatically typed from the initial return type. You can also pass an explicit interface.
interface MySessionData {
apple: number;
some?: "maybe-empty";
}
// Eager mode — ctx.sessionKey: MySessionData & { $clear(): Promise<void> }
bot.extend(
session({
key: "sessionKey",
initial: (): MySessionData => ({ apple: 1 }),
})
);
// Lazy mode — ctx.sessionKey: Promise<MySessionData & { $clear(): Promise<void> }>
bot.extend(
session({
key: "sessionKey",
lazy: true,
initial: (): MySessionData => ({ apple: 1 }),
})
);