Slack buttons fail silently

Hi,

I am trying to talk to my agent on Slack. I have the actions server and a dialogue handler (rasa_core/rasa_nlu) setup in 2 docker containers running on azure. The dialogue handler has a publicly available url which I have placed into interactive components and event subscriptions fields.

Talking to my bot using text works completely fine.

I can see the button requests from slack hit my dialogue handler.

I use the following command to run the actions server: python -m rasa_core_sdk.endpoint --actions actions.main

dialogue handler: python -m rasa_core_sdk.endpoint --actions actions.main

Does anyone have any idea why my buttons don’t work?

Can you attach the log from rase core? how do you define the buttons?

@tmbo, thanks for responding!

Here are the logs from my Rasa core instance:

10.240.255.56 - - [2019-01-28 10:27:42] "POST /webhooks/slack/webhook HTTP/1.1" 200 147 0.001447
10.240.255.55 - - [2019-01-28 10:28:34] "POST /webhooks/slack/webhook HTTP/1.1" 200 147 0.001075

Here is the button definition in my domain.yaml:

  utter_greet:
  - buttons:
    - payload: /my_correct_intent_here{}
      title: Some simple text goes here
    - payload: /tutorial{}
      title: I don't know

Any ideas?

Yes the log looks about right so does the definition in the domain.

@akelad, you set up a slack bot before, right? did you try the buttons?

I did, but I can’t remember if I tested buttons. What happens when you click the button? And can you show the deubg log of rasa_core? the curly brackets at the end of your intent in the button definition looks a bit weird

Nothing else appears in the debug log.

As for the curly braces, what should they look like?

Sidenote: my_correct_intent_here is a FormIntent, so I want the button to trigger the first required slot of the form. tutorial is just a normal intent

the curly braces shouldn’t be there.
And hm, are you running the rasa_core command with the --debug flag? And what happens when you click the button, nothing? Or does a random message get sent?

These are the logs from the debug mode.

Nothing happens when I click the button.

I don’t even get the error message Slack gives you when your interactive components webhook isn’t setup correctly.

That’s weird, can you see the other messages properly arriving in your logs? @ricwo you setup the slack channel right, did you test buttons?

Here are some of the logs from my bot (adjusted for confidential info). They look alright to me…

Logs
2019-02-01 13:32:10 DEBUG    rasa_core.processor  - Received user message 'open up the fkdfjksfl' with intent '{'name': 'rdfsdfsfsffl', 'confidence': 0.680607795715332}' and entities '[{'start': 12, 'end': 24, 'value': 'fsdfsdfsdf', 'entity': 'fsdlfks;ldfk;lsdf', 'confidence': 0.64630477285411, 'extractor': 'ner_crf', 'processors': ['ner_synonyms']}]'
2019-02-01 13:32:10 DEBUG    rasa_core.processor  - Logged UserUtterance - tracker now has 1220 events
2019-02-01 13:32:10 DEBUG    rasa_core.processor  - Current slot values: 
	fjdkfjsdlfj: None
	fksdfk;lsdfksd: None
	fjsdlfjsdlf: fjdkfjsdlfj
	fsfsdfsdf: None
	results: None
2019-02-01 13:32:10 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, None, None, {}, {'entity_fsdlfks;ldfk;lsdf': 1.0, 'prev_action_listen': 1.0, 'intent_fsfsdlfsdfksd': 1.0}]
2019-02-01 13:32:10 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-02-01 13:32:10 DEBUG    rasa_core.policies.form_policy  - There is an active form 'fsdkfjsdlfjsldfj'
2019-02-01 13:32:10 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_3_FormPolicy
2019-02-01 13:32:10 DEBUG    rasa_core.processor  - Predicted next action 'fsdkfjsdlfjsldfj' with prob 1.00.
2019-02-01 13:32:10 DEBUG    rasa_core.actions.action  - Calling action endpoint to run action 'fsdkfjsdlfjsldfj'.
2019-02-01 13:32:10 DEBUG    rasa_core.actions.action  - Failed to validate slot fjdkfjsdlfj with action fsdkfjsdlfjsldfj
2019-02-01 13:32:10 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, {}, {'entity_fsdlfks;ldfk;lsdf': 1.0, 'prev_action_listen': 1.0, 'intent_fsfsdlfsdfksd': 1.0}, {'entity_fsdlfks;ldfk;lsdf': 1.0, 'active_form_fsdkfjsdlfjsldfj': 1.0, 'intent_fsfsdlfsdfksd': 1.0, 'prev_fsdkfjsdlfjsldfj': 1.0}, {'entity_fsdlfks;ldfk;lsdf': 1.0, 'prev_action_listen': 1.0, 'active_form_fsdkfjsdlfjsldfj': 1.0, 'intent_fsfsdlfsdfksd': 1.0}]
2019-02-01 13:32:10 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-02-01 13:32:10 DEBUG    rasa_core.policies.form_policy  - There is an active form 'fsdkfjsdlfjsldfj'
2019-02-01 13:32:10 DEBUG    rasa_core.policies.ensemble  - Action 'action_listen' was predicted after a user message using policy_0_KerasPolicy. Predicting fallback action: action_default_fallback
2019-02-01 13:32:10 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_FallbackPolicy
2019-02-01 13:32:10 DEBUG    rasa_core.processor  - Predicted next action 'action_default_fallback' with prob 1.00.
2019-02-01 13:32:11 DEBUG    rasa_core.processor  - Action 'action_default_fallback' ended with events '['UserUtteranceReverted()']'
2019-02-01 13:32:11 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: Hrrm, I didn"t quite get that. Can you try to say that another way?, data: {
  "elements": null,
  "buttons": null,
  "attachment": null
})'
2019-02-01 13:32:11 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, None, None, {}, {'entity_fsdlfks;ldfk;lsdf': 1.0, 'prev_action_listen': 1.0, 'intent_fsfsdlfsdfksd': 1.0}]
2019-02-01 13:32:11 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-02-01 13:32:11 DEBUG    rasa_core.policies.form_policy  - There is an active form 'fsdkfjsdlfjsldfj'
2019-02-01 13:32:11 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_3_FormPolicy
2019-02-01 13:32:11 DEBUG    rasa_core.processor  - Predicted next action 'action_listen' with prob 1.00.
2019-02-01 13:32:11 DEBUG    rasa_core.processor  - Action 'action_listen' ended with events '[]

@DMPS I just tried to replicate the issue and can confirm that button replies aren’t processed correctly. We tested button replies early on in one of the first iterations of the slack channel in Rasa Core. I’ve reported the bug on github - we’ll look into it soon!

I’ve looked at the slack.py, the fault is that the Slack structure has changed the payload for the buttons. All references to slack_event[‘payload’][0] are incorrect. The new structure is one level more shallow (i.e. you can drop the [0] dereference). I changed the following code (a significant change to is_button_reply, because the previous version only checked that a name was set)

@staticmethod
def _is_button_reply(slack_event):
    pay = json.loads(slack_event['payload']);
    evaluation = (pay['type'] == u"interactive_message") and (pay['actions'][0]['type'] == u"button");
    return( evaluation );
##        return (slack_event.get('payload') and                                                                                                                                                                                     
##                slack_event['payload'][0] and                                                                                                                                                                                      
##                'name' in slack_event['payload'][0])                                                                                                                                                                               

A minor change to get button reply

@staticmethod
def _get_button_reply(slack_event):
    return json.loads(slack_event['payload'])['actions'][0]['name']
    ## return json.loads(slack_event['payload'][0])['actions'][0]['name']                 

and a similar change in blueprint

## sender_id = json.loads(output['payload'][0])['user']['id']                                                                                                                                                            
sender_id = json.loads(output['payload'])['user']['id']

That will put your buttons back online.

Best wishes,

M

1 Like

@akelad if you want these putting into a pull request let me know

@mark_collins, thank you for the code!

Unfortunately, I can’t use it until it gets into a release of the rasa_core docker image.

If you could put you code in a PR, perhaps @akelad or @tmbo could quickly do the code review and merge it. I suggest you link the PR to @ricwo’s earlier Github issue: Slack button replies aren't processed · Issue #1671 · RasaHQ/rasa_core · GitHub.

Out of curiosity, @ricwo mentioned something about the chat.attachmentAction. Was that a red herring?

@DMPS I’ll pop it into a pull request for you, I just put it together as a quick fix, and I was expecting @akelad or @tmbo to weigh in with some insight into whether the problem extended further. The chat.attachmentAction I’ve not looked at, so @ricwo may well have been right. If I find it is broken and I need that functionality I’ll fix it as well :slight_smile:

PR has been submitted.

Best wishes,

M

1 Like

@DMPS @ricwo Yep, the chat.attachmentAction is broken also. Seems to only occur with more than two buttons?!? The slack implementation is clearly a little bit more broken than it first appeared. I’ll take a look later today.

Best wishes,

M

– edit

The callback_id issue is caused by the expectation that messages with buttons will always contain a message and not just buttons. The callback_id being derived from the message ends up empty if there is no message.

@mark_collins I have the same issue with slack buttons where nothing happens when I click a button. But there are no errors. I see that you’ve changed some part of the code in slack.py to put the buttons back online. Can you tell me how I can use it?

@sagari The problem is that the slack structures have changed. We will eventually get a patched version, the changes I made are in process to being accepted into the main build. In the meantime, if you are happy to edit the python in the running version of Rasa-core then the file is called slack.py and the changes are as described above. I found a couple of issues with the slack.py code, so for best results I recommend you update at least the functionality around the message-callback-id as well as removing the [0] from the payload references.

If you don’t know how to do any of these things, I can email you the code copy I have here, and you can replace the slack.py file in its entirety. And if that sounds scary, I’m afraid you’ll have to wait until Rasa release a build with the changes - which is the long term solution anyway :wink:

Best wishes,

M

1 Like

@mark_collins is making changes in slack.py still the solution? I tried to make the changes you suggested, but now I get the error: Encountered an exception while running action ‘action_default_ask_affirmation’. Bot will continue, but the actions events are lost. Make sure to fix the exception in your custom code. This is the code I use

class ActionDefaultAskAffirmation(Action):

"""Vraag om bevestiging als confidence van de intent niet boven NLU threshold is."""
def name(self) -> Text:
    return "action_default_ask_affirmation"

def __init__(self) -> None:
    import csv

    self.intent_mappings = {}
    with open('data/intent_description_mapping.csv',
              newline='',
              encoding='utf-8') as file:
        csv_reader = csv.reader(file)
        for row in csv_reader:
            for item in row:
                listrow = item.split(';')
            self.intent_mappings[listrow[0]] = listrow[1]

def run(self, dispatcher: CollectingDispatcher,
        tracker: Tracker, domain: Dict[Text, Any]) -> List['Event']:

    intent_ranking = tracker.latest_message.get('intent_ranking', [])
    
    '''Als meer dan 1 intent wordt gevonden, bereken verschil tussen eerste en tweede optie.
    Als verschil kleiner is dan 0.2, geef beide opties, als verschil groter is dan 0.2, geef alleen eerste optie'''
    if len(intent_ranking) > 1:
        diff_intent_confidence = (intent_ranking[0].get("confidence") -
                                  intent_ranking[1].get("confidence"))
        if diff_intent_confidence < 0.2:
            intent_ranking = intent_ranking[:2]
        else:
            intent_ranking = intent_ranking[:1]
    first_intent_names = [intent.get('name', '')
                          for intent in intent_ranking
                          if intent.get('name', '') != 'out_of_scope']
    
    mapped_intents = [(name, self.intent_mappings.get(name, name))
                      for name in first_intent_names]

    entities = tracker.latest_message.get("entities", [])

    entities_json, entities_text = get_formatted_entities(entities)

    buttons = []

    for intent in mapped_intents:
        buttons.append({'title': intent[1] + entities_text,
                        'payload': '/{}{}'.format(intent[0],
                                                  entities_json)})
    if buttons == []:
        buttons.append({'title': 'Vertel me wat je kan',
                    'payload': '/wat_kan_je'})
        buttons.append({'title': 'Iets anders',
                    'payload': '/out_of_scope'})            
        message_title = "Sorry, dat heb ik niet begrepen. Wat zal ik doen?"
        
    else:    
        buttons.append({'title': 'Iets anders',
                    'payload': '/out_of_scope'})
        message_title = "Sorry, ik weet niet zeker of ik het goed heb begrepen. Wil je..."
    dispatcher.utter_button_message(message_title, buttons=buttons)

    return []