BlockAction optimisation

This commit is contained in:
Deon George 2022-08-23 21:28:14 +10:00
parent 4691a3f775
commit 612798e67f
5 changed files with 61 additions and 54 deletions

View File

@ -9,7 +9,7 @@ use Slack\Blockkit\Element;
final class Button extends Element final class Button extends Element
{ {
protected const LIMITS = [ protected const LIMITS = [
'action_id' => 255, 'action_id' => 255, // @todo Should be unique for each message
'callback_id' => 255, 'callback_id' => 255,
'text' => 75, 'text' => 75,
'url' => 3000, 'url' => 3000,

View File

@ -4,6 +4,7 @@ namespace Slack\Blockkit\Blocks\Elements;
use \Exception; use \Exception;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Slack\Blockkit\Element; use Slack\Blockkit\Element;
final class MultiStaticSelect extends Element final class MultiStaticSelect extends Element
@ -41,7 +42,10 @@ final class MultiStaticSelect extends Element
$this->action_id = $this->validate('action_id',$action_id); $this->action_id = $this->validate('action_id',$action_id);
if (count($options) > self::MAX_OPTIONS) if (! $options->count())
throw new Exception('There are no options?');
if ($options->count() > self::MAX_OPTIONS)
throw new Exception(sprintf('Can only have maximum %d options',self::MAX_OPTIONS)); throw new Exception(sprintf('Can only have maximum %d options',self::MAX_OPTIONS));
$this->options = $options->transform(function($item) { $this->options = $options->transform(function($item) {

View File

@ -4,6 +4,7 @@ namespace Slack\Blockkit\Blocks\Elements;
use \Exception; use \Exception;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Slack\Blockkit\Element; use Slack\Blockkit\Element;
final class StaticSelect extends Element final class StaticSelect extends Element
@ -41,7 +42,10 @@ final class StaticSelect extends Element
$this->action_id = $this->validate('action_id',$action_id); $this->action_id = $this->validate('action_id',$action_id);
if (count($options) > self::MAX_OPTIONS) if (! $options->count())
throw new Exception('There are no options?');
if ($options->count() > self::MAX_OPTIONS)
throw new Exception(sprintf('Can only have maximum %d options',self::MAX_OPTIONS)); throw new Exception(sprintf('Can only have maximum %d options',self::MAX_OPTIONS));
$this->options = $options->transform(function($item) { $this->options = $options->transform(function($item) {

View File

@ -5,6 +5,7 @@ namespace Slack\Interactive;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Slack\Exceptions\SlackException;
use Slack\Models\Channel; use Slack\Models\Channel;
/** /**
@ -61,8 +62,11 @@ class BlockActions extends Base
public function __get($key) public function __get($key)
{ {
switch ($key) { switch ($key) {
case 'action':
return Arr::get(object_get($this->_data,'actions'),$this->index);
case 'action_id': case 'action_id':
return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),$key); return object_get(Arr::get($this->actions,$this->index),$key);
// An event can have more than 1 action, each action can have 1 value. // An event can have more than 1 action, each action can have 1 value.
case 'action_key': case 'action_key':
@ -74,15 +78,23 @@ class BlockActions extends Base
case 'actions': case 'actions':
return object_get($this->_data,$key); return object_get($this->_data,$key);
case 'block_id':
return object_get($this->action,$key);
case 'callback_id': case 'callback_id':
switch (object_get($this->_data,'type')) { switch ($this->container_type) {
case 'block_actions': case 'view':
return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),$key); // For app hometab, the callback is in the view->callback_id array.
// @todo Dont assume this is a view return object_get($this->_data,sprintf('%s.%s',$this->container_type,$key));
default: default:
return object_get($this->_data,'view.callback_id'); throw new SlackException('Unknown container type: '.$this->container_type);
} }
// @todo See if all responses have a container.type, and if so, put this in base.
case 'container_type':
return object_get($this->_data,'container.type');
case 'channel_id': case 'channel_id':
return object_get($this->_data,'channel.id') ?: Channel::findOrFail($this->action('value'))->channel_id; return object_get($this->_data,'channel.id') ?: Channel::findOrFail($this->action('value'))->channel_id;
@ -100,34 +112,32 @@ class BlockActions extends Base
return object_get($this->_data,'view.id'); return object_get($this->_data,'view.id');
case 'value': case 'value':
switch (Arr::get(object_get($this->_data,'actions'),$this->index)->type) { switch (object_get($this->action,'type')) {
case 'external_select': case 'external_select':
case 'overflow': case 'overflow':
case 'static_select': case 'static_select':
return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'selected_option.value'); return object_get($this->action,'selected_option.value');
case 'multi_static_select': case 'multi_static_select':
return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'selected_options.value'); return object_get($this->action,'selected_options.value');
default: default:
return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),$key); return object_get($this->action,$key);
}
case 'values':
switch (Arr::get(object_get($this->_data,'actions'),$this->index)->type) {
// @todo To Check
case 'external_select':
// @todo To Check
case 'overflow':
// @todo To Check
case 'static_select':
return count(object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'selected_option'));
case 'multi_static_select':
return collect(object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'selected_options'))->pluck('value');
default:
return count(object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'value'));
} }
case 'value_count': case 'value_count':
return count($this->values); switch ($x=object_get($this->action,'type')) {
// @todo To Check
case 'external_select':
// @todo To Check
case 'overflow':
// @todo To Check
throw new SlackException('To be implemented: ',$x);
case 'static_select':
return count(object_get($this->action,'selected_option'));
case 'multi_static_select':
return collect(object_get($this->action,'selected_options'))->pluck('value');
default:
return count(object_get($this->action,'value'));
}
default: default:
return parent::__get($key); return parent::__get($key);
@ -138,7 +148,8 @@ class BlockActions extends Base
* Separate out an action command to the id that the command relates to * Separate out an action command to the id that the command relates to
* *
* @param string $key * @param string $key
* @return string|null * @return string
* @throws SlackException
*/ */
private function action(string $key): ?string private function action(string $key): ?string
{ {
@ -147,7 +158,7 @@ class BlockActions extends Base
$value = NULL; $value = NULL;
// We only take the action up to the pipe symbol // We only take the action up to the pipe symbol
$action_key = object_get(Arr::get(object_get($this->_data,'actions'),$this->index),'action_id'); $action_key = object_get($this->action,'action_id');
if (preg_match($regex,$action_key)) { if (preg_match($regex,$action_key)) {
$action = preg_replace($regex,'$1',$action_key); $action = preg_replace($regex,'$1',$action_key);
@ -159,9 +170,10 @@ class BlockActions extends Base
return $action ?: $action_key; return $action ?: $action_key;
case 'value': case 'value':
return $value; return $value;
}
return NULL; default:
throw new SlackException('Unknown key: '.$key);
}
} }
/** /**
@ -171,7 +183,7 @@ class BlockActions extends Base
*/ */
public function isMessage(): bool public function isMessage(): bool
{ {
return object_get($this->_data,'message') ? TRUE : FALSE; return (bool)object_get($this->_data,'message');
} }
/** /**

View File

@ -7,12 +7,16 @@ use Illuminate\Support\Facades\Log;
use Slack\Jobs\DeleteChat; use Slack\Jobs\DeleteChat;
use Slack\Interactive\BlockActions; use Slack\Interactive\BlockActions;
class BlockActionListener /**
* This class handles BlockActions events.
* It's expected that the local application would implement this class completely, rather than using this
* modules implementation.
*/
abstract class BlockActionListener
{ {
protected const LOGKEY = 'LBA'; protected const LOGKEY = 'LBA';
// Block actions arent queued, since slack expects a response to the request public $queue = 'slack';
//public $queue = 'high';
/** /**
* Handle the event. * Handle the event.
@ -66,21 +70,4 @@ class BlockActionListener
} }
} }
} }
/**
* Store data coming in from a block action dialog
*
* @param BlockActions $event
*/
protected function store(BlockActions $event): void
{
foreach ($event->actions as $id => $action) {
$event->index = $id;
switch ($event->action_id) {
default:
Log::notice(sprintf('%s:Unhandled ACTION [%s]',static::LOGKEY,$event->action_id),['m'=>__METHOD__]);
}
}
}
} }