How to initiate conversation with user from Rasa (send notification)

Hello!

Use case:

Technical support bot, It receives messages from users, asking additional info and creating issue in ticket system.

I want to achive user notification from same bot.

Example:

User: i have problem
Bot: which problem?
User: Network problem
Bot I've opened ticket #123 for you
... <ticket system push some request to rasa> ...
Bot: Your ticket #123 has been resolved

Is is possible?

My testing attempts:

I have very simply action: grab last message and post it back to the user:

class Test(Action):
    def name(self):
        return 'action_test'

    def run(self, dispatcher, tracker, domain):
        last_message = tracker.latest_message.get("text", "")
        dispatcher.utter_message('Echo:')
        dispatcher.utter_message(last_message)

        return []

What i’ve tried:

  1. Append a reminder event to the tracker.

       POST http://localhost:5005/conversations/{conversation_id}/tracker/events
       {
         "event": "reminder",
         "action": "action_test",
         "date_time": "2019-05-29T02:50:10.128172",
         "name": "my_reminder",
         "kill_on_user_msg": true.
       }
    

What I see in the logs (with --debug --verbose keys):

rasa_1           | 2019-05-29 02:41:09 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'
rasa_1           | 2019-05-29 02:44:23 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'
rasa_1           | 2019-05-29 02:45:43 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'
rasa_1           | 2019-05-29 02:45:54 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'
rasa_1           | 2019-05-29 03:03:19 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'

Nothing happens at shedulled time, even no errors in logs.

  1. Execute an action via http api

As description says “Any responses sent by the executed action will be returned as part of the endpoints result, they will not be sent over a connected output channel.” - user not recieved responce from action.

  1. Post the message to the REST channel:

    POST http://localhost:5005/webhooks/rest/webhook
    {
    "sender": "{conversation_id}",
    "message": "action_test" 
    }
    

In such way, reply was sent back to the rest channel, not via connected output channel.

As I see in the logs, my conversation_id = user_id in connected output channel:

   rasa_1           | 2019-05-30 02:28:36 DEBUG    rasa.core.agent  - Created a new lock for conversation '{conversation_id}'
   rasa_1           | 2019-05-30 02:28:36 DEBUG    rasa.core.tracker_store  - Recreating tracker for id '{conversation_id}'
  1. Post the message to the connected output channel with user_id

    POST http://localhost:5005/webhooks/telegram/webhook
    {
     "update_id": {event id},
     "message": {
         "message_id": {message id},
         "from": {
             "id": {conversation_id},
             "is_bot": false,
             "first_name": "",
             "username": "",
             "language_code": "ru"
         },
         "chat": {
             "id": {conversation_id},
             "first_name": "",
             "username": "",
             "type": "private"
         },
         "date": {unix time stamp},
         "text": "action_test"
     }
    }
    

With this method, user receives message, but I’am not sure, what it is the right way, to implement notification function (i should specify messanger related attributes in the request, like update_id, message_id, user first_name, username… and so on).

So main question, how can I call Rasa action from other system on my side, to notify my users via connected output channel?

Use cases: birthday reminder, notification from monitoring system, notification about ticket resolution etc.

Hi @selphe , have you tried just returning a ReminderScheduled() event from your custom action?

Hi @akelad I’ve tried:

    class TestActionSchedule(Action):
        def name(self):
            return 'action_test_schedule'

        def run(self, dispatcher, tracker, domain):
            return [ReminderScheduled(action_name='action_test_notify')]


    class TestActionNotify(Action):
        def name(self):
            return 'action_test_notify'

        def run(self, dispatcher, tracker, domain):
            dispatcher.utter_message('test notify')
            return []

Then tried put a reminder:

POST http://localhost:5005/conversations/abc123/tracker/events
   {
     "event": "reminder",
     "action": "action_test_schedule",
     "date_time": "2019-06-17T16:57:10.128172",
     "name": "my_reminder",
     "kill_on_user_msg": true
   }

In logs:

2019-06-17 16:56:04 DEBUG    rasa.core.tracker_store  - Recreating tracker for id 'abc123'

Also, I’ve tried return just ReminderScheduled() in action_test_notify, and call this action via event, but no success (same message in log)

Sorry, but I still can’t figure out how this should work. Do you have an example?

@Ghostvv can you take a look at this?

Hi @selphe, in your code snippet above I don’t see that you passed trigger_date_time for ReminderScheduled

Hello @Ghostvv, Didn’t trigger_date_time sets from POST request? Anyway, in my code example above i’ve set it directly in return of action_test_schedule: trigger_date_time='2019-06-19 09:50:30.942508'

Response from POST
{
  "sender_id": "abc123",
  "slots": {
    "auth": null
  },
  "latest_message": {
    "intent": {
      "name": "greet",
      "confidence": 0.9154055118560791
    },
    "entities": [],
    "intent_ranking": [
      {
        "name": "greet",
        "confidence": 0.9154055118560791
      }
    ],
    "text": "hi"
  },
  "latest_event_time": 1560912532.6339908,
  "followup_action": null,
  "paused": false,
  "events": [
    {
      "event": "action",
      "timestamp": 1560912513.7582748,
      "name": "action_listen",
      "policy": null,
      "confidence": null
    },
    {
      "event": "user",
      "timestamp": 1560912513.8670504,
      "text": "hi",
      "parse_data": {
        "intent": {
          "name": "greet",
          "confidence": 0.9154055118560791
        },
        "entities": [],
        "intent_ranking": [
          {
            "name": "greet",
            "confidence": 0.9154055118560791
          }
        ],
        "text": "hi"
      },
      "input_channel": "telegram"
    },
    {
      "event": "action",
      "timestamp": 1560912514.2715187,
      "name": "utter_greet",
      "policy": "policy_0_MemoizationPolicy",
      "confidence": 1.0
    },
    {
      "event": "bot",
      "timestamp": 1560912514.2715187,
      "text": "Hello đź––",
      "data": {
        "elements": null,
        "quick_replies": null,
        "buttons": null,
        "attachment": null,
        "image": null,
        "custom": null
      },
      "metadata": {}
    },
    {
      "event": "action",
      "timestamp": 1560912514.4364905,
      "name": "action_listen",
      "policy": "policy_0_MemoizationPolicy",
      "confidence": 1.0
    },
    {
      "event": "reminder",
      "timestamp": 1560912520.8946462,
      "action": "action_test_schedule",
      "date_time": "2019-06-19T09:45:30.942508",
      "name": "my_reminder",
      "kill_on_user_msg": true
    },
    {
      "event": "reminder",
      "timestamp": 1560912532.6339908,
      "action": "action_test_schedule",
      "date_time": "2019-06-19T09:50:30.942508",
      "name": "my_reminder",
      "kill_on_user_msg": true
    }
  ],
  "latest_input_channel": "telegram",
  "active_form": {},
  "latest_action_name": "action_listen"
}

Behaviour is the same, nothing happens at scheduled time, except recreating tracker in core logs.

I run it locally, so I believe, I can rely on time and date in task bar.

Anyhow, if I understand this function right, it can be used for schedule action, e.g. “turn of the light at morning”, so reminder expects entities? I can’t pass through whole message directly to user via request to rasa api?

Summarizing:

  1. I’m able to put reminder from input channel (e.g. Telegram), but not able to put it via HTTP API, so I can’t notify my users via reminder.
  2. I’m able to notify my users through endpoint /webhooks/<channel>/webhook, via mimic user ID and passing "/intent{"notify_slot":"text"} on behalf of username, but I’m not sure that is correct way.

May be someone know, or can guide me to better way to inform users throught Rasa?

@selphe Did u ever get resolution to this?

I’ve used workaround by mimic user ID as I’ve described above.

In domain.yml add intent and mapped action (it is not neccessary to add NLU data, if your user will not initiate notification by self)

Example
intents:
  - notify:
    triggers: action_notify

actions:
 - action_notify

In actions.py add test action.

Example
class ActionNotify(Action):
    def name(self):
        return 'action_notify'

    def run(self, dispatcher, tracker, domain):
        dispatcher.utter_message('test message')

        return [UserUtteranceReverted()] ##  In my case, i doesn't want to keep notify in tracker_store

Then send request to messenger webhook endpoint, e.g, for Telegram. http://localhost:5005/webhooks/telegram/webhook

Example
{
    "update_id": 1,
    "message": {
        "message_id": 1,
        "from": {
            "id": PUT_HERE_TG_USER_ID,
            "is_bot": false,
            "first_name": "",
            "username": "",
            "language_code": "ru"
        },
        "chat": {
            "id": PUT_HERE_TG_USER_ID,
            "first_name": "",
            "username": "",
            "type": "private"
        },
        "date": 1234,
        "text": "/notify"
    }
}

If there are exists a better way, please guide me…

1 Like

That’s not such a bad solution, although it would much nicer if notifications were supported properly.

I have no idea how I would do it with websockets connection though.

1 Like