_data = collect(); // Message is to a channel if ($o instanceof Channel) { $this->setChannel($o); // Message is to a user } elseif ($o instanceof User) { $this->setUser($o); } $this->o = $o; $this->attachments = collect(); $this->blocks = collect(); } /** * Add an attachment to a message * * @param Attachment $attachment * @return Message */ public function addAttachment(Attachment $attachment): self { $this->attachments->push($attachment); return $this; } /** * Add a block to the message * * @param BlockKit $block * @return $this */ public function addBlock(BlockKit $block): self { $this->blocks->push($block); return $this; } /** * Empty the message * * @return $this */ public function blank(): self { $this->_data = collect(); return $this; } /* * @todo This doesnt appear to work public function ephemeral(): self { $this->_data->put('ephemeral',TRUE); return $this; } */ public function forgetTS(): self { $this->_data->forget('ts'); return $this; } /** * Return if this is an empty message * * @return bool */ public function isEmpty(): bool { return $this->jsonSerialize() ? FALSE : TRUE; } /** * When we json_encode this object, this is the data that will be returned */ public function jsonSerialize() { if ($this->blocks->count()) { if ($this->_data->has('text')) throw new \Exception('Messages cannot have text and blocks!'); $this->_data->put('blocks',$this->blocks); } if ($this->attachments->count()) $this->_data->put('attachments',$this->attachments); // For interactive messages that generate a dialog, we need to return NULL return $this->_data->count() ? $this->_data : NULL; } /** * Post this message to slack * * @param Carbon|null $delete * @return Generic * @throws \Exception */ public function post(Carbon $delete=NULL): Generic { if ($this->_data->has('ephemeral')) abort('500','Cannot post ephemeral messages.'); $api = $this->o->team->slackAPI(); $response = $this->_data->has('ts') ? $api->updateMessage($this) : $api->postMessage($this); if ($delete) { Log::debug(sprintf('%s:Scheduling Delete of [%s:%s] on [%s]',static::LOGKEY,object_get($this->o,'channel_id',$this->o->id),$response->ts,$delete->format('Y-m-d')),['m'=>__METHOD__]); // Queue the delete of the message if requested dispatch((new DeleteChat($this->o,$response->ts))->onQueue('low')->delay($delete)); } return $response; } public function replace(bool $replace=TRUE): self { $this->_data['replace_original'] = $replace ? 'true' : 'false'; return $this; } /** * Post a message to slack using the respond_url * @note This URL can only be used 5 times in 30 minutes * * @param string $url */ public function respond(string $url) { $request = curl_init(); curl_setopt($request,CURLOPT_URL,$url); curl_setopt($request,CURLOPT_RETURNTRANSFER,TRUE); curl_setopt($request,CURLINFO_HEADER_OUT,TRUE); curl_setopt($request,CURLOPT_HTTPHEADER,['Content-Type: application/json; charset=utf-8']); curl_setopt($request,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($request,CURLOPT_POSTFIELDS,json_encode($this)); try { $result = curl_exec($request); if (! $result) throw new \Exception('CURL exec returned an empty response: '.serialize(curl_getinfo($request))); } catch (\Exception $e) { Log::error(sprintf('%s:Got an error while posting to [%s] (%s)',static::LOGKEY,$url,$e->getMessage()),['m'=>__METHOD__]); throw new \Exception($e->getMessage()); } if ($result !== 'ok') { switch ($result) { default: Log::critical(sprintf('%s:Generic Error',static::LOGKEY),['m'=>__METHOD__,'r'=>$result]); throw new SlackException($result,curl_getinfo($request,CURLINFO_HTTP_CODE)); } } curl_close($request); return $result; } /** * Make the message self destruct * * @param Carbon $time * @return Generic * @throws \Exception */ public function selfdestruct(Carbon $time): Generic { $this->addBlock( (new Block)->addContext( collect() ->push((new BlockKit)->text(sprintf('This message will self destruct in %s...',$time->diffForHumans(Carbon::now(),['syntax' => CarbonInterface::DIFF_RELATIVE_TO_NOW])))))); return $this->post($time); } /** * Set our channel * * @param Channel $o * @return Message */ public function setChannel(Channel $o) { $this->_data['channel'] = $o->channel_id; return $this; } /** * Set the icon next to the message * * @param string $icon * @return $this * @deprecated */ public function setIcon(string $icon): self { $this->_data->put('icon_emoji',$icon); return $this; } /** * Option groups are used by the interactive Options controller and hold no other attributes * * @param array $array * @return void */ public function setOptionGroup(array $array): void { $this->_data = collect(); $this->_data->put('option_groups',$array); } /** * Message text * * @param string $string * @return $this */ public function setText(string $string): self { $this->_data->put('text',$string); return $this; } public function setTS(string $string): self { $this->_data->put('ts',$string); return $this; } public function setThreadTS(string $string): self { $this->_data->put('thread_ts',$string); return $this; } /** * Set our channel * * @param User $o * @return Message */ public function setUser(User $o) { $this->_data['channel'] = $o->user_id; return $this; } public function setUserName(string $user) { $this->_data['username'] = $user; return $this; } }