Slack sends invalid, mal-formed JSON data after Dialog interaction - php

I am working on a slash command that'll invoke a dialog.
$dialog = [
'callback_id' => 'ryde-46e2b0',
'title' => 'Request a Ride',
'submit_label' => 'Request',
'elements' => [
[
'type' => 'text',
'label' => 'Pickup Location',
'name' => 'loc_origin'
],
[
'type' => 'text',
'label' => 'Dropoff Location',
'name' => 'loc_destination'
]
]
];
// get trigger ID from incoming slash request
$trigger = filter_input(INPUT_POST, "trigger_id");
// define POST query parameters
$query = [
'token' => 'XXXXXXXXX MY TOKEN XXXXXXXXX',
'dialog' => json_encode($dialog),
'trigger_id' => $trigger
];
// define the curl request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/dialog.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
// execute curl request
$response = curl_exec($ch);
// close
curl_close($ch);
var_export($response);
When I issue the slash command, my test dialog opens successfully
I then fill two test values test1 and test2 in the fields and submit the request. My endpoint is being hit with the dialog data payload correctly, but the data sent is not valid JSON:
The value of $_POST is: (I've masked all identifying tokens/IDs with xxx)
{"payload":"{\\\"type\\\":\\\"dialog_submission\\\",\\\"token\\\":\\\"XXX\\\",\\\"action_ts\\\":\\\"1536603864.688426\\\",\\\"team\\\":{\\\"id\\\":\\\"xxx\\\",\\\"domain\\\":\\\"ourdomain\\\"},\\\"user\\\":{\\\"id\\\":\\\"xxx\\\",\\\"name\\\":\\\"my_name\\\"},\\\"channel\\\":{\\\"id\\\":\\\"xxx\\\",\\\"name\\\":\\\"directmessage\\\"},\\\"submission\\\":{\\\"loc_origin\\\":\\\"test1\\\",\\\"loc_destination\\\":\\\"test2\\\"},\\\"callback_id\\\":\\\"ryde-46e2b0\\\",\\\"response_url\\\":\\\"https:\\\\/\\\\/hooks.slack.com\\\\/app\\\\/XXX\\\\/XXX\\\\/XXX\\\",\\\"state\\\":\\\"\\\"}"}
This is an invalid JSON, even when the "\\" instances are removed. Why is this happening?
Here is the code that handles the POST from Slack:
error_log(" -- dialog response: " . json_encode($_POST) . "\n", 3, './runtime.log');
Which results in the output above.

I'm not sure why you are calling json_encode($_POST). The documentation is very clear on the format that will be sent:
$payload = filter_input(INPUT_POST, 'payload');
$decoded = json_decode($payload);
var_dump($decoded);

Related

Migration of Slack app which uses event api (HTTP end-point) to Slack Socket Mode

I have implemented a Slack app using PHP(HTTP-endpoint). Under slack slash commands, I have inserted the request URL (HTTP end-point which points to the code I have written in PHP to open a Slack Modal ) that opens a dialogue box (Slack Modal). And upon submitting the form it will go to GitHub, that I have inserted the URL of my code written in PHP under request URL in interactivity and shortcuts(Payload).
But due to security measures, I want to migrate the app to socket mode. Can someone please let me know how to implement the socket mode for PHP in my local VM?
This is code to open a dialog box in slack
<?php
$slack_token = 'xoxb-******************';
// Dialog Form:
$dialog = [
'callback_id' => 'git_issue',
'title' => 'Add issue',
'submit_label' => 'Create',
'elements' => [
[
'type' => 'text',
'label' => 'Name',
'name' => 'name'
],
[
'type' => 'text',
'label' => 'E-mail',
'name' => 'email'
],
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/dialog.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
// execute curl request
$response = curl_exec($ch);
How to migrate the application to socket mode?
Thanks in Advance
I use this own-written code. May be it is not perfect, but it works:
<?php
require 'vendor/autoload.php';
// Slack config:
$slack_token = 'xapp-*';
$bot_token = 'xoxb-*';
$url = false;
$dialog = [
'callback_id' => 'git_issue',
'title' => 'Add new GitHub Issue',
'submit_label' => 'Create',
'elements' => [
[
'type' => 'text',
'label' => 'Developer\'s Name',
'name' => 'name'
],
]
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/apps.connections.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded',
'Authorization: Bearer '.$slack_token
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
// execute curl request
$response = curl_exec($ch);
// close
curl_close($ch);
if ($response) {
$resp = json_decode($response);
if (isset($resp->url)) {
$url = $resp->url;
}
}
if ($url) {
echo 'Slack returned the websocket URL'.PHP_EOL;
$client = new WebSocket\Client($url, ['timeout' => 3600]);
while (true) {
try {
$message = $client->receive();
echo $message.PHP_EOL.PHP_EOL;
if ($message) {
$data = json_decode($message);
if (isset($data->payload)) {
if (isset($data->payload->command) && $data->payload->command == '/git') {
// Open Dialog:
// define POST query parameters
$query = [
'token' => $bot_token,
'dialog' => json_encode($dialog),
'trigger_id' => $data->payload->trigger_id,
];
// define the curl request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/dialog.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
// execute curl request
$response = curl_exec($ch);
// close
curl_close($ch);
$query = [
'envelope_id' => $data->envelope_id
];
$client->text(json_encode($query));
// -----------
}
if (isset($data->payload->type) && $data->payload->type == 'dialog_submission') {
// collect submitted data:
$name = $data->payload->submission->name;
$query = [
'envelope_id' => $data->envelope_id,
];
$client->text(json_encode($query));
}
}
}
} catch (\WebSocket\ConnectionException $e) {
// Possibly log errors
var_dump($e);
}
}
$client->close();
}
Configure your Slack app and create tokens:
go to https://api.slack.com/apps page and select existed one or
create a new app
go to "basic information" page, find "App-Level
Tokens" section. Create a new token. I use these scopes
"connections:write, authorizations:read" for it
go to "OAuth & Permissions" page and generate "Bot User OAuth Token"
go to "slash commands" page and create a command. In my code example we have it with the name "/git"
go to "Socket Mode" page and enable the mode with a slide button
For websockets connection via PHP I use this Textalk/websocket-php realization from GitHub.

send multiple json data into api

I want to send these three array data into the external api. For that firstly I encode this into JSON, but always it sends the last array.
$params = array( array('receiverName' => 'sample_name',
'receiverEmail' => 'krishanuniyalas#gmail.com',
'senderEmail' => 'info#hotelpalacio.net',
'roomNumber' => '12456',
'accessToken' =>'ca5629d0-6810-11e8-9d40-d7194ac0ac8d'),array('receiverName' => 'sample_name',
'receiverEmail' => 'karamuniyalas#gmail.com',
'senderEmail' => 'info#hotelpalacio.net',
'roomNumber' => '12456',
'accessToken' =>'ca5629d0-6810-11e8-9d40-d7194ac0ac8d'),array('receiverName' => 'sample_name',
'receiverEmail' => 'krishanuniyalas#gmail.com',
'senderEmail' => 'info#hotelpalacio.net',
'roomNumber' => '12456',
'accessToken' =>'ca5629d0-6810-11e8-9d40-d7194ac0ac8d'));
$data_string = json_encode($params);
foreach($params as $pa) {
$r=json_encode($pa);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $r);
Here 's a working example ...
$data = [
[
'a' => 'bla',
],
[
'b' => 'blubb',
],
];
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, "http://www.example.com/");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$result = [];
foreach ($data as $value) {
$json = json_encode($value);
curl_setopt($handle, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($json),
]);
$result[] = curl_exec($handle);
}
Open a valid curl resource and set the corresponding curl options for your purpose. You want to send a json string as post request. Furthermore you should tell the other side, that you send json data. Say curl, that you 're awaiting a response and the fire every time running through the foreach loop. That 's all ...
If you want to send the whole data at once leave out the foreach loop end encode the whole data array and send it.
You need to just create a simple query params like $data = http_build_query($params)
And then pass data to your curl_setopt($ch,CURLOPT_POSTFIELDS,$data);

Slack Message Dialog's Curl Call

can anyone please give me an example of slack message dialog in PHP? How to make curl call to dialog.open method? Please suggest.
Here is a simple example in PHP of how to create a Dialog based on a slash command.
Note that you need to create and install a Slack App first. You also need to add a slash command to your Slack app, which needs to call this script. Finally you need to manually add the OAuth Access Token from your Slack app to this script (replace YOUR_TOKEN).
The script will print the API response in the Slack channel, so you can the response and if they are any errors.
Execute the slash command to run the dialog.
// define the dialog for the user (from Slack documentation example)
$dialog = [
'callback_id' => 'ryde-46e2b0',
'title' => 'Request a Ride',
'submit_label' => 'Request',
'elements' => [
[
'type' => 'text',
'label' => 'Pickup Location',
'name' => 'loc_origin'
],
[
'type' => 'text',
'label' => 'Dropoff Location',
'name' => 'loc_destination'
]
]
];
// get trigger ID from incoming slash request
$trigger = filter_input(INPUT_POST, "trigger_id");
// define POST query parameters
$query = [
'token' => 'YOUR_TOKEN',
'dialog' => json_encode($dialog),
'trigger_id' => $trigger
];
// define the curl request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://slack.com/api/dialog.open');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// set the POST query parameters
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($query));
// execute curl request
$response = curl_exec($ch);
// close
curl_close($ch);
var_export($response);

How to call a REST API in laravel 5.4

I have developed a laravel project in which I want to call a REST API to pass a form inputs to it by the use of CURL. After submitting a form by user, form data are passed to a controller, then API is called but I receives false or null as response.
The data must be sent to API as below, as you see the data must be a json in an array(image is not a file, it is a path):
[{
'title' : 'title',
'body' : 'description',
'source' : 'http://www.google.com',
'date' : 1503845107465,
'active' : true,
'image' : '758.jpg',
'category' : [
1
]
}];
here is a part of my controller, $data is build out of form inputs.
$data = [
'title' => 'title',
'body' => 'description',
'source' => 'http://www.google.com',
'date' => 1503845107465,
'active' => true,
'image' => '758.jpg',
'category' => [
1
]
];
$curl=curl_init('http://x.x.x.x/rest/test');
$send = json_encode([$data]);
//return $send;
//curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
curl_setopt($curl, CURLOPT_POSTFIELDS, $send);
try{
$res = curl_exec($curl);
}catch (Exception $e){
return $e->getMessage();
}
dd($res);
$res is false.
It must be mentioned that the code in controller works on localhost but it does not work on linux server.
I also used ixudra/curl but it does not solve my problem and it returns null.
I got this error Failed to connect to x.x.x.x Permission denied. I can ping this url and I can send data with curl to this IP in a php file. but in laravel I get this error

Square API Create Item working code now returning an error

After creating about 1000 inventory items with code, Square suddenly started returning an error.
The error returned was:
{"type":"bad_request","message":"'name' is required"}
Example code:
$postData = array(
'id' => 'test_1433281486',
'name' => 'test',
'description' => 'test',
'variations' => array(
'id' => 'test_v1433281486',
'name' => 'Regular',
'price_money' => array(
'currency_code' => 'USD',
'amount' => '19800',
),
),
);
$json = json_encode($postData);
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Authorization: Bearer ' . $access_token, 'Content-Type: application/json', 'Accept: application/json'));
curl_setopt($curl, CURLOPT_URL, "https://connect.squareup.com/v1/me/items");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLOPT_VERBOSE, TRUE);
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
$json = curl_exec($curl);
curl_close($curl);
Here is the json_encoded string:
{
"id":"test_1433281486",
"name":"test",
"description":"test",
"variations": {
"id":"test_v1433281486",
"name":"Regular",
"price_money": {
"currency_code":"USD",
"amount":"19800"
}
}
}
I have tried everything I know to do a simple Create Item with code now, but it no longer works. Always returns the message "name" is required. My code to update images, fees, categories etc still works perfectly - just can't create.
I still have 100's of new inventory items to add, so getting this to work is imperative to business.
Variations needs to be passed in as an array. Here is how the JSON should look:
{
"id":"test_1433281486",
"name":"test",
"description":"test",
"variations": [{
"id":"test_v1433281486",
"name":"Regular",
"price_money": {
"currency_code":"USD",
"amount":"19800"
}
}]
}
Thanks for the report! We will update our error messaging to send the proper message if variations is not passed in as an array.
This is for all the PHP developers. Here is an updated Create Item PHP array that is compatible with Square. Notice the nested "variations" arrays.
Square now (6/15) requires brackets in JSON arrays - PHP json_encode() does not produce them unless you add nested arrays.
$postData = array(
'id' => 'test_1433281487',
'name' => 'test2',
'description' => 'test2',
'variations' => array(array(
'id' => 'test_v1433281487',
'name' => 'Regular',
'price_money' => array(
'currency_code' => 'USD',
'amount' => '19800',
),
)),
);
$json = json_encode($postData);
Here's another example of JSON brackets in PHP.
Here is the PHP json_encode() documentation.

Categories