grammyjs / conversations

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

Using ctx.reply in conversation.external terminates bot #68

Closed receter closed 3 weeks ago

receter commented 1 year ago

I am fetching some data in a conversation and would need to call ctx.reply inside of the conversation.external function. If doing so afterwards any new update will terminate the bot.

If doing it outside of conversation.external it does work, but in my use case this is not really an option as I want to update the message several times while the API is fetching.

I have created a minimal example project which can be found here: https://github.com/receter/grammy-conversations-reply-external

KnorpelSenf commented 1 year ago

Is this a duplicate of #57? It seems to me like it is

receter commented 1 year ago

Yes, the symptoms are not exactly the same, but it seems to be related. I have issue #57 as well with an api that I am manually binding to the context via middleware. It is available in ctx.myapi at first but as soon as the conversation continues ctx.myapi is undefined.

receter commented 1 year ago

Here is something I observed fot the ctx issue: The first time the conversation is played, my api object in the context is:

MyAPI {
  basePath: '...',                
  ...
  axios: <ref *1> [Function: wrap] {    
    ...
  },
  configuration: Configuration {
    ...
  }
}

And in the next update, when I log it at the same line it looks like it got serialized:

{
  basePath: '...',
  axios: 'configuration',
  configuration: {
    ...
  }
}
KnorpelSenf commented 1 year ago

I think this can be fixed by installing your API inside a conversation.run rather than in some middleware. See https://grammy.dev/plugins/conversations.html#working-with-plugins for this.

This means you should have something like

await conversation.run(async (ctx, next) => {
  ctx.myapi = ... // set your custom context property here
  await next()
})

in your conversation, rather than doing this in your middleware upfront.