grammyjs / conversations

Conversational interfaces for grammY.
https://grammy.dev/plugins/conversations
MIT License
53 stars 17 forks source link

bug: Conversation with session { type: "multi" } returns error when cleaning session object. #29

Closed vitorleo closed 2 years ago

vitorleo commented 2 years ago

When using the conversation plugin with a bot that uses session { type: "multi" }, it presents an error at the end of the conversation:

TypeError: Cannot delete property 'conversation' of #<Object>
.....\node_modules\@grammyjs\conversations\out\conversation.js:294:17
require('dotenv').config()
const { TELEGRAM_BOT_TOKEN } = process.env
const { Bot, Context, session, webhookCallback, InputFile } = require("grammy");
const { conversations, createConversation, ConversationForm } = require("@grammyjs/conversations");

const bot = new Bot(TELEGRAM_BOT_TOKEN);  

// Create multi session
bot.use(session({
  type: "multi",
  ui: {
    initial: () => ({
      currentAlert: null,
      alerts: [] 
    })
  },
  conversation: {}
}));

// Function to interrupt and exit the conversation and remover keyboard
const endConversation = async function (ctx) {
    const msg = 'Goodbye. Type /thl, to start over.'
    await ctx.reply(msg, {
        reply_markup: { remove_keyboard: true },
    });
}

// -------- CONVERSATION start ---------
const conversationTHL = async function (conversation, ctx) {
    await ctx.reply('Calls or puts?', {
        reply_markup: {
            one_time_keyboard: true,
            keyboard: [[{text:'calls'}], [{text:'puts'}]],
            resize_keyboard: true
        }
    })

    let resposta  = await conversation.form.select(['calls', 'puts', 'fim']);

    if (resposta.toLowerCase() == 'fim') { endConversation(ctx); return } 

    // LOWER strike question
    await ctx.reply(`LOWER strike with ${resposta}?`, {
        reply_markup: {
            one_time_keyboard: true,
            keyboard: [[{text:'1'}, {text:'2'}, {text:'3'}, {text:'4'}]],
            resize_keyboard: true
        }
    });

    resposta  = await conversation.form.select(['1', '2', '3', '4', 'fim']);
    if (resposta.toLowerCase() == 'fim') { endConversation(ctx); return } 

    // HIGHER strike question
    await ctx.reply(`HIGHER strike with ${resposta}?`, {
        reply_markup: {
            one_time_keyboard: true,
            keyboard: [[{text:'4'}, {text:'3'}, {text:'2'}, {text:'1'}]],
            resize_keyboard: true
        }
    });

    resposta  = await conversation.form.select(['1', '2', '3', '4', 'fim']);
    if (resposta.toLowerCase() == 'fim') { endConversation(ctx); return } 

    await ctx.reply('Ok. If you got here that means the conversation works!');
}
// -------- CONVERSATION end --------

// Add conversation to bot
bot.use(conversations());
bot.use(createConversation(conversationTHL));

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

// Webhooks callback handling
const handleUpdate = webhookCallback(bot, 'express')

// AZURE functions HTTP trigger
module.exports = async function  (context, req) {
    console.log('-----------------------------'); 
    context.log('JavaScript HTTP trigger function processed a request.'); 

    // Mapping objects to work with express adapter
    req.header = function(k) {
        return context.res.headers[k]
    }
    context.res.end = function() {
        return context.res = {
            status: 200,
            body: ''
        }
    }

    try {
        await handleUpdate(req, context.res)
    } catch (err) {
        console.error(err)
    }

    console.log('END -----------------------------');
}
jeshio commented 2 years ago

Yes, same problem

KnorpelSenf commented 2 years ago

This is indeed a bug, it'll have to be fixed in the plugin.

KnorpelSenf commented 2 years ago

Please review #47.