botman / driver-hangouts

BotMan Hangouts Chat Driver
MIT License
10 stars 5 forks source link

Issue with Multiple Replies #3

Open stefanzweifel opened 6 years ago

stefanzweifel commented 6 years ago

Hey there 👋,

I have an issue while sending multiple replies with the Hangouts driver: Only the first appears, the others are not visible in the chat. My bot should send the different menus of the canteen into a room or DM. Code looks basically like this:

$botman->hears('menu', function ($bot) {

    $bot->reply('Looking for menues…');

    // Do some API calls to get the menues

    $todaysMenus = collect([
        ['title' => 'Menu 1: Food A'],
        ['title' => 'Menu 2: Food B'],
        ['title' => 'Menu 3: Food C']
    ]);

    $todaysMenus->each(function ($menu) use ($bot) {
        $bot->reply($menu['title']);
    });
});

The Web- and Telegram Driver correctly sends 4 replies:

Web Driver

image

Telegram Driver

image

The Hangouts driver however only shows the first reply 🤔:

image

I've hooked myself into the sendPayload method of Botman to see, what the Hangouts driver sends to Google, but in my eyes, everything looks fine 🤷‍♂️ :

[2018-08-11 12:57:03] local.INFO: array (
  'text' => 'Looking for menues 👀',
  'cards' => 
  array (
    0 => 
    array (
      'sections' => 
      array (
        0 => 
        array (
          'widgets' => 
          array (
          ),
        ),
      ),
    ),
  ),
)  
[2018-08-11 12:57:03] local.INFO: array (
  'text' => 'Menu 1: Food A',
  'cards' => 
  array (
    0 => 
    array (
      'sections' => 
      array (
        0 => 
        array (
          'widgets' => 
          array (
          ),
        ),
      ),
    ),
  ),
)  
[2018-08-11 12:57:03] local.INFO: array (
  'text' => 'Menu 2: Food B',
  'cards' => 
  array (
    0 => 
    array (
      'sections' => 
      array (
        0 => 
        array (
          'widgets' => 
          array (
          ),
        ),
      ),
    ),
  ),
)  
[2018-08-11 12:57:03] local.INFO: array (
  'text' => 'Menu 3: Food C',
  'cards' => 
  array (
    0 => 
    array (
      'sections' => 
      array (
        0 => 
        array (
          'widgets' => 
          array (
          ),
        ),
      ),
    ),
  ),
)  

I know that Hangouts Chat is not the sexiest Chat app but I would really appreciate it if anyone has some ideas, where Botman falls apart here.

If I should provide more code details or other information: I'm happy to provide everything.

Appendix

I could fix my bot by only ever reply once. (But it seems a bit hacky)

$botman->hears('menu', function ($bot) {

    // Do some API calls to get the menues

    $todaysMenus = collect([
        'Menu 1: Food A',
        'Menu 2: Food B',
        'Menu 3: Food C'
    ]);

    $bot->reply($todaysMenus->implode("\n"));
});
jonodonovan commented 5 years ago

I'm seeing the same issue, only the first response comes through

mattlibera commented 4 years ago

I noticed this too. It's not a huge deal unless you're dealing with really long responses (like lists, which I am tinkering with). Chat has a limit of ~4000 chars to a message, and silently fails if you send a message that's too long, so in my case I figured using Laravel's chunk() method would do the trick - chunk the result and send multiple messages.

Well then I noticed this issue, and so I had to break it down further - I ended up implementing a sort of "pagination", where I store the chunks in user storage, and then the user types next to retrieve the next chunk. It's not pretty, but... it works.

I'd love to see this Driver get some updates. If our use case takes off, I might see what I can do...

mattlibera commented 4 years ago

I'm digging deeper into this and have noticed the same thing that @stefanzweifel did - the payloads are being sent properly. It seems that the issue could be on the Google Chat end... potentially with their synchronous vs. asynchronous response methodology: https://developers.google.com/hangouts/chat/how-tos/bots-develop#syncresponse

I shoved a sleep(10) into the sendPayload() method on this driver to see what would happen, and sent two replies from a test endpoint. I noticed that I ended up with no response in Google Chat at all, until after both requests had been sent.

So my guess is that Google is basically just swallowing up the second one somehow. I'm going to see what I can do to keep digging on this.

Edit - looking here: https://developers.google.com/hangouts/chat/concepts/structure?hl=en_US seems to confirm that I'm on the right track. Re: synchronous:

In this pattern, the bot responds to messages from users on a one-to-one basis. One user message to the bot results in one response from the bot.

Asynchronous responses would need to be implemented in order to send multiple replies back... for that you would need to look into using service accounts, and implement some sort of thread tracking. I don't think this driver is wired for service accounts, so I think any progress here would have to take that under consideration.