Cannot send an empty message 50006 when using multipart Laravel Http post - laravel

I am getting this error when trying to send a message to a Discord webhook.
{"message": "Cannot send an empty message", "code": 50006}
I've read the discord documentation on sending images, and can honestly not see what I'm doing wrong.
Here's the code I'm running:
Http::withHeaders([
'Content-Type' => 'multipart/form-data; boundary=--abcdefghijklmnop'
])
->asMultipart()
->post(
$this->webhookUrl,
[
[
'name' => 'payload_json',
'contents' => '{
"content": "Hello, World!",
"embeds": [{
"title": "Hello, Embed!",
"description": "This is an embedded message.",
"thumbnail": {
"url": "attachment://image1.jpg"
},
"image": {
"url": "attachment://image2.jpg"
}
}],
"attachments": [{
"id": 0,
"description": "Image of a cute little cat",
"filename": "image1.jpg"
}, {
"id": 1,
"description": "Rickroll gif",
"filename": "image2.jpg"
}]
}',
'headers' => [
'Content-Type' => 'application/json',
]
],
[
'name' => 'image1.jpg',
'contents' => 'data:image/jpeg;base64,[[encoded image]]',
'headers' => [
'Content-Type' => 'image/jpeg',
]
],
[
'name' => 'image2.jpg',
'contents' => 'data:image/jpeg;base64,[[encoded image]]',
'headers' => [
'Content-Type' => 'image/jpeg',
]
]
];
);
As you can see, this is basically the message they use in their documentation as an example and I've just translated it to be sent with the Http facade.
What am I missing?

Related

Tried to made an POST request using Guzzle

Im so new using API in my project, so i tried to make an POST request using Guzzle in Laravel, but i really dont know to do it, i've been seraching on the internet how to but i can't find the answer, here's what i've been tried:
$headers = [
'Content-Type' => 'application/json',
'signature' => '73ceef837b9be3cf098eca4a4697bd6a36718b64b0cf407c4324415941ff9780',
'va' => '0000002298436631',
'timestamp', '20191209155701'
];
$body = '{
"name": "Dudy",
"phone": "082298436631",
"email": "muhammadmaududy4#gmail.com",
"amount": "10000",
"notifyUrl": "https://mywebsite.com",
"expired": "24",
"expiredType": "hours",
"comments": "Catatan",
"referenceId": "1",
"paymentMethod": "qris",
"paymentChannel": "qris"
}';
$request = new Request('POST', 'https://sandbox.ipaymu.com/api/v2/payment/direct',
$headers, $body);
And i tried to do it on postman and its work perfectly, here's the setting on my postman:
You can use Laravel's Http Facade to deal with requests (easier to test later, if needed):
$headers = [];
$body = [];
$request = Http::send(
method: 'POST',
url: 'https://your.url/',
options: [
'headers' => $headers,
'form_params' => $body,
]
);
$response = Http::withHeaders([
'X-First' => 'foo',
'X-Second' => 'bar'
])->post('http://example.com/users', [
'name' => 'Taylor',
]);
I show a example code on top. I provide your code below.
$response = Http::withHeaders ([
'Content-Type' => 'application/json',
'signature' => '73ceef837b9be3cf098eca4a4697bd6a36718b64b0cf407c4324415941ff9780',
'va' => '0000002298436631',
'timestamp', '20191209155701'
])->post('https://sandbox.ipaymu.com/api/v2/payment/direct',[
"name": "Dudy",
"phone": "082298436631",
"email": "muhammadmaududy4#gmail.com",
"amount": "10000",
"notifyUrl": "https://mywebsite.com",
"expired": "24",
"expiredType": "hours",
"comments": "Catatan",
"referenceId": "1",
"paymentMethod": "qris",
"paymentChannel": "qris"
]);
Try this
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://sandbox.ipaymu.com/api/v2/payment/direct',
[
'form_params' => [
"name" => "Dudy",
"phone" => "082298436631",
"email" => "muhammadmaududy4#gmail.com",
"amount" => "10000",
"notifyUrl" => "https://mywebsite.com",
"expired" => "24",
"expiredType" => "hours",
"comments" => "Catatan",
"referenceId" => "1",
"paymentMethod" => "qris",
"paymentChannel" => "qris"
]
],
[
'headers' => [
'Content-Type' => 'application/json',
'signature' => '73ceef837b9be3cf098eca4a4697bd6a36718b64b0cf407c4324415941ff9780',
'va' => '0000002298436631',
'timestamp', '20191209155701'
]
]
);
dd($response) //response data

Laravel 8 - Get value from api json response

I am trying to get the value from 'title' in an API JSON response in Laravel 8.
{
"kind": "search#companies",
"page_number": 1,
"items_per_page": 20,
"total_results": 1,
"items": [
{
"kind": "searchresults#company",
"links": {
"self": "/company/13082103"
},
"title": "BITPIX LIMITED",
}
],
"start_index": 0
}
The call is setup and it works as expected but I am unsure how to get the variable.
The call will only ever return 1 response within items[] as the search is based on id.
Here is my method
$company = Auth::user()->companies()->first();
$apiKey = env("COMPANIES_HOUSE");
$query = $request->validate([
'query' => 'required',
]);
$response = Http::withHeaders([
'Authorization' => 'Basic ' . $apiKey,
'Connection' => 'keep-alive',
'Accept-Encoding' => 'gzip, deflate, br',
'Accept' => '*/*'
])->get('https://api.companieshouse.gov.uk/search/companies?q=' . $query['query']);
$data = json_decode($response->body());
//dd($data);
$provider = $company->providers()->create([
'name' => $data['items'][0]->title
]);
which produces this error:
Cannot use object of type stdClass as array relating to the ->create line
Many thanks for any help you can provide.
you have to decode the json you have recieved then extract the data you want:
$value = '{ "kind": "search#companies", "page_number": 1, "items_per_page": 20, "total_results": 1, "items": [{ "kind": "searchresults#company", "links": { "self": "/company/13082103" }, "title": "BITPIX LIMITED" }], "start_index": 0 }';
$decodeValue = json_decode($value);
$firstTitle = $decodeValue->items[0]->title; // first title is BITPIX LIMITED

How can i use php conditions inside json data?

Below is the code inside my CategoryResource.php
[
'id' => $this->id,
'name' => $this->name,
'categories' => CategoryResource::collection($this->children),
'items' => ItemListResource::collection($this->items)
];
and by this i am getting response like:
{
"status": true,
"data": {
"categories": [
{
"id": 10,
"name": "Fast Food",
"categories": [
{
"id": 11,
"name": "Pizza",
"categories": [],
"items": [
{
"id": 9,
"name": "Ham \u0026 Crab Stick",
"price": "20.00",
"image": "up/products/c11/Mrn4OpjngYRCkRJ28rJ1LbXUOXy0XjTRyXU7eFoi.jpg"
}
]
}
],
"items": []
}
]
}
}
i dont want "categories" : [] when category does not exist for a category.
please suggest some ideas or ways i can deal with this issue.
I assume that CategoryResource::collection($this->children) returns an array, maybe empty or not.
If that's true, then:
$dataArray = [
'id' => $this->id,
'name' => $this->name,
'items' => ItemListResource::collection($this->items)
];
$categories = CategoryResource::collection($this->children);
if (count(categories) > 0) $dataArray['categories'] = $categories;

Guzzle POST request always returns 400 Bad Request

I have been trying to make a simple POST request to an endpoint with a payload using Guzzle but I always get 400 Bad Request returned.
I can make the same request in Postman and it works. Also, If I make the request using cURL it works.
Can anyone tell from my code what I am doing wrong?
Here's the original cURL request:
curl "https://endpoint.com/" \
-H "Authorization: ApiKey pp_test_*********" \
--data '{
"shipping_address": {
"recipient_name": "Deon Botha",
"address_line_1": "Eastcastle House",
"address_line_2": "27-28 Eastcastle Street",
"city": "London",
"county_state": "Greater London",
"postcode": "W1W 8DH",
"country_code": "GBR"
},
"customer_email": "email£example.com",
"customer_phone": "123455677",
"customer_payment": {
"amount": 29.99,
"currency": "USD"
},
"jobs": [{
"assets": ["http://psps.s3.amazonaws.com/sdk_static/1.jpg"],
"template_id": "i6_case"
}, {
"assets": ["http://psps.s3.amazonaws.com/sdk_static/2.jpg"],
"template_id": "a1_poster"
}]
}'
And the Postman PHPHttp Request which works too.
<?php
$request = new HttpRequest();
$request->setUrl('https://endpoint.com/');
$request->setMethod(HTTP_METH_POST);
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Content-Length' => '678',
'Accept-Encoding' => 'gzip, deflate',
'Host' => 'api.kite.ly',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.19.0',
'Content-Type' => 'text/plain',
'Authorization' => 'ApiKey pk_test_*******'
));
$request->setBody(' {
"shipping_address": {
"recipient_name": "Deon Botha",
"address_line_1": "Eastcastle House",
"address_line_2": "27-28 Eastcastle Street",
"city": "London",
"county_state": "Greater London",
"postcode": "W1W 8DH",
"country_code": "GBR"
},
"customer_email": "email#example.com",
"customer_phone": "12345667",
"customer_payment": {
"amount": 29.99,
"currency": "USD"
},
"jobs": [{
"assets": ["http://psps.s3.amazonaws.com/sdk_static/1.jpg"],
"template_id": "i6_case"
}, {
"assets": ["http://psps.s3.amazonaws.com/sdk_static/2.jpg"],
"template_id": "a1_poster"
}]
}');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
But when I try to send make the same request with Guzzle it fails with 400 Bad Request and I can't understand why.
$data = [
"shipping_address" => [
"recipient_name" => "Deon Botha",
"address_line_1" => "Eastcastle House",
"address_line_2" => "27-28 Eastcastle Street",
"city" => "London",
"county_state" => "Greater London",
"postcode" => "W1W 8DH",
"country_code" => "GBR"
],
"customer_email" => "example#email.com",
"customer_phone" => "+44 (0)784297 1234",
"customer_payment" => [
"amount" => 29.99,
"currency" => "USD"
],
"jobs" =>
[
"assets" => ["http://psps.s3.amazonaws.com/sdk_static/1.jpg"],
"template_id" => "i6_case"
]
];
$options = json_encode($data);
$response = $client->request('POST', config('services.endpoint.com'),
['headers' => ["Authorization" => config('services.endpoint.com.public_key'),
'Content-Type' => "application/json"], $options]);
If anyone can help me to debug this I'd be really grateful.
If you're using Guzzle 6 (and you probably should be), you're actually constructing in a more complex way than you need to, such that the endpoint is not receiving the expected JSON. Try this instead:
$client = new Client([
'base_uri' => 'https://my.endpoint.com/api',
'headers' => [
'Accept' => 'application/json',
...other headers...
]
]);
$data = [...your big slab of data...];
$response = $client->post('/kitely/path', ['json' => $data]);
// a string containing the results, which will depend on the endpoint
// the Accept header says we will accept json if it is available
// then we can use json_decode on the result
$result = $response->getBody()->getContents();
I'm using Unirest to make any sort of HTTP requests. I tried using Guzzle, but was facing the same issue as you are.
So what I did was install Unirest in my project, all the process are given in details in their documentation. This works perfectly fine for me.

Missing Request Body using Guzzle 6 in Laravel 5.7 working over Sage API 3.1

According to the SAGE API 3.1 manual, to create an invoice you must pass the following:
POST /sales_invoices
Content-Type: application/json
Accept: */*
{
"sales_invoice": {
"contact_id": "14d93840783b11e8990a122c8428e4b2",
"date": "2018-06-24",
"invoice_lines": [
{
"description": "A Minimal Invoice Item",
"ledger_account_id": "4195173e75db11e8990a122c8428e4b2",
"quantity": "1",
"unit_price": "0.99",
"tax_rate_id": "584793ca75db11e8990a122c8428e4b2"
}
]
}
}
Well, On my code
$client = new Client();
$endpoint = $this->endpoint.'/'.$this->action; // https://api.accounting.sage.com/v3.1/sales_invoices
$response = $client->post($endpoint, [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$this->token // My token valid
],
'form_params' => $this->params
]);
My params
"sales_invoice" => array:3 [
"contact_id" => "a39b46d1cb8a4f5a9048c32f7895147c"
"date" => "2018-03-04"
"invoice_lines" => array:1 [
0 => array:5 [
"description" => "Factura creada por error"
"ledger_account_id" => "49131457ee4f11e8ae720268dc652fba"
"quantity" => "1"
"unit_price" => "0"
"tax_rate_id" => "ES_EXEMPT"
]
]
]
]
And Guzzle extended error show problems in sales_invoice[invoice_lines] that missings values.
[{
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines] is invalid",
"$source": "sales_invoice[invoice_lines]"
}, {
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines] is invalid",
"$source": "sales_invoice[invoice_lines]"
}, {
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines] is invalid",
"$source": "sales_invoice[invoice_lines]"
}, {
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines][0][description] is missing",
"$source": "sales_invoice[invoice_lines][0][description]"
}, {
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines][0][ledger_account_id] is missing",
"$source": "sales_invoice[invoice_lines][0][ledger_account_id]"
}, {
"$severity": "error",
"$dataCode": "Validation",
"$message": "sales_invoice[invoice_lines][0][unit_price] is missing",
"$source": "sales_invoice[invoice_lines][0][unit_price]"
}]
What is wrong on this code?
Instead of sending it via form_params, send the payload as json:
$response = $client->post($endpoint, [
'headers' => [
'Authorization' => 'Bearer '.$this->token // My token valid
],
'json' => $this->params
]);
The content type header application/json is added automatically.

Resources