risa.context¶
The contexts handlers and hooks answer interactions through.
ErrorHandler
¶
ErrorHandler = Callable[Concatenate[ClickFailure, ...], Awaitable[bool]]
A function Client.error_handler registers: it takes a ClickFailure, then anything to inject.
ClickFailure
¶
ClickFailure(ctx: ComponentContext, error: Exception, stage: FailureStage)
Bases: Struct
A click that failed, as the functions Client.error_handler registers receive it.
Attributes:
-
ctx(ComponentContext) –The context of the click. It has no view state, as in
View.on_outdated: answer withrespond,editwithout interactive components orreplace, and on a view with durable fieldsrerender()raisesNoViewError.respondcontinues what was sent before the failure, as it would in the handler. -
error(Exception) –The exception.
-
stage(FailureStage) –Where it was raised.
ComponentContext
¶
ComponentContext(
interaction: ComponentInteraction,
*,
rest: RESTClient,
meta: ViewMeta,
build: Callable[[View, Snowflake], Awaitable[Rendered]],
gate: ResponseGate | None = None,
slot: ViewSlot | None = None,
)
Bases: Context[ComponentInteraction]
The context of a click on one of a view's components.
A handler answers through it: rerender() redraws the message from the view's
state, edit(...) replaces it with another layout, and respond(...) sends a new
message. risa makes one per click.
resolved
property
¶
resolved: ResolvedOptionData | None
The users, members, roles and channels picked in an entity select menu, or None.
edit
async
¶
edit(layout: Layout) -> None
Replace the message with layout, keeping the view's state on it.
For a screen the view's render does not draw, such as a confirmation or a closing
message. A layout without interactive components ends the view, since nothing on it
can be clicked any more. Like rerender(), it saves the view's state.
Parameters:
-
layout(Layout) –The new layout: one top-level component, or several in order.
Raises:
-
NoViewError–If the layout has interactive components and the view has durable fields, but this context has no view state, as in
on_outdatedandon_state_missing, or ifreplace()gave the message to another view. -
EphemeralOriginError–If the message is ephemeral and the interaction was answered with a new message.
-
StateOverflowError–If an
InMessageview's state does not fit the layout's components. -
StateConflictError–If another process saved the view's state first. The view then holds that state.
-
StateUnreadableError–If another process saved the view's state first, in a form this code cannot read.
replace
async
¶
replace(view: View) -> None
Turn the message into another view, which answers its clicks from here on.
It builds view as Client.build does, so a view in a store gets a record of its own.
This view's state is not saved, also not when the handler returns, and its record stays
until its ttl runs out. If the message cannot be edited, the new view's record stays
the same way and this view keeps the message. Afterwards rerender() and edit() of
this context raise NoViewError, since the message is no longer this view's; edit
only ever shows this view's own components.
Parameters:
-
view(View) –The view to show, an instance of a registered class.
Raises:
-
EphemeralOriginError–If the message is ephemeral and the interaction was answered with a new message.
-
NotAViewError–If the view's class was never registered.
-
StateOverflowError–If an
InMessageview's state does not fit its components. -
ViewDeclarationError–If the view keeps its state in a store this client does not have.
rerender
async
¶
rerender() -> None
Redraw the message from the view's current state, and save that state.
Every rerender is a commit. InMessage state is written into the message itself;
InStore state goes to the store first, then the message is edited. A change made
without calling it is saved when the handler returns, but that save can only log a
failure; call it yourself, before any respond(), where a failure must be handled.
Raises:
-
NoViewError–If the view has durable fields but this context has no view state, as in
on_outdatedandon_state_missing, or ifreplace()gave the message to another view. -
EphemeralOriginError–If the message is ephemeral and the interaction was answered with a new message.
-
StateOverflowError–If an
InMessageview's state no longer fits its components. -
StateConflictError–If another process saved the view's state first. The view then holds that state, so the handler can apply its change again and rerender.
-
StateUnreadableError–If another process saved the view's state first, in a form this code cannot read.
-
StateNotFoundError–If an
InStoreview's record disappeared while the handler ran.
Context
¶
Context(
interaction: T, *, rest: RESTClient, gate: ResponseGate | None = None
)
What a handler or hook gets for the interaction it answers.
guild_id
property
¶
guild_id: Snowflake | None
The id of the guild the interaction happened in, or None outside a guild.
member
property
¶
member: InteractionMember | None
The member who used the component, or None outside a guild.
acknowledge
async
¶
Acknowledge the interaction like defer, unless it already has its initial response.
Where defer raises, this does nothing, so it is safe to call whatever happened
before.
Parameters:
defer
async
¶
Acknowledge the interaction now and answer it later.
By default the acknowledgement is silent, and the answer is a rerender() or an
edit() of the message. With thinking=True, Discord shows a "thinking..." message
that the next respond() takes the place of.
Parameters:
-
thinking(bool, default:False) –Show a "thinking..." message.
-
ephemeral(bool, default:False) –Show that message only to the user who clicked.
Raises:
-
AlreadyRespondedError–If the interaction already has its initial response.
respond
async
¶
respond(
content: UndefinedOr[str] = UNDEFINED,
*,
ephemeral: bool = False,
tts: UndefinedOr[bool] = UNDEFINED,
attachment: UndefinedOr[Resourceish] = UNDEFINED,
attachments: UndefinedOr[Sequence[Resourceish]] = UNDEFINED,
component: UndefinedOr[ComponentBuilder] = UNDEFINED,
components: UndefinedOr[Sequence[ComponentBuilder]] = UNDEFINED,
embed: UndefinedOr[Embed] = UNDEFINED,
embeds: UndefinedOr[Sequence[Embed]] = UNDEFINED,
mentions_everyone: UndefinedOr[bool] = UNDEFINED,
user_mentions: UndefinedOr[
SnowflakeishSequence[PartialUser] | bool
] = UNDEFINED,
role_mentions: UndefinedOr[
SnowflakeishSequence[PartialRole] | bool
] = UNDEFINED,
) -> Response
Send a message in answer to the interaction.
The first response answers the interaction itself; every later one is a follow-up
message. After a thinking message, the first one replaces it, and keeps its visibility
whatever ephemeral and tts say. Apart from ephemeral, the parameters are those of hikari's
create_interaction_response
and execute_webhook, which describe them
in full.
Parameters:
-
content(UndefinedOr[str], default:UNDEFINED) –The message text.
-
ephemeral(bool, default:False) –Show the message only to the user who clicked.
-
tts(UndefinedOr[bool], default:UNDEFINED) –Have Discord read the message aloud.
-
attachment(UndefinedOr[Resourceish], default:UNDEFINED) –One file. Not together with
attachments. -
attachments(UndefinedOr[Sequence[Resourceish]], default:UNDEFINED) –The files to attach.
-
component(UndefinedOr[ComponentBuilder], default:UNDEFINED) –One builder, sent as it is: risa adds no routing or state. To send a view, spread
await client.build(view). Not together withcomponents. -
components(UndefinedOr[Sequence[ComponentBuilder]], default:UNDEFINED) –The builders, sent as they are.
-
embed(UndefinedOr[Embed], default:UNDEFINED) –One embed. Not together with
embeds. -
embeds(UndefinedOr[Sequence[Embed]], default:UNDEFINED) –The embeds.
-
mentions_everyone(UndefinedOr[bool], default:UNDEFINED) –Whether
@everyoneand@hereare parsed. -
user_mentions(UndefinedOr[SnowflakeishSequence[PartialUser] | bool], default:UNDEFINED) –Truefor every user, or the users to parse. -
role_mentions(UndefinedOr[SnowflakeishSequence[PartialRole] | bool], default:UNDEFINED) –Truefor every role, or the roles to parse.
Returns:
-
Response–The message, to fetch, edit or delete later.
FailureStage
¶
Bases: StrEnum
Where a click failed, as ClickFailure.stage names it.
Attributes:
-
HANDLER–The handler raised.
-
LOAD–The view's
loadraised, so the handler never ran. -
ON_OUTDATED–View.on_outdatedraised. -
ON_STATE_MISSING–View.on_state_missingraised. -
STATE–The view's state could not be reached before any of the bot's code ran: the store failed or is missing, its lock timed out, or the codec's extra is not installed.
Response
¶
Response(
rest: RESTClient,
interaction: ComponentInteraction | ModalInteraction,
message: Message | None,
)
A message sent with respond(), to fetch, edit or delete later.
edit
async
¶
edit(
content: UndefinedNoneOr[str] = UNDEFINED,
*,
attachment: UndefinedNoneOr[Resourceish | Attachment] = UNDEFINED,
attachments: UndefinedNoneOr[
Sequence[Resourceish | Attachment]
] = UNDEFINED,
component: UndefinedNoneOr[ComponentBuilder] = UNDEFINED,
components: UndefinedNoneOr[Sequence[ComponentBuilder]] = UNDEFINED,
embed: UndefinedNoneOr[Embed] = UNDEFINED,
embeds: UndefinedNoneOr[Sequence[Embed]] = UNDEFINED,
mentions_everyone: UndefinedOr[bool] = UNDEFINED,
user_mentions: UndefinedOr[
SnowflakeishSequence[PartialUser] | bool
] = UNDEFINED,
role_mentions: UndefinedOr[
SnowflakeishSequence[PartialRole] | bool
] = UNDEFINED,
) -> Message
Edit the message.
The parameters are those of hikari's
edit_interaction_response, which
describes them in full. Every edit sends the mention settings, so one left out switches
that mention parsing off.
Parameters:
-
content(UndefinedNoneOr[str], default:UNDEFINED) –The new text.
Noneremoves it. -
attachment(UndefinedNoneOr[Resourceish | Attachment], default:UNDEFINED) –One file. Not together with
attachments. -
attachments(UndefinedNoneOr[Sequence[Resourceish | Attachment]], default:UNDEFINED) –The files to keep or add.
Noneremoves them all. -
component(UndefinedNoneOr[ComponentBuilder], default:UNDEFINED) –One builder, sent as it is: risa adds no routing or state. Not together with
components. -
components(UndefinedNoneOr[Sequence[ComponentBuilder]], default:UNDEFINED) –The builders, sent as they are.
Noneor an empty sequence removes them. -
embed(UndefinedNoneOr[Embed], default:UNDEFINED) –One embed. Not together with
embeds. -
embeds(UndefinedNoneOr[Sequence[Embed]], default:UNDEFINED) –The embeds.
Noneor an empty sequence removes them. -
mentions_everyone(UndefinedOr[bool], default:UNDEFINED) –Whether
@everyoneand@hereare parsed. -
user_mentions(UndefinedOr[SnowflakeishSequence[PartialUser] | bool], default:UNDEFINED) –Truefor every user, or the users to parse. -
role_mentions(UndefinedOr[SnowflakeishSequence[PartialRole] | bool], default:UNDEFINED) –Truefor every role, or the roles to parse.
Returns:
-
Message–The message as it is now.
ResponseGate
¶
ResponseGate(
lock: Lock = ...,
acknowledged: Event = ...,
response: _InitialResponse = NONE,
adopted: bool = False,
)
Bases: Struct
Whether an interaction has been answered, shared by everything that answers it.
risa makes one per interaction, so a handler and the auto-defer watchdog never both send the initial response.
Attributes:
-
lock(Lock) –Held while the initial response is decided and sent.
-
acknowledged(Event) –Set once nothing more is owed to the REST listener: the initial response went out, or risa has finished with the interaction.
-
response(_InitialResponse) –Which initial response the interaction got.
-
adopted(bool) –Whether the click routed to a view, rather than being left to another listener.