PHP
laravel
linebot

[PHP] Laravel+LineBotAPI アップロードした画像をそのまま返してくれる機能の実装

LineBotAPI から画像を送るには https 付きのフルパスで指定してあげる必要があって
Storage::url が返してくるのが相対パスなのであああああああああってなってた
public_path とか色々使ったけど、asset で解決しました :thumbsup:

<?php

class ImageMessageHandler extends AbstractHandler
{
    public static function create(LINEBot $bot, ImageMessage $imageMessage): self
    {
        $messages = [];
        $contentId = $imageMessage->getMessageId();
        $image = $bot->getMessageContent($contentId)->getRawBody();

        Storage::put('public/file.jpg', $image);
        $url = asset(Storage::url('public/file.jpg'));
        $messages[] = new TextMessageBuilder($url);
        $messages[] = new ImageMessageBuilder($url, $url);

        Log::info('ImageMessageHandler@create', [
            'url' => $url,
        ]);

        return new self($bot, $imageMessage->getReplyToken(), $messages);
    }
}

Screenshot_20181015-235735.png

公式曰く
https://readouble.com/laravel/5.6/ja/filesystem.html

s3、もしくはrackspaceドライバを使用している場合、完全なリモートURLを返します

とあるので、クラウドを使うときはここで詰むことはなさそう(むしろ逆に asset 消さなきゃ?)

後日談

!?

Screenshot_20181016-003900.png

プレビュー用の情報をキャッシュで持ってる?っぽく一意にしてあげることで解決

-        Storage::put('public/file.jpg', $image);
-        $url = asset(Storage::url('public/file.jpg'));
+        $filePath = sprintF('public/%s.jpg', Carbon::now()->getTimestamp());
+        Storage::put($filePath, $image);
+        $url = asset(Storage::url($filePath));

ただこれだと複数がいっぺんにあげたときとかが考慮されてないので本当に組み込む時はもうちょい考えてあげる必要がありそう