iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 5
2
自我挑戰組

用 laravel 尻出自己形狀的 line bot,還要撐三十天!系列 第 5

【第五天】推送通知PUSH! Part2(2/2)

【第五天】推送通知PUSH! Part2(2/2)

大家晚上好,今天要來把推送的樣板實作上去!以下面那隻小小兵為例!
https://ithelp.ithome.com.tw/upload/images/20171209/20107380eCIfbQTpVR.png

為什麼會選他咧?因為我想做的事情是做一個推送巴哈動畫瘋的當日當季新番動畫列表!
所以對這需求來說,有張小截圖是很合理的!

好啦不廢話開始進入正題吧~

還記得昨天做的那隻推送訊息的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(),
        ]);
    }

沒問題!我們就餵給他這個物件!但要選哪一個咧?依照我的判斷應該是發綠光的那個!
https://ithelp.ithome.com.tw/upload/images/20171210/20107380oSPYx1LfCz.png
如果你是使用PHP Storm 可以直接 ctrl(用mac的是command) + 左鍵 點擊 MessageBuilder,就可以快速查找有哪些物件有用他了
https://ithelp.ithome.com.tw/upload/images/20171210/201073804KVGKNLJ4B.png
如果是用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介面的物件,依照文件上描述他可以有這四種物件!
https://ithelp.ithome.com.tw/upload/images/20171210/20107380pM1bVSCEzF.png

那我們就用一樣的找法,可以找到有用這介面的四種物件吧!
https://ithelp.ithome.com.tw/upload/images/20171210/20107380CYHxlKEthe.png

恩~仔細看了一下,多的兩個是CarouselTemplateBuilderImageCarouselTemplateBuilder,看起來是多提供給我們拿來包複數個的CarouselColumnTemplateBuilderImageCarouselColumnTemplateBuilder!真是太佛啦!

那話不多說,我們就先從寄送單一個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這個來使用!
頭暈了嗎!?
仔細整理一下這個大腸包小腸的概念到底是包了什麼!
https://ithelp.ithome.com.tw/upload/images/20171210/20107380VP9I9EyyFb.png

然後我們就可以組出下面這個!
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());
    }

然後他就400了!What!!!?

我們先別急,把他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%相似的陣列。
https://ithelp.ithome.com.tw/upload/images/20171210/20107380FIgUPhbzWg.png

有想法了嗎?對的,就是那同個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());
    }

恩~收到一堆垃圾了!
https://ithelp.ithome.com.tw/upload/images/20171210/20107380J5OyuV9JkZ.png

好欸!成功了!
接著我們稍微整理一下我們想要塞入資料的格式,最後會生出下面這個,詳細可以參考這裡
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());
        }
    }

好啦!今天時間差不多了,如果有任何其他問題或是建議都可以在底下留言回覆喔!


上一篇
【第四天】推送通知PUSH! Part1(1/2)
下一篇
【第六天】爬蟲聽起來很強欸!那是啥?
系列文
用 laravel 尻出自己形狀的 line bot,還要撐三十天!30

1 則留言

0
牙膏大師!
iT邦新手 4 級 ‧ 2017-12-18 14:12:30

XD 跟實況一樣的文章很有趣!

太太 iT邦新手 5 級 ‧ 2017-12-19 00:17:33 檢舉

謝謝啦XD 希望多少對大家有點幫助!

我要留言

立即登入留言