Create a bot to detect additional tasks from Asana’s Webhook

syobochim
4 min readOct 31, 2020

--

I created a bot to notify slack when I add a task in the task management service’s Asana.
Usually, there are many apps that can be integrated with Asana as shown in the image below, so there is almost no need to write code from 1. However, there is a limit to the apps that can be added by the company Asana and the company Slack, so I decided to write code this time.

When I tried to use Webhook, I wanted to guarantee the security, but I didn’t have any information about it, so I hope that I can be of some help to those who make applications with Asana Webhook.

Creating ‘Personal Access Token’ for Authentication

First, create a Personal Access Token for authentication.

First, you access Asana’s Developer App Console.
You can access this URL “https://app.asana.com/0/developer-console", and
you can also click “My Profile Settings” from the profile image on the upper right of the screen where you logged in with Asana, and from the pop-up “Apps” tab, click “Manage Developer Apps”.

You can obtain a token in the following format by clicking “+ New Access Token” and entering the token name:. This token is used for program and curl access.

1/1234567890123456:bive3xuos5Ohcavei4yie7ha0Oovaph8

Second, Register a Webhook

To register a Webhook, you need the Project ID where the Task will be registered and the URL to send the information when the event occurs.
You can check the ID of Project from the URL of Asana. The number in the URL when you check the list or board of the project to register the task indicates the Project ID.
In the example below, 1234567890123456 is the Project ID.
https://app.asana.com/0/1234567890123456/board

Run the curl command, substituting {access-token} for the Access Token, {project-id} for the Project ID, and {target-url} for the URL to which the Webhook event should be sent.

action: added detects additional events for the task. In addition to added, changed removed deleted undeleted may be used.

$ curl -X POST https://app.asana.com/api/1.0/webhooks \
-H ‘Content-Type: application/json’ \
-H ‘Accept: application/json’ \
-H ‘Authorization: Bearer {access-token}’ \
-d ‘{
“data”: {
“filters”: [
{
“action”: “added”,
“resource_type”: “task”
}
],
“resource”: “{project-id}”,
“target”: “https://{target-url}”
}
}’

Third, Handshake

When the first Webhook event occurs, a request containing X-Hook-Secret in the HTTP header for Handshake is sent to the URL set to target-url .The registration is completed by returning a 200 OK or 204 No Content response to this request.

Here is the AWS Lambda code in Node.js at initial registration:. The second line logs the HTTP header X-Hook-Secret. MEMO this X-Hook-Secret value for later use. Also, this code is only used once when you register for the first time.

exports.handler = async (event) => {
console.log(‘this is secret header — — ->’ + event.headers[‘X-Hook-Secret’])
const response = {
statusCode: 200,
headers: {“X-Hook-Secret”: event.headers[‘X-Hook-Secret’]},
body: JSON.stringify(‘Hello from Lambda!’),
};
return response;
};

X-Hook-Secret is a string of the form “a0ge6aChaiPhee7ioph7cucongaht3”.

You can also use this site to easily verify that this code is working properly.
https://asana-webhook-tool.herokuapp.com/

Finally, verify the requests received by Webhook

Next, the Webhook receives the data that was actually sent.
By using the X-Hook-Secret you just got, you can verify that the request sent to the target url came from Asana and safely process the request.

Below is the AWS Lambda code using Node.js. Replace {X-Hook-Secret} with the value you just got.
Asana sends you a request with a X-Hook-Signature header. The value of X-Hook-Signature is the body of the request hashed with SHA 256 HMAC using X-Hook-Secret.
Check if the hashed value and X-Hook-Signature are the same, and if they are, treat them as normal requests.

var crypto = require(“crypto”);
exports.handler = async (event) => {
const signature = event.headers[‘X-Hook-Signature’];
const hash = crypto.createHmac(‘sha256’, ‘{X-Hook-Secret}’)
.update(String(event.body))
.digest(‘hex’);
// Check header secret
if (signature != hash) {
console.error(‘Calculated digest does not match digest from API. This event is not trusted. : ‘ + signature);
return response = {
statusCode: 401
};
}
// TODO : Write code to handle Webhook dataconst response = {
statusCode: 200
};
return response;
};

This completes the basic Webhook configuration.
After checking the header, you can safely manipulate the Webhook request by processing the body of the HTTP request.

Reference Links

--

--

syobochim
syobochim

No responses yet