Standardisation of callback_id/key/value and action_id/key/value, Message can only have 50 blocks

This commit is contained in:
Deon George 2022-09-06 11:30:28 +10:00
parent be26c3c0a3
commit 1b55d7ab52
9 changed files with 74 additions and 107 deletions

View File

@ -456,6 +456,8 @@ final class API
case 'thread_not_found': case 'thread_not_found':
throw new SlackThreadNotFoundException('Thread Not Found',$request->status()); throw new SlackThreadNotFoundException('Thread Not Found',$request->status());
case 'account_inactive':
// @todo Mark the token/team as inactive
default: default:
Log::error(sprintf('%s:Generic Error',static::LOGKEY),['m'=>__METHOD__,'t'=>$this->_token->team_id,'r'=>$response]); Log::error(sprintf('%s:Generic Error',static::LOGKEY),['m'=>__METHOD__,'t'=>$this->_token->team_id,'r'=>$response]);
throw new SlackException($response->error,$request->status()); throw new SlackException($response->error,$request->status());

View File

@ -64,6 +64,36 @@ abstract class Base
return $o->exists ? $o : NULL; 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 * Return the Eneterprise object that a Response is related to
* *

View File

@ -10,6 +10,16 @@ use Slack\Exceptions\SlackSyntaxException;
/** /**
* Class BlockKit - Slack Blockit Objects * 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 * @package Slack
*/ */
abstract class BlockKit implements \JsonSerializable,\Countable abstract class BlockKit implements \JsonSerializable,\Countable

View File

@ -35,6 +35,7 @@ abstract class Base extends SlackBase
* + user_id * + user_id
* @param string $key * @param string $key
* @return mixed|object * @return mixed|object
* @throws \Exception
*/ */
public function __get(string $key) public function __get(string $key)
{ {
@ -46,6 +47,12 @@ abstract class Base extends SlackBase
case 'user_id': case 'user_id':
return object_get($this->_data,'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 'callback_id':
case 'trigger_id': case 'trigger_id':
case 'type': case 'type':

View File

@ -69,10 +69,10 @@ final class BlockActions extends Base
// 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':
return $this->action('action'); return $this->keyitem('id',object_get($this->action,'action_id'));
case 'action_value': case 'action_value':
return $this->action('value'); return $this->keyitem('value',object_get($this->action,'action_id'));
case 'actions': case 'actions':
case 'response_url': case 'response_url':
@ -99,7 +99,7 @@ final class BlockActions extends Base
return object_get($this->_data,'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->keyitem('value',object_get($this->action,'action_id')))->channel_id;
case 'keys': case 'keys':
return collect(object_get($this->_data,'view.blocks'))->pluck('accessory.action_id'); 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 * Some block actions are triggered by messages, and thus dont have a callback_id
* *

View File

@ -99,26 +99,8 @@ class InteractiveMessage extends Base
public function respond(): Message 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::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; 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);
$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);
}
} }
} }

View File

@ -24,14 +24,14 @@ class ViewSubmission extends Base
case 'blocks': case 'blocks':
return collect(object_get($this->_data,'view.'.$key)); return collect(object_get($this->_data,'view.'.$key));
case 'callback': case 'callback_id':
return object_get($this->_data,'view.callback_id'); return object_get($this->_data,'view.callback_id');
case 'callback_id': case 'callback_key':
return $this->callback('id'); return $this->keyitem('id',$this->callback_id);
case 'callback_value': case 'callback_value':
return $this->callback('value'); return $this->keyitem('value',$this->callback_id);
case 'meta': case 'meta':
return object_get($this->_data,'view.private_metadata'); 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 * This method should be overridden by a local implementation
* *
@ -85,25 +56,7 @@ class ViewSubmission extends Base
{ {
// Do some magic with event data // 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__]); 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__]);
Log::notice(sprintf('%s:Unhandled action [%s]',self::LOGKEY,$this->callback_key),['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__]);
}
return new Modal; return new Modal;
} }

View File

@ -27,6 +27,7 @@ final class Message extends BlockKit
private const LOGKEY = 'SM-'; private const LOGKEY = 'SM-';
private const MAX_ATTACHMENTS = 20; private const MAX_ATTACHMENTS = 20;
private const MAX_BLOCKS = 50;
private Model $o; private Model $o;
private ?Carbon $selfdestruct = NULL; private ?Carbon $selfdestruct = NULL;
@ -97,6 +98,9 @@ final class Message extends BlockKit
$this->blocks->push($block); $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; return $this;
} }

View File

@ -5,6 +5,7 @@ namespace Slack\Options;
use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Log;
use Slack\Base as SlackBase; use Slack\Base as SlackBase;
use Slack\Exceptions\SlackException;
use Slack\Message; use Slack\Message;
abstract class Base extends SlackBase abstract class Base extends SlackBase
@ -35,6 +36,7 @@ abstract class Base extends SlackBase
* + user_id * + user_id
* @param string $key * @param string $key
* @return mixed|object * @return mixed|object
* @throws \Exception
*/ */
public function __get(string $key) public function __get(string $key)
{ {
@ -48,11 +50,20 @@ abstract class Base extends SlackBase
case 'user_id': case 'user_id':
return object_get($this->_data,'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 'callback_id':
//case 'action_ts': //case 'action_ts':
//case 'message_ts': //case 'message_ts':
case 'type': case 'type':
return object_get($this->_data,$key); return object_get($this->_data,$key);
default:
throw new SlackException('Unknown key: '.$key);
} }
} }