shun123
@shun123 (shun noel)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHPを使ってLine Notify APIで画像を送信したい

Q&A

Closed

解決したいこと

PHPを使ってLINE Notify のメッセージ送信APIで、画像をLINE送信したいです。
メッセージ送信はできるのですが、画像を送信することができません。
解決方法をご存知の方がおりましたら、お教え願います。
HTTPクライアントライブラリとしてGuzzleを利用しています。

発生している問題・エラー

Client error: `POST https://notify-api.line.me/api/notify` resulted in a `400 Bad Request` response:
{"status":400,"message":"Failed to upload file."}」

該当するソースコード

use \GuzzleHttp\Client;
$client = new Client();
$uri = 'https://notify-api.line.me/api/notify';
$line_token = 'xxxxxxxxxxxxxxxxxxxxxxx';
$image_path = 'login.jpg'
$message = 'test message';

$res = $client->request('POST',$uri,[
    'headers' => [
        'Authorization' => 'Bearer ' . $line_token ,
        'Content-Type' => 'multipart/form-data'
    ],
    'multipart' => [
        [
            'name' => 'message',
            'contents' => $message 
        ],
        [
            'name' => 'imageFile',
            'contents' => fopen($image_path, "rb")
        ]
    ]
]);

確認したこと

以下pythonの場合だと正常に画像を送信することができます。

import requests, os
def main():
    send_image_line_notify()

def send_image_line_notify():
    # カレントディレクトリを、送信画像が配置されているパスに変更
    os.chdir(os.getcwd() + '/png')

    # LineNotify 連携用トークン・キー準備
    line_notify_token = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
    line_notify_api = 'https://notify-api.line.me/api/notify'

    # payload・httpヘッダー設定
    payload = {'message': 'テスト通知1'}
    headers = {'Authorization': 'Bearer ' + line_notify_token}

    # 送信画像設定
    files = {'imageFile': open("110.png", "rb")}  # バイナリファイルオープン

    # post実行
    line_notify = requests.post(line_notify_api, data=payload, headers=headers, files=files)


if __name__ == "__main__":
    main()
0

1Answer

すみません、実際にLINE APIに詳しいわけではないのでエラー内容からの推測ですが
サイズが大きそうなファイルなのでboundaryによるパート分けが発生していると思います。
にもかかわらず'Content-Type'を'multipart/form-data'と明示的に指定しているので、boundaryを設定できていないのではないでしょうか?
Guzzleが自動的にcontent-typeを設定すると思いますので、以下コードはいかがでしょうか?

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\LazyOpenStream;

$client = new Client();
$uri = 'https://notify-api.line.me/api/notify';
$line_token = 'xxxxxxxxxxxxxxxxxxxxxxx';
$image_path = 'login.jpg';
$message = 'test message';

$res = $client->request('POST', $uri, [
    'headers' => [
        'Authorization' => 'Bearer ' . $line_token
    ],
    'multipart' => [
        [
            'name' => 'message',
            'contents' => $message 
        ],
        [
            'name' => 'imageFile',
            'contents' => new LazyOpenStream($image_path, 'r')
        ]
    ]
]);

もしcontent-typeを手動で設定する必要がある場合は
'Content-Type' => 'multipart/form-data; boundary='.$boundary,
とboundaryを付与してあげる必要があります。

1Like

Your answer might help someone💌