Background coordinator processes
The DSL provides a few constructions to allow the users of a bot to do things together.
Sending internal messages
to: syntax, you can send an event (with optional
payload) to another user. This way, you can create a chatbot which
relays messages between two users.
However, in order to do this, you need to know the other user’s
user_id, which is not exposed in every chat session.
There are two types of scripts which are special and run as separate
“threads” in the bot runtime. These are called
group. These background processes can be used to relay information
between different users, perform tasks in the background, and do
several other things.
master script is a special process which runs as a separate
process. There is at most one master process per bot:
From a user script, you can
emit something to
:master. It receives
the event and can then relay the information to another user, or send
(emit) something back to the sender.
emit "hello", to: :master
The master process can catch this
"hello" event and then perform
something, update some administration or
emit something back:
task event: "hello" do users = users + [event.sender] # let the user know we have registered it emit "ok", to: event.sender end
Sends an event to the given user, and waits for the 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.
The ChatterBot in the botsquad examples is a good example of how a
master script is used to create a group chat in which all chat
members relay all text messages and images they send to each other.
group script is also a background process which can be used to
group several members of a chat together.
Group coordinators work similarly to the master process, but there can be multiple groups active at the same time:
By default, a chat session is not part of any group. A new group
process can be started by using the
group = spawn_group()
group variable now contains the identifier of the newly created
group. To have other people join this group, you need to share the
link to the group chat. This can be done with the
say "Group created! Have people join using the following link:" say chat_link("web", g: group)
When someone clicks that link, he will be joined in the group. When a
chat is part of a group, it will have a
group variable automatically
filled in the DSL context. This
group variable can be used to
messages to the group coordinator:
emit "hello", to: group
group = spawn_group("~mygroup")
Group names always start with a
passing initial variables to group
group = spawn_group("~mygroup", [foo: "bar"])
foo is now available in the group process.
You can also spawn a new group with a randomized name and predefined
variables, by giving
nil as the group name:
group = spawn_group(nil, [foo: "bar"])
group names based on user ids
Sometimes you want to give the group a deterministic identifier, based
on the identifiers of the participants, for instance when creating a
one-on-one chat. The
group_name() function providers exactly
that. Given the input identifiers, it returns a unique identifier that
is usable as group name. The identifier is based on the given
identifiers, but they are sorted and hashed together into a short new