InfiArtt Developer Center · Developer space · InfiTalk bot catalog

InfiTalk bot documentation

Make your own InfiTalk bot: it runs on your computer and reaches every server it was added to through one WebSocket connection. It can write, answer commands, open dialogs that work well with screen readers, and play audio.

Quick start

  1. Make a bot on Developer space and copy its token (it starts with itw_). The token is shown once. Never share it or put it in a public repository.
  2. Add the bot to a server you manage with "Add to a server" on the same page. Your own bots need no review.
  3. Download an example and run it with your token:
INFITALK_TOKEN=itw_... node echo-bot.js

# PowerShell
$env:INFITALK_TOKEN="itw_..."; node echo-bot.js

Python SDK

For bigger bots, use the official InfiArtt SDK infitalk (Python 3.10+, MIT license). It takes care of the connection, resume, the 3-second rule, dialogs, buttons and audio, and has a local tester that needs no server.

pip install git+https://github.com/InfiArtt/infitalk-python

from infitalk import Bot

bot = Bot()  # INFITALK_TOKEN

@bot.command("echo", "Repeat what you write")
async def echo(ctx, text: str):
    await ctx.respond(text, public=True)

bot.run()

The example has a menu (Ctrl+Shift+P in InfiTalk) with an echo command, a hello dialog and a quiet one-second tone.

Connecting to the gateway

The address is wss://tt.infiartt.com/bot. Every message is one JSON object in one WebSocket text message.

  1. The gateway says hello:
    {"op":"hello","gateway":1,"heartbeat_interval":30000}
  2. The bot sends its token within 10 seconds:
    {"op":"identify","token":"itw_...","resume":{"12":{"session":"...","seq":340}}}
    "resume" may be empty. It holds the session and the last event number per server from the previous connection.
  3. The gateway answers:
    {"op":"identified","bot":{"id":7,"name":"echo"},
     "servers":[{"server":12,"name":"Kafe Musik","awake":true}],
     "limits":{"messages_per_second":200,"audio_streams_per_server":2,"max_message":1048576}}
  4. Send {"op":"heartbeat"} at least every heartbeat_interval milliseconds. The answer is {"op":"heartbeat_ack"}. The gateway keeps the line to every server alive itself, so no heartbeat per server is needed.

If the connection drops, connect again with "resume". Servers keep the bot for 60 seconds and the last 1000 events (2 minutes), so nothing is lost and people do not see the bot leave and come back.

Servers

One connection serves every server the bot was added to. Every message from and to a server carries "server".

  • ready: the server is awake and the bot is in. It has the bot's user id, the channels it may see, its permissions, the session and "resumed".
  • server_sleeping: the server went to sleep because nobody is on it. The gateway connects again by itself when it wakes, then a new "ready" comes. Bots do not keep a server awake.
  • server_added / server_removed: the bot was added or removed on infiartt.com (within a minute).
{"op":"say","server":12,"channel":5,"content":"Hello!"}

What a bot sends

Every request may carry "ref". The answer is {"op":"result","ref":...,"ok":true|false,"error":...}.

Ops a bot sends
OpUse
joinchannel or path; 0 to leave; "everywhere":true to be in every channel (needs approval)
saya message in a channel: channel, content, reply_to, actions (buttons and a choice)
edit / deletethe bot's own messages (msgid)
pma private message, only to someone who wrote to the bot or named it in the last 10 minutes
commandsthe bot's menu (up to 250 commands) with categories, fields and permission (everyone, moderator, admin)
respondan answer for one person, or for the channel with "public":true
defer"working on it", when an answer takes more than 3 seconds
suggestionssuggestions while someone types in a field with "suggest"
dialog, dialog_update, dialog_closedialogs from JSON (see below)
audio, audio_endaudio (see below)
statusstatus text such as "Playing: ..."; may be per channel
allowedmay this person use that command (for commands typed in the chat)
channel_infowho is in a channel, its name and path
{"op":"commands","server":12,"commands":[
  {"name":"echo","description":"Repeat what you write","category":"Fun",
   "options":[{"name":"text","label":"Text","type":"text","required":true}]},
  {"name":"stop","description":"Stop the music","permission":"moderator"}]}

Events a bot receives

  • command: someone used the menu. It has interaction, command, values, user (with level), channel.
  • action: a button or choice on a bot message was used.
  • form, suggest, dialog_event: a form was filled in, someone is typing in a field, or something happened in a dialog.
  • message: a message that names the bot (mentions), or every message (messages).
  • direct: a private message to the bot.
  • member: someone joined or left a channel (members).

The 3-second rule: every interaction must be answered within 3 seconds with respond, defer, dialog or dialog_update, else the person hears that the bot did not answer. An interaction can be answered for 15 minutes after defer.

Dialogs

Dialogs are made from JSON and shown by the client as real Windows controls, so they work with NVDA and JAWS. Controls: label, text, number, checkbox, radio, select, slider, list, button and group.

  • Every control except label needs a label. The server refuses dialogs without labels.
  • An & in a label gives the Alt letter. If it is missing or taken, the client picks one.
  • At most 100 controls, 200 options per control, 64 KB.
  • dialog_update replaces controls in place without closing the dialog; "announce" is read by the screen reader.
{"op":"dialog","server":12,"interaction":881,"dialog":{"id":"eq","title":"Equalizer","focus":"bass",
 "controls":[
  {"type":"slider","id":"bass","label":"&Bass","min":-12,"max":12,"step":1,"unit":"dB","value":0,"notify":true},
  {"type":"select","id":"preset","label":"&Preset","options":[{"value":"flat","label":"Flat"},{"value":"pop","label":"Pop"}]},
  {"type":"button","id":"save","label":"&Save","default":true},
  {"type":"button","id":"close","label":"Close","close":true}]}}

Audio

  • Format: PCM 48 kHz, stereo, 16-bit signed little-endian, base64 encoded. The server turns it into the channel's Opus.
  • Send in real time, for example 20 ms pieces (3840 bytes) every 20 ms. The server keeps up to 3 seconds.
  • The bot must be in that channel (join) and allowed to speak there.
  • At most 2 audio streams at once per bot per server. Member servers play in at most 7 channels at once.
  • audio_end plays out what is buffered and stops; "drop":true stops at once (stop, skip).
  • Keep the volume reasonable. Listeners have their own volume for bots, but loud audio still hurts.
{"op":"join","server":12,"channel":5}
{"op":"audio","server":12,"channel":5,"pcm":"AAAAAP7/..."}
{"op":"audio_end","server":12,"channel":5}

Permissions

A bot asks for permissions when it is made. Server owners see them on the consent screen and may give fewer. Without the needed one, a request gets missing_permission.

  • mentions: messages that name the bot or answer a message of the bot.
  • direct: private messages sent to the bot.
  • send: write messages in channels and answer for the whole channel.
  • manage_own: change and delete the messages the bot wrote itself.
  • speak: send audio to channels, for example music.
  • dialogs: open windows with buttons, lists and sliders for the person who uses it.
  • commands: have a command menu (Ctrl+Shift+P) people can use.
  • everywhere: the bot shows in everyone's channel without join or leave sounds, and can play audio in several channels at once (a music bot, for example). Never in private channels.
  • messages: every message in channels the bot may read, never from private channels. Needs a clear reason. (privileged permission)
  • members: who joins the channels the bot may see. (privileged permission)
  • presence: see who is online on the server. Not used yet. (privileged permission)

A bot never gets private messages between two people, private channels that do not allow it, passwords, IP addresses or device ids.

Limits and error codes

  • Messages up to 1 MiB. At most 200 messages a second per bot (bursts up to 400).
  • Channel messages: 5 per 5 seconds per channel and 50 a minute.
  • At most 20 connections from one address, and 30 identify attempts a minute.
Close codes
CodeMeaning
1001the gateway restarts or infiartt.com cannot be reached; connect again
1009message too big
4001no identify within 10 seconds
4002invalid WebSocket frame
4004the token is not valid, was changed, or the bot was turned off; do not connect again with it
4005the same bot connected somewhere else
4008too many messages
4009no heartbeat

Errors in "result": identify_first, unknown_server, server_asleep, rate_limited (with retry_after), too_many_streams, missing_permission (with permission), not_in_channel, not_allowed, invalid_token, bad_json.

The last error and the last connection time of a bot are shown on Developer space.

Catalog and rules

Bots sent to the catalog are reviewed by the InfiArtt team before every server owner can add them. Before sending: a description in Indonesian and English, a help page, a privacy policy, and the bot has connected at least once. The review checks:

  • The bot is on, answers within 3 seconds, and all its commands work
  • Its menu, dialogs and messages were tried with NVDA: every control has a label, Alt letters make sense, texts are not too long to be read
  • The permissions fit what it does, and privileged ones have a reason
  • The help page and privacy policy exist and are clear
  • No spam, harmful content or disturbing audio

A bot that asks for new permissions leaves the catalog until it is reviewed again; servers that added it keep the old permissions. Bots that break the rules (spam, collecting data without consent, disturbing audio) are turned off.