Discord-Client
view release on metacpan or search on metacpan
lib/Discord/Client/Interaction.pm view on Meta::CPAN
if ( my $initial = $self->{initial_operation} ) {
$initial->fail( $failed->failure ) unless $initial->is_ready;
}
# Cancel outstanding delivery after publishing the deadline failure.
if ( my $source = delete $self->{initial_source} ) {
$source->cancel unless $source->is_ready;
}
}
sub _message {
my ( $self, $message, %options ) = @_;
# Copy caller data before adding SDK-controlled visibility flags.
croak 'Message must be a string or hash reference'
unless defined($message)
&& ( !ref($message) || ref($message) eq 'HASH' );
my $data = ref($message) ? {%$message} : { content => "$message" };
if ( $options{ephemeral} ) {
croak 'Invalid message flags'
if defined( $data->{flags} )
&& ( ref( $data->{flags} ) || $data->{flags} !~ /\A\d+\z/ );
$data->{flags} = ( $data->{flags} // 0 ) | 64;
}
return $data;
}
sub reply {
my ( $self, $message, %options ) = @_;
return $self->_failed( 'Autocomplete interactions require choices', 'state' ) if $self->{type} == 4;
my $data = eval { $self->_message( $message, %options ) };
return $self->_failed( 'Invalid interaction message', 'request' ) if $@;
# Complete a confirmed deferral by editing its original message exactly once.
if ( $self->{state} eq 'deferred' || $self->{state} eq 'deferred_update' ) {
return $self->_failed( 'Deferred response visibility is already fixed', 'request' )
if exists $options{ephemeral};
$self->{state} = 'completing';
my $future = $self->_webhook( 'PATCH', '/messages/@original', json => $data );
$future->on_ready( sub { $self->{state} = $future->is_done ? 'replied' : 'failed' } );
return $future;
}
return $self->_initial( 4, $data, 'replied' );
}
sub defer {
my ( $self, %options ) = @_;
return $self->_failed( 'Autocomplete cannot be deferred', 'state' ) if $self->{type} == 4;
# Message updates and new deferred replies have different visibility rules.
if ( $options{update} ) {
return $self->_failed( 'Update deferral requires a message component', 'state' ) unless $self->_can_update;
return $self->_failed( 'Update deferral cannot set ephemeral visibility', 'request' ) if $options{ephemeral};
return $self->_initial( 6, undef, 'deferred_update' );
}
return $self->_initial( 5, $options{ephemeral} ? { flags => 64 } : undef, 'deferred' );
}
sub _can_update { $_[0]->{type} == 3 || ( $_[0]->{type} == 5 && ref( $_[0]->{raw}{message} ) eq 'HASH' ) }
sub update {
my ( $self, $message ) = @_;
return $self->_failed( 'Update requires a message component', 'state' ) unless $self->_can_update;
my $data = eval { $self->_message($message) };
return $self->_failed( 'Invalid interaction message', 'request' ) if $@;
return $self->_initial( 7, $data, 'replied' );
}
sub autocomplete {
my ( $self, $choices ) = @_;
return $self->_failed( 'Choices require an autocomplete interaction', 'state' ) unless $self->{type} == 4;
return $self->_failed( 'Invalid autocomplete choices', 'request' )
unless ref($choices) eq 'ARRAY' && @$choices <= 25;
# Validate each suggestion against the focused option and normalize JSON value types.
my @wire;
for my $choice (@$choices) {
return $self->_failed( 'Invalid autocomplete choice', 'request' )
unless ref($choice) eq 'HASH'
&& defined( $choice->{name} )
&& !ref( $choice->{name} )
&& length( $choice->{name} ) >= 1
&& length( $choice->{name} ) <= 100
&& defined( $choice->{value} )
&& !ref( $choice->{value} );
my $type = $self->{focused}{type};
if ( $type == 3 ) {
return $self->_failed( 'Invalid autocomplete choice value', 'request' )
if length( $choice->{value} ) > 100;
}
else {
return $self->_failed( 'Invalid autocomplete choice value', 'request' )
if !looks_like_number( $choice->{value} )
|| abs( $choice->{value} ) > 9007199254740992
|| ( $type == 4
&& ( $choice->{value} != int( $choice->{value} ) || abs( $choice->{value} ) >= 9007199254740992 ) );
}
push @wire, { %$choice, value => $type == 3 ? "$choice->{value}" : 0 + $choice->{value} };
}
return $self->_initial( 8, { choices => \@wire }, 'replied' );
}
sub modal {
my ( $self, $data ) = @_;
# A modal opens only from a command or message component, never a modal submission.
return $self->_failed( 'Modal response is invalid for this interaction', 'state' )
unless $self->{type} == 2 || $self->{type} == 3;
return $self->_failed( 'Invalid modal response', 'request' )
unless ref($data) eq 'HASH'
&& defined( $data->{custom_id} )
&& !ref( $data->{custom_id} )
&& length( $data->{custom_id} ) <= 100
&& length( $data->{custom_id} ) > 0
&& defined( $data->{title} )
&& !ref( $data->{title} )
&& length( $data->{title} ) > 0
&& length( $data->{title} ) <= 45
&& ref( $data->{components} ) eq 'ARRAY';
return $self->_initial( 9, $data, 'replied' );
}
( run in 0.712 second using v1.01-cache-2.11-cpan-1236ad508bc )