Skip to content

Instantly share code, notes, and snippets.

@patrickxchong
Created February 5, 2022 11:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickxchong/9dbae2f68ad31313c8c824f359dea6e7 to your computer and use it in GitHub Desktop.
Save patrickxchong/9dbae2f68ad31313c8c824f359dea6e7 to your computer and use it in GitHub Desktop.
Asana Tasks to ICal Feed
const axios = require("axios");
const ics = require('ics');
const fs = require('fs');
const asanaClient = axios.create({
baseURL: 'https://app.asana.com/api/1.0/',
headers: { "Authorization": "Bearer <Get personal ACCESS_TOKEN from Asana>" }
});
async function getMe() {
let res = await asanaClient.get("/users/me");
return res.data["data"];
}
async function getWorkspaces() {
let res = await asanaClient.get("/workspaces");
return res.data["data"];
}
async function getTasks({workspace, assignee}) {
let res = await asanaClient.get(`/tasks?workspace=${workspace}&assignee=${assignee}&completed_since=now&opt_fields=projects,name,assignee,html_notes,notes,due_on,due_at,created_at,modified_at,completed_at`);
return res.data["data"];
}
function getDateArray(date) {
const dt = new Date(date);
return [dt.getUTCFullYear(), dt.getUTCMonth() + 1, dt.getUTCDate(), dt.getUTCHours(), dt.getUTCMinutes()];
}
async function asanaToIcal() {
// can hardcode values after getting them from API
let assignee = (await getMe()).gid
// getWorkspaces returns an array of workspaces, so you may need to reference a different workspace gid if you're looking for tasks in another workspace
let workspace = (await getWorkspaces())[0].gid
let tasks = await getTasks({assignee, workspace});
let events = tasks.filter(task => task.due_on).map(task => {
// use " ^^" as a delimiter for task duration (in minutes)
let [title, minutes] = task.name.split(" ^^");
if (!minutes) {
// put default number of minutes
minutes = 30;
}
return {
uid: task.gid,
title,
description: task.notes,
status: 'CONFIRMED',
busyStatus: 'BUSY',
start: getDateArray(task.due_at || task.due_on),
startInputType: "utc",
created: getDateArray(task.created_at),
lastModified: getDateArray(task.modified_at),
duration: { minutes: parseInt(minutes) }
};
});
const { error, value: ics_feed } = ics.createEvents(events);
if (error) {
console.log(error);
return;
}
// ics_feed can either be
// 1. written to a file to upload separately, eg:
// fs.writeFileSync(`${__dirname}/event.ics`, ics_feed);
// 2. be sent back as a lambda response, eg:
// res.status(200).send(ics_feed);
// 3. or be used for other purposes downstream
return ics_feed;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment