~williewillus/r16

a2042139b6fe958b7490ed963d4a10cba4fc3cc6 — Vincent Lee 3 months ago 4aac4da
Overhaul documentation
1 files changed, 92 insertions(+), 30 deletions(-)

M scribblings/r16.scrbl
M scribblings/r16.scrbl => scribblings/r16.scrbl +92 -30
@@ 2,25 2,53 @@

@(require (for-label racket/base))

@title{R16 - A Discord Trick Bot}

R16 is a "trick bot" for Discord. It saves snippets of code, which can then be recalled and executed on user-provided input.
@title{R16 -- Community-Driven Interactive Code Evaluation}

R16 is a "trick bot". It saves snippets of code, which can then be recalled and executed on user-provided input.

As of the time of writing, there exists one frontend, for Discord. More are planned, so
this manual is structured by frontend.

@section{Configuration}

The bot is run by invoking its @tt{main.rkt} file, and stores its configuration in a JSON
file that is read on startup. See the @tt{-h} output for precise details about
command-line flags.

The configuration file must contain a top level object with the following keys and
associated values:

@itemlist[
@item{@tt{storage}: A string defining the folder in which to store the bot's save data.}
@item{@tt{frontend}: A nested object. Within that object, the @tt{module} key must have a
string value that is a module path as in @racket[dynamic-require] which identifies the frontend to run.
Frontends may require more specific configuration within this object, see the documentation
of your chosen frontend for more details.}
]

A working default configuration for the Discord frontend:
@codeblock|{
{
  "storage": "/home/r16bot/r16_save_data",
  "frontend": {
    "module": "r16/frontends/discord",
    "bot_token": "<your bot token here>"
  }
}
}|

@section{The Trick Environment}

Tricks are stored as plain text, and invoked in a sandbox from @racket[racket/sandbox].

The following symbols are available in the trick context:
Tricks are stored as plain text, and invoked in a sandbox using @racketmodname[racket/sandbox].

All symbols from the @racket[threading-lib] package are available for convenience.
The following values are available in the sandbox's namespace:

@defproc[(make-attachment [payload bytes?]
                          [name (or/c string? bytes?)]
                          [mime (or/c symbol? string? bytes?)]) any/c]{
Creates an attachment with payload @racket[payload], filename @racket[name], and MIME-type @racket[mime].
This opaque object must be returned from the trick to be sent to Discord.
If more than one attachment is returned, an unspecified one is sent.
}
@itemlist[
@item{All symbols exported by @racketmodname[threading], for convenience.}
@item{All items listed below.}
@item{Any items made available by the specific frontend, see the documentation of your chosen
frontend for details.}
]

@defproc[(call-trick [name (or/c symbol? string?)]
                     [argument any/c]) any/c]{


@@ 28,10 56,6 @@ Invokes another trick named by @racket[name] and return its result.
If @racket[argument] is @racket[#f], then an empty string is passed to the subtrick. Otherwise, @racket[(~a argument)] is passed.
}

@defthing[message-contents string?]{
Full text of the message that invoked this trick.
}

@defthing[string-args string?]{
Text of the message after the bot command, as a string.
}


@@ 40,6 64,40 @@ Text of the message after the bot command, as a string.
Function that returns @racket[string-args], but as a list of datums read by @racket[read]. If there is a read failure, @racket[#f] is returned.
}

@defthing[parent-context (or/c (hash/c symbol? any/c) #f)]{
If the currently executing trick is a top-level trick invocation, @racket[#f]. Otherwise,
a mapping of all the provided symbols (such as @racket[string-args], etc.) in the context
of the parent that executed @racket[call-trick].
}

@section{Discord Frontend}
This frontend provides integration with the Discord chat service.

Commands to the bot are issued by prefixing Discord messages with a configurable prefix
value. The rest of the message is then treated as a command. For more details, send the
message @tt{<bot_prefix> help} in your Discord server.

The frontend also has a configurable trick shorthand prefix. Messages of the form
@tt{<trick_prefix>foo bar ...} are equivalent to @tt{<bot_prefix> call foo bar ...}.

@subsection{Discord Configuration}
The @tt{frontend} object in the configuration file can have the following keys and values:
@itemlist[
@item{@tt{module} must be the string @code{"r16/frontends/discord"}.}
@item{@tt{bot_token} must be a string containing your Discord bot token.}
@item{@tt{bot_prefix} is a string specifying the bot's trigger prefix. If not present, defaults to @code{"!rkt "}.}
@item{@tt{trick_prefix} is a string specifying the bot's shorthand prefix. If not present, defaults to @code{"!!"}.}
]

@subsection{Trick Environment Extensions}
In additional to the bindings described above, the following items are available in the
trick environment.


@defproc[(delete-caller) void?]{
Thunk that deletes the message that invoked this sandbox.
}

@defproc[(emote-lookup [name string?]) (or/c string? #f)]{
Function that returns the ID for emote with name @racket[name], or @racket[#f] if it doesn't exist.
}


@@ 48,8 106,20 @@ Function that returns the ID for emote with name @racket[name], or @racket[#f] i
Function that returns the PNG data of the emote with ID @racket[id], or @racket[#f] if it doesn't exist.
}

@defproc[(make-attachment [payload bytes?]
                          [name (or/c string? bytes?)]
                          [mime (or/c symbol? string? bytes?)]) any/c]{
Creates an attachment with payload @racket[payload], filename @racket[name], and MIME-type @racket[mime].
This opaque object must be returned from the trick to be sent to Discord.
If more than one attachment is returned, an unspecified one is sent.
}

@defthing[message-contents string?]{
Full text of the message that invoked this trick.
}

@defproc[(read-storage [type (or/c 'guild 'channel 'user)]) any/c]{
Reads "trick-local storage" @racket[name] and return its result, or @racket[#f] if the result is uninitialized.
Reads "trick-local storage" @racket[type] and return its result, or @racket[#f] if the result is uninitialized.

A trick's "trick-local storage" can be per-guild, per-channel, or per-user.



@@ 63,17 133,9 @@ Writes @racket[data] to the trick's "trick-local storage," overwriting any exist
A trick's "trick-local storage" can be per-guild, per-channel, or per-user; each type of storage has its own limitation on size:
@tabular[#:sep @hspace[1]
  `(,(list @bold{Type} @bold{Size Limit})
          ("guild"     "64kb")
          ("channel"   "8kb")
          ("user"      "2kb"))]
          ("guild"     "64 KiB")
          ("channel"   "8 KiB")
          ("user"      "2 KiB"))]
}

This will always be a no-op when invoked from the eval command.

@defproc[(delete-caller) void?]{
Thunk that deletes the message that invoked this sandbox.
}

@defthing[parent-context (or/c (hash/c symbol? any/c) #f)]{
Mapping of all the above symbols for the trick calling this one, or @racket[#f] if this trick is the top level invocation.
}