Sunday, April 24, 2016

Slack PHP API - Avoid Timeout error

1 comment

I am trying to use Slack Custom command and not pretty sure how to use delayed messages since the Yoda Speak External API takes more than 3 seconds to respond.

I have done the following:

  • Sent the slack command /Yoda in my case and received the reponse_url.
  • Used the following to post the following to the response URL.
$data_string = '{"response_type": "in_channel", "text":"Checking,please wait..."}' ; $chs = curl_init(); curl_setopt($chs, CURLOPT_URL, $response_url); curl_setopt($chs, CURLOPT_POST, true); curl_setopt($chs, CURLOPT_POSTFIELDS, $data_string);  curl_setopt($chs, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($chs, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($chs, CURLOPT_RETURNTRANSFER, true); curl_setopt($chs, CURLOPT_POST, 1); curl_setopt($chs, CURLOPT_HTTPHEADER, array('Content-Type:application/json')); $results = curl_exec($chs); 

enter image description here

  • Now, when I call the Yoda API, it gives the following error "Timeout was reached". I read about delayed responses but not sure how should I proceed from here.
$chsres = curl_init(); curl_setopt($chsres, CURLOPT_URL, "https://yoda.p.mashape.com/yoda?sentence=welcome+to+stack"); curl_setopt($chsres, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($chsres, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($chsres, CURLOPT_VERBOSE, true); curl_setopt($chsres, CURLOPT_TIMEOUT, 45); curl_setopt($chsres, CURLOPT_RETURNTRANSFER, true); curl_setopt($chsres, CURLOPT_HTTPHEADER, array('Content-Type:application/json', "X-Mashape-Key:> deMeGoBfMvmshQSemozTqJEY9z0jp1eIhuAjsnx9cQAQsHUifD")); $resultchsres = curl_exec($chsres); echo $resultchsres; 

Can someone please let me know how to get rid of the timeout error using delayed responses?

UPDATED CODE:

$response_url = $_POST['response_url']; $text = $_POST['text'];  $term = str_replace(' ', '+', $text);  //https://paypal.slack.com/services/B0VQMHX8W#service_setup //initial respond with 200OK for timeout ignore_user_abort(true); set_time_limit(0); 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();       $chsres = curl_init();     curl_setopt_array($chsres, array(         CURLOPT_URL => "https://yoda.p.mashape.com/yoda?sentence=$term",         CURLOPT_SSL_VERIFYPEER => FALSE,         CURLOPT_SSL_VERIFYHOST => FALSE,         CURLOPT_VERBOSE => true,         CURLOPT_RETURNTRANSFER => FALSE,         CURLOPT_HTTPHEADER => array('Content-Type:application/json', "X-Mashape-Key: deMeGoBfMvmshQSemozTqJEY9z0jp1eIhuAjsnx9cQAQsHUifD"),         CURLOPT_RETURNTRANSFER => true     ));     $yodaresponse = curl_exec($chsres);      $curl = curl_init();     curl_setopt_array($curl, array(         CURLOPT_URL => $response_url,         CURLOPT_POST => 1,         CURLOPT_RETURNTRANSFER => true,         CURLOPT_POSTFIELDS => $yodaresponse     ));      $resp = curl_exec($curl);     var_dump($resp);     curl_close($curl); 

I still get the same error "Darn – that slash command didn't work (error message: Timeout was reached). Manage the command at slash-command"

2 Answers

Answers 1

You're doing all the right things, just need to change the order.

  1. Respond to the original request with a 200 OK response immediately. See this answer for details, but essentially:

    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(); 
  2. Then make the Yoda API request using curl, as you're doing

  3. Once you have the Yoda results, send them to Slack at $response_url using curl, as you're doing.

Answers 2

From what I can see in the documentation, you're doing things mostly correctly. Just by echoing anything out, you're already passing a 200 OK message, so no need to do it explicitly. You should check to make sure this isn't a server problem though; is the URL being posted to valid? Not getting mangled by a rewrite rule along the way?

I've made some changes to your code below, including some debugging that will go to your error log (i.e. Apache's error log, by default.) Give it a try, and at the very least you'll have some more debugging details.

<?php $response_url = $_POST["response_url"]; $term = rawurlencode($_POST["text"]); error_log("POST: " . print_r($_POST, 1));  ob_end_clean(); ob_start(); $response = ["response_type"=>"in_channel", "text"=>"Checking, please wait..."]; echo json_encode($response); header("Content-Type: application/json"); header("Content-Length: " . ob_get_size()); ob_end_flush(); flush();  $ch = curl_init(); curl_setopt_array($ch, [     CURLOPT_URL => "https://yoda.p.mashape.com/yoda?sentence=$term",     CURLOPT_HTTPHEADER => ["X-Mashape-Key: deMeGoBfMvmshQSemozTqJEY9z0jp1eIhuAjsnx9cQAQsHUifD"],     CURLOPT_RETURNTRANSFER => true ]); $yodaresponse = curl_exec($ch); curl_close($ch); error_log("Yoda response: $yodaresponse");  $yodajson = json_encode([     "response_type"=>"in_channel",     "text"=>$yodaresponse ]); $ch = curl_init(); curl_setopt_array($ch, [     CURLOPT_URL => $response_url,     CURLOPT_POST => 1,     CURLOPT_HTTPHEADER => ["Content-Type: application/json"],     CURLOPT_RETURNTRANSFER => true,     CURLOPT_POSTFIELDS => $yodajson ]);  $resp = curl_exec($ch); curl_close($ch); error_log("API response: $resp"); 
If You Enjoyed This, Take 5 Seconds To Share It

1 comment:

  1. Another great post on Blogspot.com. Thanks a lot, man!!!! All the tips given by you are extremely useful when it comes to blogging. I agree with you that not being able to write regularly is not a big problem. We're doing the same thing, and you can check out our blog to see what we're doing. Brief description of Slack Native App. I need to try new things and learn. Anyway, that was a great post; keep doing good work. Best wishes

    ReplyDelete