grammyjs/conversations

Writing session data in conversations

jokroese opened this issue · 1 comments

I am trying to write session data within a conversation. However, that data does not persist outside of the conversation.

I suspect this is due to me not understanding how to incorporate Golden Rule 1 of conversations. However, my attempts with wrapping the call to write the data in conversation.external() have not worked.

Where am I going wrong?

import { Bot, Context, session, SessionFlavor } from "grammy";
import { BOT_TOKEN } from "./config";
import {
  type Conversation,
  type ConversationFlavor,
  conversations,
  createConversation,
} from "@grammyjs/conversations";

interface SessionData {
  cats: Array<string>;
}

type MyContext = Context & ConversationFlavor & SessionFlavor<SessionData>;
type MyConversation = Conversation<MyContext>;

const bot = new Bot<MyContext>(BOT_TOKEN);

bot.use(session({ initial: () => ({ cats: ["marina"] }) }));
bot.use(conversations());

async function greeting(conversation: MyConversation, ctx: MyContext) {
  await ctx.reply(
    `Hi there! Your first cat is called ${ctx.session.cats[0]}. What is your second cat's name?`
  );
  const message = await conversation.form.text();
  await ctx.session.cats.push(message); // <-- important part
  // await conversation.external(() => ctx.session.cats.push(message)); // also doesn't work
  ctx.reply(`Your cats are called ${JSON.stringify(ctx.session.cats)}.`);
}

bot.use(createConversation(greeting));

bot.command("start", async (ctx) => {
  await ctx.conversation.enter("greeting");
});

bot.command("show_data", (ctx) => {
  ctx.reply(JSON.stringify(ctx.session.cats));
});

bot.start();

Interacting with this bot goes as follows:

/start
// Hi there! Your first cat is called marina. What is your second cat's name?
hermione
// Your cats are called ["marina","hermione"].
/show_data
// ["marina"]

Solved through the Grammy telegram channel - thanks @KnorpelSenf!

To make this work, we need to replace ctx.session with conversation.session, turning the key line into await conversation.session.cats.push(message).