Skip to content

Events & scheduling

Events are named signals that can be sent and received by the bot's conversations.

Events can come from various sources: from an external script or the REST API; from another conversation, or from a user interface templates like the buttons template.

Receiving events

As events are usually sent at any time to the bot, they can be caught by using an event trigger, either on a dialog, or on a task:

dialog event: "status_update" do
  say "A status update came in: #{event.payload.text}"
end
task event: "status_update" do
  log "status update: " + event.payload.text
end

Alternatively, if we want the current script to block until an event has come in, we can use await to pause the script until the event is fired:

dialog main do
  say "We are waiting on a click"
  await event("click")
  say "A click was received"
end

Sending events from Bubblescript

Sending events from Bubblescript is done using emit:

emit "status_update", text: "#{user.first_name} started using the bot"

By default, emit sends it event to the client, where it can be picked up by for instance the Javascript SDK (Botsqd.onEmit("event", ....)), but it can also send events to other processes, for instance the master process or a local group.

emit "status_update", [], to: "master"

Sends a message to the bot's master process. In that process it will be handled using the dialog event: "..." trigger.

to:

These are the emit to: targets:

  • :client -- Sends the event to the code that is hosting the chat, e.g., the Javascript SDK. In the SDK, it can be caught using the onEmit() function. (this is the default value)
  • :chat_bubble -- Sends the event to the chat bubble that hosts the conversation. This is only possible when the "web widget" connection is configured in the bot and the live visitors setting of the web widget is enabled. This can be used to send an event to the instance of the ChatBubble class of the ChatBubble JS SDK.
  • :master -- Sends the event to the bot'smaster process, if a master script was defined. See multiple processes.
  • "string" -- When the recipient is a string, it is considered a user ID, and sends the event there.

emit is "fire and forget" -- No warnings / errors are generated when sending of the message fails. If you need to check whether the message was arrived, use query.

Scheduling events

The platform contains a scheduling system, so that events can be scheduled to be sent in the future. Use either in: or at: as arguments to emit to schedule events in the future.

The following send a "status_update" event to the client, in 10 seconds from now:

emit "status_update", [], in: 10

The following send a "wakeup" event to the client, in one year:

emit "wakeup", [], in: "1y", to: :self

Specifying an absolute point in time is also possible:

emit "status_update", [], at: "tomorrow at 10:00"

When using at:, the Duckling date parser is used to parse the given date string. If the parsing fails, a runtime error is thrown.

Note: It is not possible to schedule events in the past.

Scheduled events with a name

While scheduling, you can give the event a name that you can use to cancel it again. You can also use it to reschedule the event, because the name is unique; scheduling a second emit with the same name will cancel out the first (if it was not yet fired).

emit "status_update", [], in: 10, name: "update"
emit "status_update", [], in: 20, name: "update"

This will only send out one emit, in 20 seconds.

Cancelling named events

When a scheduled emit has a name, it is possible to cancel it by calling cancel_emit():

emit "status_update", [], in: 10, name: "update"
result = cancel_emit "update"

Request / response

Using the query function, you can send an event and wait for a reply.

reply = query :master, "ping"
say reply

In the other script, define a task or dialog that catches the ping event, and use the reply construct to send a payload back:

task event: "ping" do
  reply "pong"
end

Make sure that the handling task / dialog in the other process finishes quickly. If there is no reply received within 1 second, the value :timeout is returned in the calling process.