4

I'm trying to use the files.upload method to upload a file to Slack, but I only got a blank message so far.

This is the code, I found this script on the internet, but it's not working.

<?php
include '../connessione.php';

$slacktoken = "myToken"; //this is not the real token ofc
$header = array();
$header[] = 'Content-Type: multipart/form-data';
$file = new CurlFile('../tmp/slack_icon.png', 'image/png');

$postitems =  array(
    'token' => $slacktoken,
    'channels' => "test_channel",
    'file' =>  $file,
    'text' => "This is my photo",
    'title' => "Photo title",
    'filename' => "myIcon.jpg"
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "https://slack.com/api/files.upload");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS,$postitems);

//Execute curl and store in variable
$data = curl_exec($curl);
?>

What am I doing wrong?

Thank you.

Edit: after lots of tests I got this message if I echo the $data variable:

{"ok":false,"error":"missing_scope","needed":"files:write:user","provided":"identify,commands"}

UPDATE I'll post here the full working code.

<?php
include '../connessione.php';

    // Buffer all upcoming output...
    ob_start();

    // Send your response.
    echo "Here be response";

    // Get the size of the output.
    $size = ob_get_length();

    // Disable compression (in case content length is compressed).
    header("Content-Encoding: none");

    // Set the content length of the response.
    header("Content-Length: {$size}");

    // Close the connection.
    header("Connection: close");

    // Flush all output.
    ob_end_flush();
    ob_flush();
    flush();

    // Close current session (if it exists).
    if(session_id()) session_write_close();


$channel = $_POST['channel_id'];
$slacktoken = "myToken";
$header = array();
$header[] = 'Content-Type: multipart/form-data';
$file = new CurlFile('slack_icon.png', 'image/png');



$postitems =  array(
        'token' => $slacktoken,
        'channels' => "test_channel",
        'file' =>  $file,
        'text' => "This is my photo",
        'title' => "Photo title",
        'filename' => "myIcon.jpg"
    );

$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_URL, "https://slack.com/api/files.upload");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $postitems);

//Execute curl and store in variable
$data = curl_exec($curl);
?>

The initial part is taken from this continue processing php after sending http response. That's needed to send an immediate answer back to Slack and avoid the "Timeout was reached" message.

Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
DoomWZ
  • 53
  • 1
  • 6
  • 1
    Welcome! Unfortunatly we won’t be able to help you without an error message. If you’re getting a blank screen, trying removing the `?>` from the end of your page and trying again. Make sure you have [error reporting turned on](https://secure.php.net/manual/en/function.error-reporting.php). Otherwise we have no idea what the problem might be. Good luck! – Zoe Edwards Nov 09 '18 at 15:59
  • @ThomasEdwards Hello! I have the error reporting turned on, but I'm still getting a blank screen if I go to the webpage. I also tried to remove the `?>`, but nothing. – DoomWZ Nov 09 '18 at 16:08
  • If I run the script through the slash command I get a blank message from my slack app – DoomWZ Nov 09 '18 at 16:09
  • Obviously your token does not have the required scopes: you need to add `files:write:user` scope to your token – Erik Kalkoken Nov 09 '18 at 17:29
  • @ErikKalkoken How do i do that? – DoomWZ Nov 09 '18 at 17:31

1 Answers1

3

Missing scopes

You token is missing the necessary scopes, here: files:write:user.

To add additional scopes:

Assuming you have a Slack app, go to the management page for your app and then add it on the "Ouath" sub page there is a scope section where you can add it. here is a direct link to your apps: https://api.slack.com/apps.

After that you need to re-install your app to the workspace, so the changes become active.

Working with CurlFile

Another potential pitfall is that CurlFile apparently only works with absolute paths to your file. (see this answer). A quick fix would be something like this:

$file = new CurlFile(realpath(dirname(__FILE__) . '/../tmp/slack_icon.png'), 'image/png');

Erik Kalkoken
  • 30,467
  • 8
  • 79
  • 114
  • I created a bot user and now I have another OAuth token. Using this new token now I get this `{"ok":false,"error":"no_file_data"}` – DoomWZ Nov 09 '18 at 17:38
  • 1
    Alright, now I get this `{"ok":true,"file":{"id":"FDZF1LH0R","created":1541785891,"timestamp":1541785891,"name":"myIcon.jpg".....` I cut all the string cause it's too long, but it seems like it's working, but if I run it through slack slash command I get a Timeout – DoomWZ Nov 09 '18 at 17:54
  • Cool. Then I would say the initial question has been answered. How to work with the 3 second timeout on slash commands it a whole other topic. and already answered here: https://stackoverflow.com/questions/36195924/slack-php-api-avoid-timeout-error/42272824#42272824 – Erik Kalkoken Nov 09 '18 at 18:00
  • I tried to add `ignore_user_abort(true); ob_start(); echo('{"response_type": "in_channel", "text": "Checking, please wait..."}'); header($_SERVER["SERVER_PROTOCOL"] . " 200 OK"); header("Content-Type: application/json"); header('Content-Length: '.ob_get_length()); ob_end_flush(); ob_flush(); flush();` But it still gives me a timeout error. However the uploads works and the file shows on the slack anyway. So not it's just a matter of details – DoomWZ Nov 09 '18 at 18:08
  • I never got it to work with the buffer capture approach (ob_start(), ..) either. But check the question I linked for the curl based approach. That one works great. – Erik Kalkoken Nov 09 '18 at 18:10
  • Will try that. Thank you! – DoomWZ Nov 09 '18 at 18:13