diff --git a/src/Http/Controllers/InteractiveMessageController.php b/src/Http/Controllers/InteractiveMessageController.php new file mode 100644 index 0000000..1a693b2 --- /dev/null +++ b/src/Http/Controllers/InteractiveMessageController.php @@ -0,0 +1,45 @@ +payload,TRUE),TRUE)); + Log::debug(sprintf('%s:Firing Event [%s] and responding [%s]',static::LOGKEY,get_class($event),$event->respondNow)); + + if ($event->respondNow) { + if (! method_exists($event,'respond')) { + Log::alert(sprintf('%s:Cant respond to Event [%s], no respond method',static::LOGKEY,get_class($event))); + + } else { + $result = $event->respond(); + + return (($result instanceof Message) AND $result->isEmpty()) ? NULL : $result; + } + + } else { + event($event); + + Log::info(sprintf('%s:Dispatched Event [%s]',static::LOGKEY,get_class($event))); + return response('IM Event Processed',200); + } + } +} \ No newline at end of file diff --git a/src/Http/Controllers/SlackAppController.php b/src/Http/Controllers/SlackAppController.php index dd29500..9f33ce7 100644 --- a/src/Http/Controllers/SlackAppController.php +++ b/src/Http/Controllers/SlackAppController.php @@ -2,16 +2,16 @@ namespace Slack\Http\Controllers; -use App\Http\Controllers\Controller; use GuzzleHttp\Client; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Redirect; - use Slack\Jobs\TeamUpdate; use Slack\Models\{Enterprise,Team,Token,User}; +use App\Http\Controllers\Controller; + class SlackAppController extends Controller { protected const LOGKEY = 'CSA'; diff --git a/src/Http/Middleware/CheckRequest.php b/src/Http/Middleware/CheckRequest.php index 951450d..60024fb 100644 --- a/src/Http/Middleware/CheckRequest.php +++ b/src/Http/Middleware/CheckRequest.php @@ -7,8 +7,8 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Log; use Slack\Client\Payload; use Slack\Event\Factory as EventFactory; +use Slack\Interactive\Factory as InteractiveFactory; -use App\Slack\Interactive\Factory as InteractiveFactory; use App\Slack\Options\Factory as OptionsFactory; class CheckRequest @@ -51,7 +51,7 @@ class CheckRequest break; case 'api/imsg': - $event = InteractiveFactory::make($request); + $event = InteractiveFactory::make(new Payload(json_decode($request->payload,TRUE),TRUE)); break; default: diff --git a/src/Interactive/Base.php b/src/Interactive/Base.php index e5a31bd..db219d7 100644 --- a/src/Interactive/Base.php +++ b/src/Interactive/Base.php @@ -8,6 +8,8 @@ use Slack\Base as SlackBase; abstract class Base extends SlackBase { // Does the event respond with a reply to the HTTP request, or via a post with a trigger + // Child class should have a respond() function. + // (There should be a local implementation of the child class should respondNow = TRUE) public $respondNow = FALSE; // When retrieving multiple action values, this is the index we are retrieving. @@ -61,4 +63,4 @@ abstract class Base extends SlackBase if ($key == 'index') $this->{$key} = $value; } -} +} \ No newline at end of file diff --git a/src/Interactive/BlockActions.php b/src/Interactive/BlockActions.php index 1d513ef..61db4dc 100644 --- a/src/Interactive/BlockActions.php +++ b/src/Interactive/BlockActions.php @@ -60,9 +60,6 @@ class BlockActions extends Base public function __get($key) { switch ($key) { - case 'actions': - return object_get($this->_data,$key); - case 'action_id': return object_get(Arr::get(object_get($this->_data,'actions'),$this->index),$key); @@ -73,9 +70,15 @@ class BlockActions extends Base case 'action_value': return $this->action('value'); + case 'actions': + return object_get($this->_data,$key); + case 'callback_id': return object_get($this->_data,'view.callback_id'); + case 'channel_id': + return object_get($this->_data,'channel.id') ?: Channel::findOrFail($this->action('value'))->channel_id; + case 'keys': return collect(object_get($this->_data,'view.blocks'))->pluck('accessory.action_id'); @@ -83,9 +86,6 @@ class BlockActions extends Base case 'message_ts': return object_get($this->_data,'message.ts'); - case 'channel_id': - return object_get($this->_data,'channel.id') ?: Channel::findOrFail($this->action('value'))->channel_id; - case 'team_id': // view.team_id represent workspace publishing view return object_get($this->_data,'user.team_id'); @@ -166,4 +166,20 @@ class BlockActions extends Base { return object_get($this->_data,'message') ? TRUE : FALSE; } -} + + /** + * Get the selected options from a block action actions array + * + * @return Collection + */ + public function selected_options(): Collection + { + $result = collect(); + + foreach (Arr::get(object_get($this->_data,'actions'),'0')->selected_options as $option) { + $result->push($option->value); + } + + return $result; + } +} \ No newline at end of file diff --git a/src/Interactive/Factory.php b/src/Interactive/Factory.php index ad7afdd..ed51f61 100644 --- a/src/Interactive/Factory.php +++ b/src/Interactive/Factory.php @@ -15,11 +15,11 @@ class Factory { * @var array event type to event class mapping */ public const map = [ - 'block_actions'=>BlockActions::class, - 'interactive_message'=>InteractiveMessage::class, - 'shortcut'=>Shortcut::class, - 'view_closed'=>ViewClosed::class, - 'view_submission'=>ViewSubmission::class, + 'block_actions' => BlockActions::class, + //'interactive_message' => InteractiveMessage::class, + 'shortcut' => Shortcut::class, + 'view_closed' => ViewClosed::class, + //'view_submission' => ViewSubmission::class, ]; /** @@ -31,7 +31,7 @@ class Factory { */ public static function create(string $type,array $request): Base { - $class = Arr::get(self::map,$type,Unknown::class); + $class = Arr::get(config('slack.interactive',self::map),$type,Unknown::class); Log::debug(sprintf('%s:Working out Interactive Message Event Class for [%s] as [%s]',static::LOGKEY,$type,$class),['m'=>__METHOD__]); if (App::environment() == 'local') @@ -53,4 +53,4 @@ class Factory { return $o; } -} +} \ No newline at end of file diff --git a/src/Interactive/InteractiveMessage.php b/src/Interactive/InteractiveMessage.php index ab082f1..bdb2669 100644 --- a/src/Interactive/InteractiveMessage.php +++ b/src/Interactive/InteractiveMessage.php @@ -57,7 +57,7 @@ use Slack\Message; */ class InteractiveMessage extends Base { - private const LOGKEY = 'IIM'; + protected const LOGKEY = 'IIM'; // Does the event respond with a reply to the HTTP request, or via a post with a trigger public $respondNow = TRUE; @@ -90,6 +90,11 @@ class InteractiveMessage extends Base } } + /** + * This method should be overridden by a local implementation + * + * @return 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__]); @@ -112,7 +117,7 @@ class InteractiveMessage extends Base switch ($action) { default: Log::notice(sprintf('%s:Unhandled ACTION [%s]',static::LOGKEY,$action),['m'=>__METHOD__]); - return (new Message)->setText('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); } } } diff --git a/src/Interactive/ViewSubmission.php b/src/Interactive/ViewSubmission.php index 316dfb5..10c1747 100644 --- a/src/Interactive/ViewSubmission.php +++ b/src/Interactive/ViewSubmission.php @@ -5,6 +5,7 @@ namespace Slack\Interactive; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; +use Slack\Message; use Slack\Models\Team; use Slack\Blockkit\Modal; @@ -15,7 +16,7 @@ use Slack\Blockkit\Modal; */ class ViewSubmission extends Base { - private const LOGKEY = 'IVS'; + protected const LOGKEY = 'IVS'; // View Submissions must respond with via a trigger or inline public $respondNow = TRUE; @@ -37,33 +38,11 @@ class ViewSubmission extends Base } } - private function blocks(): Collection - { - $result = collect(); - - foreach (object_get($this->_data,'view.blocks',[]) as $id=>$block) { - switch (object_get($block,'type')) { - case 'input': - $result->put($block->element->action_id,$block->block_id); - break; - - case 'section': - $result->put($block->block_id,$id); - break; - } - } - - return $result; - } - - public function value(string $block_id): ?string - { - $key = Arr::get($this->blocks(),$block_id); - - // Return the state value, or the original block value - return object_get($this->_data,'view.state.values.'.$key.'.'.$block_id.'.value') ?: object_get(Arr::get(object_get($this->_data,'view.blocks'),$key),'text.text',''); - } - + /** + * This method should be overridden by a local implementation + * + * @return Message + */ public function respond(): Modal { // Do some magic with event data @@ -90,4 +69,31 @@ class ViewSubmission extends Base return new Modal(new Team); } + + protected function blocks(): Collection + { + $result = collect(); + + foreach (object_get($this->_data,'view.blocks',[]) as $id=>$block) { + switch (object_get($block,'type')) { + case 'input': + $result->put($block->element->action_id,$block->block_id); + break; + + case 'section': + $result->put($block->block_id,$id); + break; + } + } + + return $result; + } + + public function value(string $block_id): ?string + { + $key = Arr::get($this->blocks(),$block_id); + + // Return the state value, or the original block value + return object_get($this->_data,'view.state.values.'.$key.'.'.$block_id.'.value') ?: object_get(Arr::get(object_get($this->_data,'view.blocks'),$key),'text.text',''); + } } diff --git a/src/routes.php b/src/routes.php index 90f2249..42b6e62 100644 --- a/src/routes.php +++ b/src/routes.php @@ -28,4 +28,9 @@ app('router') 'uses' => 'EventsController@fire', 'as' => 'event', ]); + + $router->post('imsg', [ + 'uses' => 'InteractiveMessageController@fire', + 'as' => 'imsg', + ]); }); \ No newline at end of file