diff --git a/src/API.php b/src/API.php index 849c5a9..8f07a23 100644 --- a/src/API.php +++ b/src/API.php @@ -456,6 +456,8 @@ final class API case 'thread_not_found': throw new SlackThreadNotFoundException('Thread Not Found',$request->status()); + case 'account_inactive': + // @todo Mark the token/team as inactive default: Log::error(sprintf('%s:Generic Error',static::LOGKEY),['m'=>__METHOD__,'t'=>$this->_token->team_id,'r'=>$response]); throw new SlackException($response->error,$request->status()); diff --git a/src/Base.php b/src/Base.php index 14cd1b7..567237b 100644 --- a/src/Base.php +++ b/src/Base.php @@ -64,6 +64,36 @@ abstract class Base return $o->exists ? $o : NULL; } + /** + * Separate out an callback command to the id that the command relates to + * + * @param string $key + * @param string $item + * @return string|null + * @throws \Exception + */ + final protected function keyitem(string $key,string $item): ?string + { + $regex = '/^([a-z_]+)\|([0-9]+)$/'; + $id = NULL; + $value = NULL; + + if (preg_match($regex,$item)) { + $id = preg_replace($regex,'$1',$item); + $value = preg_replace($regex,'$2',$item); + } + + switch ($key) { + case 'id': + return $id ?: $item; + case 'value': + return $value; + + default: + throw new \Exception('Unknown key: '.$key); + } + } + /** * Return the Eneterprise object that a Response is related to * diff --git a/src/BlockKit.php b/src/BlockKit.php index 622e1ee..1bb32cc 100644 --- a/src/BlockKit.php +++ b/src/BlockKit.php @@ -10,6 +10,16 @@ use Slack\Exceptions\SlackSyntaxException; /** * Class BlockKit - Slack Blockit Objects * + * @notes + * + callback_id is used to identify the source of any action (modal). (Message blocks do not have a callback_id, accept in attachments). + * eg: hometab, add_product, ask_modal + * + block_id is used to identify the sub action(s) of any action (modal) + * eg: multiple blocks (list of something) + * + action_id is used to identify the action that was initiated + * eg: view, edit, review + * + value is the value of the action_id + * eg: 5 (question #), yes, no, skip, abort + * * @package Slack */ abstract class BlockKit implements \JsonSerializable,\Countable diff --git a/src/Interactive/Base.php b/src/Interactive/Base.php index 201013a..e863026 100644 --- a/src/Interactive/Base.php +++ b/src/Interactive/Base.php @@ -35,6 +35,7 @@ abstract class Base extends SlackBase * + user_id * @param string $key * @return mixed|object + * @throws \Exception */ public function __get(string $key) { @@ -46,6 +47,12 @@ abstract class Base extends SlackBase case 'user_id': return object_get($this->_data,'user.id'); + case 'callback_key': + return $this->keyitem('id',$this->callback_id); + + case 'callback_value': + return $this->keyitem('value',$this->callback_id); + case 'callback_id': case 'trigger_id': case 'type': diff --git a/src/Interactive/BlockActions.php b/src/Interactive/BlockActions.php index 4af105a..01b1207 100644 --- a/src/Interactive/BlockActions.php +++ b/src/Interactive/BlockActions.php @@ -69,10 +69,10 @@ final class BlockActions extends Base // An event can have more than 1 action, each action can have 1 value. case 'action_key': - return $this->action('action'); + return $this->keyitem('id',object_get($this->action,'action_id')); case 'action_value': - return $this->action('value'); + return $this->keyitem('value',object_get($this->action,'action_id')); case 'actions': case 'response_url': @@ -99,7 +99,7 @@ final class BlockActions extends Base return object_get($this->_data,'container.type'); 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->keyitem('value',object_get($this->action,'action_id')))->channel_id; case 'keys': return collect(object_get($this->_data,'view.blocks'))->pluck('accessory.action_id'); @@ -156,38 +156,6 @@ final class BlockActions extends Base } } - /** - * Separate out an action command to the id that the command relates to - * - * @param string $key - * @return string|null - * @throws \Exception - */ - private function action(string $key): ?string - { - $regex = '/^([a-z_]+)\|([0-9]+)$/'; - $action = NULL; - $value = NULL; - - // We only take the action up to the pipe symbol - $action_key = object_get($this->action,'action_id'); - - if (preg_match($regex,$action_key)) { - $action = preg_replace($regex,'$1',$action_key); - $value = preg_replace($regex,'$2',$action_key); - } - - switch ($key) { - case 'action': - return $action ?: $action_key; - case 'value': - return $value; - - default: - throw new \Exception('Unknown key: '.$key); - } - } - /** * Some block actions are triggered by messages, and thus dont have a callback_id * diff --git a/src/Interactive/InteractiveMessage.php b/src/Interactive/InteractiveMessage.php index f2fce5e..c9cef3f 100644 --- a/src/Interactive/InteractiveMessage.php +++ b/src/Interactive/InteractiveMessage.php @@ -99,26 +99,8 @@ class InteractiveMessage extends Base public function respond(): Message { Log::info(sprintf('%s:Interactive Message - Callback [%s] Name [%s] Type [%s]',static::LOGKEY,$this->callback_id,$this->name,$this->type),['m'=>__METHOD__]); + Log::notice(sprintf('%s:Unhandled action [%s]',static::LOGKEY,$this->callback_id),['m'=>__METHOD__]); - $action = NULL; - $id = NULL; - - if (preg_match('/^(.*)\|([0-9]+)/',$this->callback_id)) { - [$action,$id] = explode('|',$this->callback_id,2); - - } elseif (preg_match('/^[a-z_]+$/',$this->callback_id)) { - $id = $this->name; - $action = $this->callback_id; - - } else { - // If we get here, its an action that we dont know about. - Log::notice(sprintf('%s:Unhandled CALLBACK [%s]',static::LOGKEY,$this->callback_id),['m'=>__METHOD__]); - } - - switch ($action) { - default: - Log::notice(sprintf('%s:Unhandled ACTION [%s]',static::LOGKEY,$action),['m'=>__METHOD__]); - return (new Message)->text('That didnt work, I didnt know what to do with your button - you might like to tell '.$this->team()->owner->slack_user); - } + return (new Message)->text('That didnt work, I didnt know what to do with your button - you might like to tell '.$this->team()->owner->slack_user); } } \ No newline at end of file diff --git a/src/Interactive/ViewSubmission.php b/src/Interactive/ViewSubmission.php index c332c11..1702632 100644 --- a/src/Interactive/ViewSubmission.php +++ b/src/Interactive/ViewSubmission.php @@ -24,14 +24,14 @@ class ViewSubmission extends Base case 'blocks': return collect(object_get($this->_data,'view.'.$key)); - case 'callback': + case 'callback_id': return object_get($this->_data,'view.callback_id'); - case 'callback_id': - return $this->callback('id'); + case 'callback_key': + return $this->keyitem('id',$this->callback_id); case 'callback_value': - return $this->callback('value'); + return $this->keyitem('value',$this->callback_id); case 'meta': return object_get($this->_data,'view.private_metadata'); @@ -47,35 +47,6 @@ class ViewSubmission extends Base } } - /** - * Separate out an callback command to the id that the command relates to - * - * @param string $key - * @return string|null - * @throws \Exception - */ - private function callback(string $key): ?string - { - $regex = '/^([a-z_]+)\|([0-9]+)$/'; - $id = NULL; - $value = NULL; - - if (preg_match($regex,$this->callback)) { - $id = preg_replace($regex,'$1',$this->callback); - $value = preg_replace($regex,'$2',$this->callback); - } - - switch ($key) { - case 'id': - return $id ?: $this->callback; - case 'value': - return $value; - - default: - throw new \Exception('Unknown key: '.$key); - } - } - /** * This method should be overridden by a local implementation * @@ -85,25 +56,7 @@ class ViewSubmission extends Base { // Do some magic with event data Log::info(sprintf('%s:View Submission for Callback [%s] User [%s] in [%s]',self::LOGKEY,$this->callback_id,$this->user_id,$this->team_id),['m'=>__METHOD__]); - - $action = NULL; - $id = NULL; - - if (preg_match('/^(.*)\|([0-9]+)/',$this->callback_id)) { - [$action,$cid] = explode('|',$this->callback_id,2); - - } elseif (preg_match('/^[a-z_]+$/',$this->callback_id)) { - $action = $this->callback_id; - - } else { - // If we get here, its an action that we dont know about. - Log::notice(sprintf('%s:Unhandled CALLBACK [%s]',static::LOGKEY,$this->callback_id),['m'=>__METHOD__]); - } - - switch ($action) { - default: - Log::notice(sprintf('%s:Unhandled ACTION [%s]',self::LOGKEY,$action),['m'=>__METHOD__]); - } + Log::notice(sprintf('%s:Unhandled action [%s]',self::LOGKEY,$this->callback_key),['m'=>__METHOD__]); return new Modal; } diff --git a/src/Message.php b/src/Message.php index 3557cac..270f079 100644 --- a/src/Message.php +++ b/src/Message.php @@ -27,6 +27,7 @@ final class Message extends BlockKit private const LOGKEY = 'SM-'; private const MAX_ATTACHMENTS = 20; + private const MAX_BLOCKS = 50; private Model $o; private ?Carbon $selfdestruct = NULL; @@ -97,6 +98,9 @@ final class Message extends BlockKit $this->blocks->push($block); + if (count($this->blocks) > self::MAX_BLOCKS) + throw new SlackSyntaxException(sprintf('Messages should not have more than %d blocks',self::MAX_BLOCKS)); + return $this; } diff --git a/src/Options/Base.php b/src/Options/Base.php index 58b897f..1b2a1ad 100644 --- a/src/Options/Base.php +++ b/src/Options/Base.php @@ -5,6 +5,7 @@ namespace Slack\Options; use Illuminate\Support\Facades\Log; use Slack\Base as SlackBase; +use Slack\Exceptions\SlackException; use Slack\Message; abstract class Base extends SlackBase @@ -35,6 +36,7 @@ abstract class Base extends SlackBase * + user_id * @param string $key * @return mixed|object + * @throws \Exception */ public function __get(string $key) { @@ -48,11 +50,20 @@ abstract class Base extends SlackBase case 'user_id': return object_get($this->_data,'user.id'); + case 'callback_key': + return $this->keyitem('id',$this->callback_id); + + case 'callback_value': + return $this->keyitem('value',$this->callback_id); + case 'callback_id': //case 'action_ts': //case 'message_ts': case 'type': return object_get($this->_data,$key); + + default: + throw new SlackException('Unknown key: '.$key); } }