How to create a webhook in Asana

Hi Team,

I tried to create a webhook on asana in C# .net. I created a HTTP post request using the following code.

var client = new RestClient(“https://app.asana.com/api/1.0/webhooks”);
var request = new RestRequest(Method.POST);
request.AddHeader(“content-type”, “application/x-www-form-urlencoded”);
request.AddHeader(“authorization”, “Bearer key”);
request.AddParameter(“application/x-www-form-urlencoded”,
“resource = resource_id (id of the resouces task or project)& target = https://campaignhero.app/admin/api/messenger/TargetWebHook”,
ParameterType.RequestBody);

I debugged with this method on local machine and the resposnse I received was 204

What caused this reponse. How can I create the webhook regarding this.

Hi :wave:
Did you have a look at the other posts about webhook creation in the community? That might help.

Yes. I saw that. and I wrote the code accordingly. It says that to create a webhook I need to make a httppost request to “https://app.asana.com/api/1.0/webhooks” url. I also need to mention the Target url. I specified the target url also. I also specified the project_id from my asana account. I created a function in the .Net MVC application and triggered it on local environment but I received the response as 204 (No content) and also I did not receive any X-Hook-Secret key in the response. Could you please help.

I think it only works with an HTTPS address… :thinking: @Phil_Seeman isn’t that right?
The target URL you are giving to Asana, it is available online publicly right?

Yes, the target url is available in publicly

With https?

Yes. It is available with https.

Then @Phil_Seeman is the man, he is the expert!

@Phil_Seeman could you please help me with this.

Hi @Swapnil.G,

I don’t use RestSharp, but try these changes.

Try setting your authorization header like this instead:

request.AddParameter("Authorization", string.Format("Bearer " + access_token),
            ParameterType.HttpHeader);

Then try adding resource and target as separate parameters:

request.AddParameter("resource", resource_id, ParameterType.GetOrPost);
request.AddParameter("target", "https://campaignhero.app/admin/api/messenger/TargetWebHook", ParameterType.GetOrPost);
1 Like

@Swapnil.G @Bastien_Siebman @Marie

Also FYI I moved this thread to the Developers & API forum section.

1 Like

Hi @Phil_Seeman

Can you help me with the code I should write in the Target url of my domain.

Please find the current code I have written.

public HttpResponseMessage TargetWebHook()//Stream data
{
//TODO
Log(“Target WebHook started”);
var headers = Request.Headers;
HttpResponseMessage _response = new HttpResponseMessage();
Log(“Target WebHook started” + headers.ToString());
if (headers.Authorization.Parameter.Contains(“X-Hook-Secret”))
{
var key = headers.Authorization.Parameter[0];
Log(key.ToString());
_response.Headers.Add(“X-Hook-Secret”, key.ToString());
_response.StatusCode = HttpStatusCode.OK;
}
return _response;//Json(“OK”, JsonRequestBehavior.AllowGet);

    } 

Is this correct

I do it a bit differently. I’m not saying your code won’t work - I wouldn’t be able to say for sure without testing it - but here’s what I do:

            string xHookSecret = req.Headers.FirstOrDefault(x => x.Key == "X-Hook-Secret").Value?.FirstOrDefault();
            if (xHookSecret != null && xHookSecret.Length > 0)
            {
                var resp = req.CreateResponse(HttpStatusCode.OK);
                resp.Headers.Add("X-Hook-Secret", xHookSecret);
                return resp;
            }

Note that this is only for creating the webhook. Once it’s created, you’ll need code at your target URL to process the incoming webhooks. Here’s what I do for that:

            string xHookSignature = req.Headers.FirstOrDefault(x => x.Key == "X-Hook-Signature").Value?.FirstOrDefault();
            if (xHookSignature != null && xHookSignature.Length > 0)
            {
                string jsonContent = await req.Content.ReadAsStringAsync();

                // Your application-specific code to process the incoming webhook events goes here.

                var resp = req.CreateResponse(HttpStatusCode.OK);
                resp.Headers.Add("X-Hook-Signature", xHookSignature);
                return resp;
            }

Hi @Phil_Seeman. I made necessary changes in my service. Now I am getting the following error message “The remote server did not respond with the handshake secret.”,“help”:“For more information on API status codes and how to handle them, read the docs on errors”

Well that’s some progress I suppose.

That error message indicates that this code:

            string xHookSecret = req.Headers.FirstOrDefault(x => x.Key == "X-Hook-Secret").Value?.FirstOrDefault();
            if (xHookSecret != null && xHookSecret.Length > 0)
            {
                var resp = req.CreateResponse(HttpStatusCode.OK);
                resp.Headers.Add("X-Hook-Secret", xHookSecret);
                return resp;
            }

is either not being executed or something is amiss with it., as the Asana service is saying that it sent you the X-Hook-Secret and did not receive it back.

Can you debug that code and see if it’s being triggered first of all, and if so, is it executing properly? Also make sure you respond to their service within 10 seconds, and that you’re communicating strictly via HTTPS. There was also some discussion I recall a while back that certain types of SSL certificates were apparently not sufficient for the Asana service; you might want to search the Developers & API forum section for “SSL certificate”.

Hey @Joe_Trollo, any other thoughts on this issue? I know you guys recently implemented the more-specific webhook error messages; does this specific message tell you anything more than I mentioned above?

I @Phil_Seeman the error was resolved. Thanks for the help

1 Like

Can you share the solution?

1 Like