大家晚上好,今天要來把推送的樣板實作上去!以下面那隻小小兵為例!
為什麼會選他咧?因為我想做的事情是做一個推送巴哈動畫瘋的當日當季新番動畫列表!
所以對這需求來說,有張小截圖是很合理的!
好啦不廢話開始進入正題吧~
還記得昨天做的那隻推送訊息的function嗎?
/**
* @param MessageBuilder|string $content
* @return Response
*/
public function pushMessage($content): Response
{
if (is_string($content)) {
$content = new TextMessageBuilder($content);
}
return $this->lineBot->pushMessage($this->lineUserId, $content);
}
如果有自己看過官方的API文件大概就會知道為何我註解寫的content
可以是MessageBuilder|string
,如果還沒看也沒關係,吃連結吧!
或是直接看程式碼也有說明他吃MessageBuilder
這個介面的物件!LINEBot.php
/**
* Sends arbitrary message to destination.
*
* @param string $to Identifier of destination.
* @param MessageBuilder $messageBuilder Message builder to send.
* @return Response
*/
public function pushMessage($to, MessageBuilder $messageBuilder)
{
return $this->httpClient->post($this->endpointBase . '/v2/bot/message/push', [
'to' => $to,
'messages' => $messageBuilder->buildMessage(),
]);
}
沒問題!我們就餵給他這個物件!但要選哪一個咧?依照我的判斷應該是發綠光的那個!
如果你是使用PHP Storm 可以直接 ctrl(用mac的是command) + 左鍵
點擊 MessageBuilder
,就可以快速查找有哪些物件有用他了
如果是用VS code的話好像要另外下載套件,我記得是按F12的樣子
那我們再來看看TemplateMessageBuilder
這個樣板Message是在幹嘛的! 文件
<?php
namespace LINE\LINEBot\MessageBuilder;
use LINE\LINEBot\Constant\MessageType;
use LINE\LINEBot\MessageBuilder;
/**
* A builder class for template message.
*
* @package LINE\LINEBot\MessageBuilder
*/
class TemplateMessageBuilder implements MessageBuilder
{
/** @var string */
private $altText;
/** @var TemplateBuilder */
private $templateBuilder;
/**
* TemplateMessageBuilder constructor.
* @param string $altText
* @param TemplateBuilder $templateBuilder
*/
public function __construct($altText, TemplateBuilder $templateBuilder)
{
$this->altText = $altText;
$this->templateBuilder = $templateBuilder;
}
(...略)
}
恩~看來他又要餵一個叫做TemplateBuilder
介面的物件,依照文件上描述他可以有這四種物件!
那我們就用一樣的找法,可以找到有用這介面的四種物件吧!
恩~仔細看了一下,多的兩個是CarouselTemplateBuilder
和ImageCarouselTemplateBuilder
,看起來是多提供給我們拿來包複數個的CarouselColumnTemplateBuilder
和ImageCarouselColumnTemplateBuilder
!真是太佛啦!
那話不多說,我們就先從寄送單一個ImageCarouselColumnTemplateBuilder
來試試看吧!ImageCarouselColumnTemplateBuilder.php
<?php
/**
namespace LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder;
use LINE\LINEBot\TemplateActionBuilder;
/**
* A builder class for column of image carousel template.
*
* @package LINE\LINEBot\MessageBuilder\TemplateBuilder
*/
class ImageCarouselColumnTemplateBuilder implements TemplateBuilder
{
/** @var string */
private $imageUrl;
/** @var TemplateActionBuilder */
private $actionBuilder;
/** @var array */
private $template;
/**
* ImageCarouselColumnTemplateBuilder constructor.
*
* @param string $imageUrl
* @param TemplateActionBuilder $actionBuilder
*/
public function __construct($imageUrl, $actionBuilder)
{
$this->imageUrl = $imageUrl;
$this->actionBuilder = $actionBuilder;
}
(...略)
}
恩...又來了一個TemplateActionBuilder
,一樣的方法去追code,這次就不廢話了,我選UriTemplateActionBuilder
這個來使用!
頭暈了嗎!?
仔細整理一下這個大腸包小腸的概念到底是包了什麼!
然後我們就可以組出下面這個!LineBotService.php
public function buildTemplateMessageBuilderDeprecated(
string $imagePath,
string $directUri,
string $label
): TemplateMessageBuilder {
$aa = new UriTemplateActionBuilder($label, $directUri);
$target = new ImageCarouselColumnTemplateBuilder($imagePath, $aa);
return new TemplateMessageBuilder('test123', $target);
}
LineBotServiceTest.php
public function testPushMessageWithObjectDeprecated()
{
$target = $this->lineBotService->buildTemplateMessageBuilderDeprecated(
'https://i.imgur.com/BlBH2HE.jpg',
'https://github.com/Tai-ch0802/php-crawler-chat-bot',
'自己玩的linebot'
);
$response = $this->lineBotService->pushMessage($target);
$this->assertEquals(200, $response->getHTTPStatus());
}
我們先別急,把他dd
出來看一下他吐回的訊息是什麼
{"message":"A message (messages[0]) in the request body is invalid","details":[{"message":"unknown template type","property":"template[@type=unknown]"}]}
這是一坨大雷!
一開始我完全搞不懂他到底是在表達什麼!unknown template type
我都已經照文件上給的了,應該沒有問題才對!到底是鬧哪樣了呢?
接著我開始去細看每一個物件到底在必瞎咪懵!發現他是在組json的字串格式! 文件
沒錯,最終目的是要組出跟這有87%相似的陣列。
有想法了嗎?對的,就是那同個interface的另外一個物件ImageCarouselTemplateBuilder
!
我們就把它拿來用用看吧!就決定是你啦!LineBotService.php
public function buildTemplateMessageBuilderDeprecated(
string $imagePath,
string $directUri,
string $label
): TemplateMessageBuilder {
$aa = new UriTemplateActionBuilder($label, $directUri);
$bb = new ImageCarouselColumnTemplateBuilder($imagePath, $aa);
$target = new ImageCarouselTemplateBuilder([$bb, $bb, $bb, $bb, $bb, $bb, $bb, $bb]);
return new TemplateMessageBuilder('test123', $target);
}
LineBotServiceTest.php
public function testPushMessageWithObjectDeprecated()
{
$target = $this->lineBotService->buildTemplateMessageBuilderDeprecated(
'https://i.imgur.com/BlBH2HE.jpg',
'https://github.com/Tai-ch0802/php-crawler-chat-bot',
'自己玩的linebot'
);
$response = $this->lineBotService->pushMessage($target);
$this->assertEquals(200, $response->getHTTPStatus());
}
恩~收到一堆垃圾了!
好欸!成功了!
接著我們稍微整理一下我們想要塞入資料的格式,最後會生出下面這個,詳細可以參考這裡LineBotService.php
public function buildTemplateMessageBuilder(array $data, string $notificationText = '新通知來囉!'): array
{
$imageCarouselColumnTemplateBuilders = array_map(function ($d) {
return $this->buildImageCarouselColumnTemplateBuilder(
$d['imagePath'],
$d['directUri'],
$d['label']
);
}, $data);
$tempChunk = array_chunk($imageCarouselColumnTemplateBuilders, 5);
return array_map(function ($data) use ($notificationText) {
return new TemplateMessageBuilder(
$notificationText,
new ImageCarouselTemplateBuilder($data)
);
}, $tempChunk);
}
/**
* @param string $imagePath
* @param string $directUri
* @param string $label
* @return ImageCarouselColumnTemplateBuilder
*/
protected function buildImageCarouselColumnTemplateBuilder(
string $imagePath,
string $directUri,
string $label
): ImageCarouselColumnTemplateBuilder {
return new ImageCarouselColumnTemplateBuilder(
$imagePath,
new UriTemplateActionBuilder($label, $directUri)
);
}
LineBotServiceTest.php
public function testPushMessageWithObject()
{
if (empty(env('LINEBOT_TOKEN'))) {
$this->markTestSkipped('Invalid LINEBOT_TOKEN');
}
$data = [
[
'imagePath' => 'https://i.imgur.com/BlBH2HE.jpg',
'directUri' => 'https://github.com/Tai-ch0802/php-crawler-chat-bot',
'label' => '自己玩的linebot',
],
[
'imagePath' => 'https://i.imgur.com/XJkiup5.jpg',
'directUri' => 'https://zh.wikipedia.org/wiki/%E7%8C%AB',
'label' => '喵星人',
],
[
'imagePath' => 'https://pbs.twimg.com/profile_images/839721704163155970/LI_TRk1z_400x400.jpg',
'directUri' => 'https://www.google.com.tw/',
'label' => 'Google',
],
[
'imagePath' => 'https://www.codeforest.net/wp-content/uploads/2013/04/laravel-logo-big-570x398.png',
'directUri' => 'https://laravel.com/',
'label' => 'laravel',
],
[
'imagePath' => 'https://cdn2.ettoday.net/images/2471/2471912.jpg',
'directUri' => 'https://ithelp.ithome.com.tw/ironman',
'label' => '鐵人賽',
],
[
'imagePath' => 'https://cdn2.ettoday.net/images/2709/2709694.jpg',
'directUri' => 'https://login.apiary.io/login',
'label' => 'Blueprint',
],
[
'imagePath' => 'https://d.line-scdn.net/stf/line-lp/1200x630.png',
'directUri' => 'https://developers.line.me/en/',
'label' => 'LINE',
],
];
$targets = $this->lineBotService->buildTemplateMessageBuilder($data, 'test push!');
foreach ($targets as $target) {
$response = $this->lineBotService->pushMessage($target);
$this->assertEquals(200, $response->getHTTPStatus());
}
}
好啦!今天時間差不多了,如果有任何其他問題或是建議都可以在底下留言回覆喔!