Skip to content

Instantly share code, notes, and snippets.

@waptik
Created September 3, 2021 07:39
Show Gist options
  • Save waptik/577e1c010b6184d7bbd569732fc6684e to your computer and use it in GitHub Desktop.
Save waptik/577e1c010b6184d7bbd569732fc6684e to your computer and use it in GitHub Desktop.
Custom session adapter for grammyjs using supabase. Please give it a try and comment for feedback
  1. Create a new table in your supabase database called bot_sessions.
  2. bot_sessions should have these required columns: id as string(primary key), session as string
import { Bot, Context, session, SessionFlavor } from 'grammy'
import { CustomSessionAdapter } from './session'
// This bot will collect some basic statistics about each chat. They can be
// retrieved with the `/stats` command.
// This is the data that will be saved per chat.
interface SessionData {
messages: number
edits: number
}
// flavor the context type to include sessions
type MyContext = Context & SessionFlavor<SessionData>
// Create a bot
export const bot = new Bot<BotContext>(process.env.BOT_TOKEN);
// Note that using `session()` will only save the data in-memory. If the Node
// process terminates, all data will be lost. A bot running in production will
// need some sort of database or file storage to persist data between restarts.
// Confer the grammY documentation to find out how to store data with your bot.
bot.use(session({ initial: () => ({ messages: 1, edits: 0 }), storage: CustomSessionAdapter() }))
// Check https://github.com/grammyjs/examples/blob/main/stats.ts on how to proceed
import { supabase } from "./supabase";
interface Session {
id: string;
session: string;
}
export function CustomSessionAdapter<T>() {
const db = supabase.from<Session>("bot_sessions");
return {
read: async (id: string) => {
const { data, error } = await db.select("session").eq("id", id).single();
if (error || !data) {
if (error) {
console.log("read ==> ", { error });
}
console.log("read ==> ", { data });
return undefined;
}
return JSON.parse(data.session) as T;
},
write: async (id: string, value: T) => {
const input = { id, session: JSON.stringify(value) };
const { error } = await db.upsert(input, { returning: "minimal" });
if (error) {
console.log("write ==> ", { error });
}
},
delete: async (id: string) => {
const { error } = await db.delete({ returning: "minimal" }).match({ id });
if (error) {
console.log("delete ==> ", { error });
}
},
};
}
import { createClient } from "@supabase/supabase-js"; // install supabase first
export const supabase = createClient(process.env.SUPABASE_URL, process.env.SUPABASE_SECRET_KEY);
@KnorpelSenf
Copy link

Should use MyContext not BotContext in bot.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment