Skip to main content

How to validate a Monday.com Webhook in PHP

  • August 27, 2019
  • 21 replies
  • 11192 views

  • Participating Frequently

Is there any one here that can display a PHP script example to validate a monday.com webhook and make it work.

I am stuck at sending the response back to the http post request to validate the webhook url.

This topic has been closed for replies.

21 replies

dipro
Forum|alt.badge.img
  • Leader
  • September 20, 2019

Hey Frank!

Dipro here – what have you got so far? I don’t have a PHP example for this, but would a Node.js example help you understand the logic?

Cheers,
Dipro


primetheus
  • New Participant
  • January 13, 2020

@dipro That would certainly help me…


  • Author
  • Participating Frequently
  • February 22, 2020

Yes I would like to see the Node.js example


robzinn
  • New Participant
  • March 5, 2020

Seriously… The documentation of this feature is horrible. The guide even has major grammatical mistakes which is just lazy. I guess this feature is not that important to the dev team? It’s up to us to figure out how to integrate? rude!

Too bad because Monday.com Webhooks would basically eliminate the barriers many developers face in beating their workflows into the Monday.com box.

I have no idea about Node.js but below is how far I’ve gotten with PHP… still working on how to actually validate the “challenge” JSON.

context:

  • I have a file called webhooks_processor.php on our company website.
  • that file logs POST requests to an error file called “webhook.log” that is also on our server so I can see what the heck monday.com webhooks are sending.
  • not to overstate the obvious (because it was not to me at first) but at the Board > Integrations > webhooks > “When a column changes, send a webhook” > WebhookURL Prompt, I am entering the url of my webhooks_processor.php file.

code:

So far, all I can get is boolean return of “TRUE” out of this. However, I have no idea if I am a accurately directing the validation response because its not mentioned in the webhook documentation! Now I’m sending it to: https://api.monday.com/v2/ but I don’t know. This is not really an API feature.

<?php

// set a timestamp for tracking events in the log file
$now = date("Y.m.d @ G:i");

//capture the monday.com webhook challenge as a php object
$challenge_received = json_decode($GLOBALS['HTTP_RAW_POST_DATA'])->challenge;

// write the challenge to a log file for debugging
error_log("$now: JSON challenge: $challenge_received\\n", 3, "webhook.log");

// prepare JSON response
$challenge_response = json_encode($challenge_received);

// initiate cURL
$ch = curl_init("https://api.monday.com/v2/");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $challenge_response);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));

// execute the request
$result = curl_exec($ch);

// execute the request
$result = curl_exec($ch);

// inspect result
if ($result === FALSE) {
    error_log("$now: the result object returned FALSE\\n", 3, "webhook.log");
} else {
    error_log("$now: response to challenge validation attempt: $result\\n", 3, "webhook.log");
}
?>

I hope this helps and we can move this forward somehow.


  • monday club member
  • March 5, 2020

@robzinn, here’s my PHP code to authorize it.

if ($request->has('challenge')) {
     return response()->json(['challenge' => $request->input('challenge')]);
} 

This example is part of a Laravel app but you should be returning the json_encoded challenge as a reply to the POST.


robzinn
  • New Participant
  • March 7, 2020

Thanks @darren. I have no idea what Laravel is but could you share or direct me to more of the code from your example? I can capture the challenge and send it back but to where!? sending it to

$ch = curl_init("https://api.monday.com/v2/");

was just a hunch based on the API documentation and must be wrong.

I’ve tried sending it to

$_SERVER['REMOTE_ADDR']

Which is the only header I could find coming in from the webhook that might be a remote address, but it was an IP address, not a URL.

Perhaps I am missing something… can you just call “respond” to a POST somehow in PHP and send back a response without knowing the actual address?


robzinn
  • New Participant
  • March 7, 2020

Update: Now seeing this error in the JS console:

Access to XMLHttpRequest at ‘https://api-gw.monday.com/automations/automations’ from origin ‘https://mymnodayspace.monday.com’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

I think this means monday.com servers are not setup for CORS correctly as both requests are on the same domain.


  • Author
  • Participating Frequently
  • March 7, 2020

I finally figured it out. The documentation could have been better explained
because it’s quite simple if you explained it better. Below is the simple code I figured out

after trying to send back to a url. It is a simple echo to send back the challenge.

<?php //grab the challenge sent by Monday.com $challenge = file_get_contents('php://input'); //echo back the challenge echo $challenge; ?>

robzinn
  • New Participant
  • March 7, 2020

OMG seriously! Thank you so much @renow! If only I had the last 3 days back! 😉

Great, I will keep working and post any additional insights.


  • Participating Frequently
  • March 9, 2020

@renow thank you for posting this! Is there anything else that needs to be included? I tried:

<?php
$challenge = file_get_contents('php://input'); 
echo $challenge; 
?>

but I get a failed to communicate with URL error. Does it need to be encoded?


  • monday club member
  • March 9, 2020

@mru if Monday sends 1234 as the challenge then you need to return this:

{“challenge”:“1234”}


  • Participating Frequently
  • March 10, 2020

@darren thank you for the response. I understand that I need to return the challenge but for some reason it keeps getting denied when I try to link the integration. I have it formatted exactly how you have it and I’ve verified that I am getting a challenge.


  • Author
  • Participating Frequently
  • March 10, 2020

@mru are you using a secure url? It has to be a “https://example.com” url.


  • monday club member
  • March 10, 2020

If @mru is seeing the webhook hitting his system then I’d guess he must be using a secure url. @mru are you returning it with Content-Type set to application/json? I don’t know if it’s mandatory but that’s how I’m returning it.


  • Participating Frequently
  • March 10, 2020

@renow yes the server is https. @darren I’ve tried with and without. It should be this shouldn’t it? Sorry PHP isn’t my strong suit.
header('content-type: application/json');
I’ve been logging the request to verify the format and it is: {“challenge”:“1234”}. I know with GraphQL we have to escape special characters but I’m assuming it isn’t the case here.


Does anyone have suggestion for node.js I’ve tried everything: exports.handler = event => {
console.log( {“challenge”: JSON.parse(event.body).challenge});
const response = {
statusCode: 200,
body: JSON.parse(event.body)

};
console.log(response);
return response;
};


Finally got it to work. Below is my index.js file using node.js

exports.handler = async event => {
  console.log( {"challenge": JSON.parse(event.body).challenge});
  const response = {
    statusCode: 200,
    body: event.body
    
  };
  console.log(response);
  return response;
};

dipro
Forum|alt.badge.img
  • Leader
  • April 13, 2020

Spoke to @mru about this issue – looks like rebuilding the challenge as a new JSON object was his solution:

<?php

$data = json_decode(file_get_contents('php://input'), true);

$message = [

"challenge" => $data["challenge"]

];

file_put_contents("response1.log", print_r(json_encode($data), true));

header('content-type: application/json');

echo json_encode($message);

?>

  • Participating Frequently
  • July 16, 2020

Can you explain more,it would be helpful


So it really depends what you’d like to do from there. But to access the data passed in the webhook declare a variable like this : const data = JSON.parse(event.body).event This will give you the data being passed in the trigger. To call back to Monday do something like this
//create and fill request for Monday call
const body = {
query: query ($itemId:[Int], $boardId:[Int]){ boards(ids: $boardId) { items(ids:$itemId){ name column_values(){ id title text } } } } ,
variables: {
boardId: data.boardId,
itemId: data.pulseId
}
}
const responseItem = await axios
.post(https://api.monday.com/v2, body, {
headers: {
Authorization:
‘AUTHORIZATION CODE GOES HERE’
}
})
.catch(err => {
console.log(err)
})
.then(res => {
console.log(‘response’, res.data.data.boards[0])
return res.data.data.boards[0].items[0]
})
We are using axios to structure the POST call. I hope this helps.


  • Participating Frequently
  • July 17, 2020

Thanks @hilaryMatusiak It helps and makes everything a lot clear. 😊