Handing off to human on Slack

I get this errors

I’m using slackclient==2.5.0

hey @nbeuchat

now I’m using slackclient==1.2.1, I can send a message to slack channel and I get this message “hello i’m a human agent what do you want ?” and conversation paused but I still get no response from slack channel

can you help me ?

Hey @KhalidBentaleb could you upgrade to slackclient~=1.3.2 (which is the one I use so I can help)

But when you send a message with the API, what do you get exactly in the response? Is it None? Is it an object? A dict?

The same problem when I upgrade to slackclient~=1.3.2, I get None

hey @nbeuchat I still get no response from slack channel

Let’s forget about the bot for a moment. Can you send a message to the Slack channel from a normal python prompt? What response do you get from the slack client?

yes I send a message to the slack channel from a normal python prompt and I get this response {‘ok’: True, ‘channel’: ‘C0123EJAP3Q’, ‘ts’: …

1 Like

Cool :slight_smile: From the log, it seems that there is 1) an async issue (that’s a huge pain, that’s why I downgraded to 1.3 as that worked for me), 2) you have not authenticated the client. How do you authenticate it?

Can you also post the code of your action?

For custom actions I get same response

code of my action :

client_slack = SlackClient(token)

class ActionHandoverToSupport(Action): def name(self): return “action_handover_to_support”

def run(
    self,
    dispatcher,
    tracker,
    domain,
):
    events = []
    text = f"@canal Help needed for user {tracker.sender_id}"
    response = client_slack.api_call(
        "chat.postMessage", channel="#chatbot", text=text, link_names=1
    )
    print(response)

    if response.get("ok"):
        dispatcher.utter_message(template="utter_handover_to_support")
        events.append(ConversationPaused())
    else:
        dispatcher.utter_message(
            template="utter_technical_issue",
            extra_message="I could not send a message to my humans 😢",
        )

    return events

Did you check that your token is correctly set here? From the logs you shared earlier it said you were not authenticated

when I used slackclient==1.3.2, I didn’t get any logs so my token is correctly

I’ve got the simple part working using slackclient==2.5.0 with minor modifications to the code above:

import os
from slack import WebClient
from slack.errors import SlackApiError

client_slack = WebClient(token=os.environ["SLACK_API_TOKEN"], run_async=True)
SLACK_SUPPORT_CHANNEL = os.environ["SLACK_SUPPORT_CHANNEL"]


class ActionHumanHandoff(Action):
    def name(self):
        return "action_human_handoff"

    async def run(
        self, dispatcher, tracker, domain, reason: Text = None,
    ):
        events = []
        text = f"Help needed for user {tracker.sender_id}"
        try:
            response = await client_slack.chat_postMessage(
                channel=SLACK_SUPPORT_CHANNEL, text=text
            )
            if response.get("ok"):
                dispatcher.utter_message(template="utter_handover_to_support")
                events.append(ConversationPaused())
        except SlackApiError as e:
            dispatcher.utter_message(
                template="utter_technical_issue", extra_message=e.response["error"],
            )
        return events

In data/nlu.md:

## intent:request_human
- let me speak to a human
- agent
- real person

And domain.yml:

actions:
  - action_human_handoff
intents:
  -
    request_human: {"triggers": "action_human_handoff"}

The message comes through to Slack just fine, but obviously there’s more to it than that and I’m not exactly sure what! It would seem that I somehow need to forward the messages sent by a human in Slack to the user connected to the Rasa bot, but how and where?

@mia.le0711 what @k1m was asking, once the conversation is paused and the initial message sent to Slack, how can the human operator take over from the bot in the conversation with the user?

So the user’s messages must be forwarded to Slack, and the human operator’s messages must be forwarded to the user until it is indicated that the bot can take over again.

@cck197 @nbeuchat @k1m @KhalidBentaleb @mia.le0711
How do you resume the conversation after pausing it? I ran a custom action that returned a ConversationPaused() event and now the bot ignores everything I send it.

@basil-chatha Great question! The only way I found is to use the execute action endpoint through the API. In our case, we have a team of human agents that take over the conversation and have a button in their system to unpause the bot. That buttons triggers POST request to the execute action endpoint.

URL: https://{{url}}/conversations/{{sender_id}}/execute?token={{token}}

with the body being:

{
	"name": "action_resume_bot"
}

See the documentation: HTTP API

Note that this endpoint is deprecated now. I have no idea how we could do that without it. It has been replaced by the trigger intent endpoint (see: HTTP API) but this won’t work in the case the bot is paused. Beware that the tracker history will be massively broken as intents from the users are still registered but there are no actions/utterances on the bot side. Might be worth restarting the bot as well.

EDIT:

There is actually a way to use the non-deprecated API endpoints. I have not tested it though.

See @Tobias_Wochinger answer in an issue we discussed a while back: prediction fails after resuming bot · Issue #5645 · RasaHQ/rasa · GitHub (text copied from his answer)

  • directly append the ConversationResume() event via HTTP API
  • use this endpoint to trigger the action_resume_bot with an intent. This has the advantage that you can write stories for it so that the model learns how to deal with it

You can then do whatever you want in the action_resume_bot (resetting the state of the conversation, slots, etc.)

I hope that helps! Cheers Nicolas

1 Like

@nbeuchat Thanks! Curious, how do you go about routing the message from the user to the human agents once you’ve paused the conversation? Would I have stories in stories.md that tell it to run a specific custom action after a conversation paused event or something to that effect?

@basil-chatha We actually do that outside of Rasa. Our customer support team is connected to Facebook Messenger (that’s our only bot channel) through Front (https://frontapp.com/). They can then jump into the conversation.

Once the bot is paused, you can’t run actions. The only way to run actions is to unpause the bot and trigger an intent to run an action.

You can write stories for after the action is resumed. My recommendation is to actually restart the conversation as well in your custom resume action so you have a clean tracker.

@nbeuchat

Ah ok cool thank you! So In my implementation I’m trying to set a slot that tells rasa to do something when the human agent decides to end the chat with the following request:

curl -X POST \
  'http://url/api/conversations/default/tracker/events?include_events=NONE' \
  -H 'Content-Type: application/json' \
  -d '{"event":"slot","name":"name","value":"Tanja","timestamp":0}'

However, I’m getting a Not Found response. Do you know what that could mean or how to fix it?

Hey @basil-chatha, the problem is your url (the part where it’s written url). I suppose you are doing this locally so you need to use localhost with the correct port.

@nbeuchat I actually have it running on Google Cloud Platform so the url is of form rasabot.com