Giter Site home page Giter Site logo

node-asana's Introduction

asana GitHub release NPM Version

  • API version: 1.0
  • Package version: 3.0.7

Installation

npm install from npmjs

npm install asana --save

For browser

Include the latest release directly from GitHub:

<script src="https://github.com/Asana/node-asana/releases/download/v3.0.7/asana-min.js"></script>

Example usage (NOTE: be careful not to expose your access token):

<script>
    let client = Asana.ApiClient.instance;
    let token = client.authentications['token'];
    token.accessToken = '<YOUR_ACCESS_TOKEN>';

    let usersApiInstance = new Asana.UsersApi();
    let user_gid = "me";
    let opts = {};

    usersApiInstance.getUser(user_gid, opts).then((result) => {
        console.log('API called successfully. Returned data: ' +  JSON.stringify(result.data, null, 2));
    }, (error) => {
        console.error(error.response.body);
    });
</script>

Webpack Configuration

Using Webpack you may encounter the following error: "Module not found: Error: Cannot resolve module", most certainly you should disable AMD loader. Add/merge the following section to your webpack config:

module: {
  rules: [
    {
      parser: {
        amd: false
      }
    }
  ]
}

Getting Started

Please follow the installation instruction and execute the following JS code:

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let usersApiInstance = new Asana.UsersApi();
let user_gid = "me"; // String | A string identifying a user. This can either be the string \"me\", an email, or the gid of a user.
let opts = { 
    "opt_fields": "email,name,photo,photo.image_1024x1024,photo.image_128x128,photo.image_21x21,photo.image_27x27,photo.image_36x36,photo.image_60x60,workspaces,workspaces.name" // [String] | This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
};

usersApiInstance.getUser(user_gid, opts).then((result) => {
    console.log('API called successfully. Returned data: ' +  JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

Example: GET, POST, PUT, DELETE on tasks

GET - get multiple tasks

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let opts = { 
    "limit": 50, // Number | Results per page. The number of objects to return per page. The value must be between 1 and 100.
    "project": "<YOUR_PROJECT_GID>", // String | The project to filter tasks on.
    "modified_since": "2012-02-22T02:06:58.158Z", // Date | Only return tasks that have been modified since the given time.  *Note: A task is considered “modified” if any of its properties change, or associations between it and other objects are modified (e.g.  a task being added to a project). A task is not considered modified just because another object it is associated with (e.g. a subtask) is modified. Actions that count as modifying the task include assigning, renaming, completing, and adding stories.*
    "opt_fields": "actual_time_minutes,approval_status,assignee,assignee.name,assignee_section,assignee_section.name,assignee_status,completed,completed_at,completed_by,completed_by.name,created_at,created_by,custom_fields,custom_fields.asana_created_field,custom_fields.created_by,custom_fields.created_by.name,custom_fields.currency_code,custom_fields.custom_label,custom_fields.custom_label_position,custom_fields.date_value,custom_fields.date_value.date,custom_fields.date_value.date_time,custom_fields.description,custom_fields.display_value,custom_fields.enabled,custom_fields.enum_options,custom_fields.enum_options.color,custom_fields.enum_options.enabled,custom_fields.enum_options.name,custom_fields.enum_value,custom_fields.enum_value.color,custom_fields.enum_value.enabled,custom_fields.enum_value.name,custom_fields.format,custom_fields.has_notifications_enabled,custom_fields.is_formula_field,custom_fields.is_global_to_workspace,custom_fields.is_value_read_only,custom_fields.multi_enum_values,custom_fields.multi_enum_values.color,custom_fields.multi_enum_values.enabled,custom_fields.multi_enum_values.name,custom_fields.name,custom_fields.number_value,custom_fields.people_value,custom_fields.people_value.name,custom_fields.precision,custom_fields.resource_subtype,custom_fields.text_value,custom_fields.type,dependencies,dependents,due_at,due_on,external,external.data,followers,followers.name,hearted,hearts,hearts.user,hearts.user.name,html_notes,is_rendered_as_separator,liked,likes,likes.user,likes.user.name,memberships,memberships.project,memberships.project.name,memberships.section,memberships.section.name,modified_at,name,notes,num_hearts,num_likes,num_subtasks,offset,parent,parent.created_by,parent.name,parent.resource_subtype,path,permalink_url,projects,projects.name,resource_subtype,start_at,start_on,tags,tags.name,uri,workspace,workspace.name" // [String] | This endpoint returns a compact resource, which excludes some properties by default. To include those optional properties, set this query parameter to a comma-separated list of the properties you wish to include.
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

POST - create a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let body = {
    "data": {
        "name": "New Task",
        "approval_status": "pending",
        "assignee_status": "upcoming",
        "completed": false,
        "external": {
            "gid": "1234",
            "data": "A blob of information.",
        },
        "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
        "is_rendered_as_separator": false,
        "liked": true,
        "assignee": "me",
        "projects": ["<YOUR_PROJECT_GID>"],
    },
};
let opts = {};

// POST - Create a task
tasksApiInstance.createTask(body, opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

PUT - update a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let task_gid = "<YOUR_TASK_GID>";
let body = {
    "data": {
        "name": "Updated Task",
    },
};
let opts = {};

// PUT - Update a task
tasksApiInstance.updateTask(body, task_gid, opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

DELETE - delete a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let task_gid = "<YOUR_TASK_GID>";

// DELETE - Delete a task
tasksApiInstance.deleteTask(task_gid).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

Documentation for API Endpoints

All URIs are relative to https://app.asana.com/api/1.0

Class Method HTTP request Description
Asana.AllocationsApi createAllocation POST /allocations Create an allocation
Asana.AllocationsApi deleteAllocation DELETE /allocations/{allocation_gid} Delete an allocation
Asana.AllocationsApi getAllocation GET /allocations/{allocation_gid} Get an allocation
Asana.AllocationsApi getAllocations GET /allocations Get multiple allocations
Asana.AllocationsApi updateAllocation PUT /allocations/{allocation_gid} Update an allocation
Asana.AttachmentsApi createAttachmentForObject POST /attachments Upload an attachment
Asana.AttachmentsApi deleteAttachment DELETE /attachments/{attachment_gid} Delete an attachment
Asana.AttachmentsApi getAttachment GET /attachments/{attachment_gid} Get an attachment
Asana.AttachmentsApi getAttachmentsForObject GET /attachments Get attachments from an object
Asana.AuditLogAPIApi getAuditLogEvents GET /workspaces/{workspace_gid}/audit_log_events Get audit log events
Asana.BatchAPIApi createBatchRequest POST /batch Submit parallel requests
Asana.CustomFieldSettingsApi getCustomFieldSettingsForPortfolio GET /portfolios/{portfolio_gid}/custom_field_settings Get a portfolio's custom fields
Asana.CustomFieldSettingsApi getCustomFieldSettingsForProject GET /projects/{project_gid}/custom_field_settings Get a project's custom fields
Asana.CustomFieldsApi createCustomField POST /custom_fields Create a custom field
Asana.CustomFieldsApi createEnumOptionForCustomField POST /custom_fields/{custom_field_gid}/enum_options Create an enum option
Asana.CustomFieldsApi deleteCustomField DELETE /custom_fields/{custom_field_gid} Delete a custom field
Asana.CustomFieldsApi getCustomField GET /custom_fields/{custom_field_gid} Get a custom field
Asana.CustomFieldsApi getCustomFieldsForWorkspace GET /workspaces/{workspace_gid}/custom_fields Get a workspace's custom fields
Asana.CustomFieldsApi insertEnumOptionForCustomField POST /custom_fields/{custom_field_gid}/enum_options/insert Reorder a custom field's enum
Asana.CustomFieldsApi updateCustomField PUT /custom_fields/{custom_field_gid} Update a custom field
Asana.CustomFieldsApi updateEnumOption PUT /enum_options/{enum_option_gid} Update an enum option
Asana.EventsApi getEvents GET /events Get events on a resource
Asana.GoalRelationshipsApi addSupportingRelationship POST /goals/{goal_gid}/addSupportingRelationship Add a supporting goal relationship
Asana.GoalRelationshipsApi getGoalRelationship GET /goal_relationships/{goal_relationship_gid} Get a goal relationship
Asana.GoalRelationshipsApi getGoalRelationships GET /goal_relationships Get goal relationships
Asana.GoalRelationshipsApi removeSupportingRelationship POST /goals/{goal_gid}/removeSupportingRelationship Removes a supporting goal relationship
Asana.GoalRelationshipsApi updateGoalRelationship PUT /goal_relationships/{goal_relationship_gid} Update a goal relationship
Asana.GoalsApi addFollowers POST /goals/{goal_gid}/addFollowers Add a collaborator to a goal
Asana.GoalsApi createGoal POST /goals Create a goal
Asana.GoalsApi createGoalMetric POST /goals/{goal_gid}/setMetric Create a goal metric
Asana.GoalsApi deleteGoal DELETE /goals/{goal_gid} Delete a goal
Asana.GoalsApi getGoal GET /goals/{goal_gid} Get a goal
Asana.GoalsApi getGoals GET /goals Get goals
Asana.GoalsApi getParentGoalsForGoal GET /goals/{goal_gid}/parentGoals Get parent goals from a goal
Asana.GoalsApi removeFollowers POST /goals/{goal_gid}/removeFollowers Remove a collaborator from a goal
Asana.GoalsApi updateGoal PUT /goals/{goal_gid} Update a goal
Asana.GoalsApi updateGoalMetric POST /goals/{goal_gid}/setMetricCurrentValue Update a goal metric
Asana.JobsApi getJob GET /jobs/{job_gid} Get a job by id
Asana.MembershipsApi createMembership POST /memberships Create a membership
Asana.MembershipsApi deleteMembership DELETE /memberships/{membership_gid} Delete a membership
Asana.MembershipsApi getMembership GET /memberships/{membership_gid} Get a membership
Asana.MembershipsApi getMemberships GET /memberships Get multiple memberships
Asana.MembershipsApi updateMembership PUT /memberships/{membership_gid} Update a membership
Asana.OrganizationExportsApi createOrganizationExport POST /organization_exports Create an organization export request
Asana.OrganizationExportsApi getOrganizationExport GET /organization_exports/{organization_export_gid} Get details on an org export request
Asana.PortfolioMembershipsApi getPortfolioMembership GET /portfolio_memberships/{portfolio_membership_gid} Get a portfolio membership
Asana.PortfolioMembershipsApi getPortfolioMemberships GET /portfolio_memberships Get multiple portfolio memberships
Asana.PortfolioMembershipsApi getPortfolioMembershipsForPortfolio GET /portfolios/{portfolio_gid}/portfolio_memberships Get memberships from a portfolio
Asana.PortfoliosApi addCustomFieldSettingForPortfolio POST /portfolios/{portfolio_gid}/addCustomFieldSetting Add a custom field to a portfolio
Asana.PortfoliosApi addItemForPortfolio POST /portfolios/{portfolio_gid}/addItem Add a portfolio item
Asana.PortfoliosApi addMembersForPortfolio POST /portfolios/{portfolio_gid}/addMembers Add users to a portfolio
Asana.PortfoliosApi createPortfolio POST /portfolios Create a portfolio
Asana.PortfoliosApi deletePortfolio DELETE /portfolios/{portfolio_gid} Delete a portfolio
Asana.PortfoliosApi getItemsForPortfolio GET /portfolios/{portfolio_gid}/items Get portfolio items
Asana.PortfoliosApi getPortfolio GET /portfolios/{portfolio_gid} Get a portfolio
Asana.PortfoliosApi getPortfolios GET /portfolios Get multiple portfolios
Asana.PortfoliosApi removeCustomFieldSettingForPortfolio POST /portfolios/{portfolio_gid}/removeCustomFieldSetting Remove a custom field from a portfolio
Asana.PortfoliosApi removeItemForPortfolio POST /portfolios/{portfolio_gid}/removeItem Remove a portfolio item
Asana.PortfoliosApi removeMembersForPortfolio POST /portfolios/{portfolio_gid}/removeMembers Remove users from a portfolio
Asana.PortfoliosApi updatePortfolio PUT /portfolios/{portfolio_gid} Update a portfolio
Asana.ProjectBriefsApi createProjectBrief POST /projects/{project_gid}/project_briefs Create a project brief
Asana.ProjectBriefsApi deleteProjectBrief DELETE /project_briefs/{project_brief_gid} Delete a project brief
Asana.ProjectBriefsApi getProjectBrief GET /project_briefs/{project_brief_gid} Get a project brief
Asana.ProjectBriefsApi updateProjectBrief PUT /project_briefs/{project_brief_gid} Update a project brief
Asana.ProjectMembershipsApi getProjectMembership GET /project_memberships/{project_membership_gid} Get a project membership
Asana.ProjectMembershipsApi getProjectMembershipsForProject GET /projects/{project_gid}/project_memberships Get memberships from a project
Asana.ProjectStatusesApi createProjectStatusForProject POST /projects/{project_gid}/project_statuses Create a project status
Asana.ProjectStatusesApi deleteProjectStatus DELETE /project_statuses/{project_status_gid} Delete a project status
Asana.ProjectStatusesApi getProjectStatus GET /project_statuses/{project_status_gid} Get a project status
Asana.ProjectStatusesApi getProjectStatusesForProject GET /projects/{project_gid}/project_statuses Get statuses from a project
Asana.ProjectTemplatesApi deleteProjectTemplate DELETE /project_templates/{project_template_gid} Delete a project template
Asana.ProjectTemplatesApi getProjectTemplate GET /project_templates/{project_template_gid} Get a project template
Asana.ProjectTemplatesApi getProjectTemplates GET /project_templates Get multiple project templates
Asana.ProjectTemplatesApi getProjectTemplatesForTeam GET /teams/{team_gid}/project_templates Get a team's project templates
Asana.ProjectTemplatesApi instantiateProject POST /project_templates/{project_template_gid}/instantiateProject Instantiate a project from a project template
Asana.ProjectsApi addCustomFieldSettingForProject POST /projects/{project_gid}/addCustomFieldSetting Add a custom field to a project
Asana.ProjectsApi addFollowersForProject POST /projects/{project_gid}/addFollowers Add followers to a project
Asana.ProjectsApi addMembersForProject POST /projects/{project_gid}/addMembers Add users to a project
Asana.ProjectsApi createProject POST /projects Create a project
Asana.ProjectsApi createProjectForTeam POST /teams/{team_gid}/projects Create a project in a team
Asana.ProjectsApi createProjectForWorkspace POST /workspaces/{workspace_gid}/projects Create a project in a workspace
Asana.ProjectsApi deleteProject DELETE /projects/{project_gid} Delete a project
Asana.ProjectsApi duplicateProject POST /projects/{project_gid}/duplicate Duplicate a project
Asana.ProjectsApi getProject GET /projects/{project_gid} Get a project
Asana.ProjectsApi getProjects GET /projects Get multiple projects
Asana.ProjectsApi getProjectsForTask GET /tasks/{task_gid}/projects Get projects a task is in
Asana.ProjectsApi getProjectsForTeam GET /teams/{team_gid}/projects Get a team's projects
Asana.ProjectsApi getProjectsForWorkspace GET /workspaces/{workspace_gid}/projects Get all projects in a workspace
Asana.ProjectsApi getTaskCountsForProject GET /projects/{project_gid}/task_counts Get task count of a project
Asana.ProjectsApi projectSaveAsTemplate POST /projects/{project_gid}/saveAsTemplate Create a project template from a project
Asana.ProjectsApi removeCustomFieldSettingForProject POST /projects/{project_gid}/removeCustomFieldSetting Remove a custom field from a project
Asana.ProjectsApi removeFollowersForProject POST /projects/{project_gid}/removeFollowers Remove followers from a project
Asana.ProjectsApi removeMembersForProject POST /projects/{project_gid}/removeMembers Remove users from a project
Asana.ProjectsApi updateProject PUT /projects/{project_gid} Update a project
Asana.RulesApi triggerRule POST /rule_triggers/{rule_trigger_gid}/run Trigger a rule
Asana.SectionsApi addTaskForSection POST /sections/{section_gid}/addTask Add task to section
Asana.SectionsApi createSectionForProject POST /projects/{project_gid}/sections Create a section in a project
Asana.SectionsApi deleteSection DELETE /sections/{section_gid} Delete a section
Asana.SectionsApi getSection GET /sections/{section_gid} Get a section
Asana.SectionsApi getSectionsForProject GET /projects/{project_gid}/sections Get sections in a project
Asana.SectionsApi insertSectionForProject POST /projects/{project_gid}/sections/insert Move or Insert sections
Asana.SectionsApi updateSection PUT /sections/{section_gid} Update a section
Asana.StatusUpdatesApi createStatusForObject POST /status_updates Create a status update
Asana.StatusUpdatesApi deleteStatus DELETE /status_updates/{status_update_gid} Delete a status update
Asana.StatusUpdatesApi getStatus GET /status_updates/{status_update_gid} Get a status update
Asana.StatusUpdatesApi getStatusesForObject GET /status_updates Get status updates from an object
Asana.StoriesApi createStoryForTask POST /tasks/{task_gid}/stories Create a story on a task
Asana.StoriesApi deleteStory DELETE /stories/{story_gid} Delete a story
Asana.StoriesApi getStoriesForTask GET /tasks/{task_gid}/stories Get stories from a task
Asana.StoriesApi getStory GET /stories/{story_gid} Get a story
Asana.StoriesApi updateStory PUT /stories/{story_gid} Update a story
Asana.TagsApi createTag POST /tags Create a tag
Asana.TagsApi createTagForWorkspace POST /workspaces/{workspace_gid}/tags Create a tag in a workspace
Asana.TagsApi deleteTag DELETE /tags/{tag_gid} Delete a tag
Asana.TagsApi getTag GET /tags/{tag_gid} Get a tag
Asana.TagsApi getTags GET /tags Get multiple tags
Asana.TagsApi getTagsForTask GET /tasks/{task_gid}/tags Get a task's tags
Asana.TagsApi getTagsForWorkspace GET /workspaces/{workspace_gid}/tags Get tags in a workspace
Asana.TagsApi updateTag PUT /tags/{tag_gid} Update a tag
Asana.TaskTemplatesApi deleteTaskTemplate DELETE /task_templates/{task_template_gid} Delete a task template
Asana.TaskTemplatesApi getTaskTemplate GET /task_templates/{task_template_gid} Get a task template
Asana.TaskTemplatesApi getTaskTemplates GET /task_templates Get multiple task templates
Asana.TaskTemplatesApi instantiateTask POST /task_templates/{task_template_gid}/instantiateTask Instantiate a task from a task template
Asana.TasksApi addDependenciesForTask POST /tasks/{task_gid}/addDependencies Set dependencies for a task
Asana.TasksApi addDependentsForTask POST /tasks/{task_gid}/addDependents Set dependents for a task
Asana.TasksApi addFollowersForTask POST /tasks/{task_gid}/addFollowers Add followers to a task
Asana.TasksApi addProjectForTask POST /tasks/{task_gid}/addProject Add a project to a task
Asana.TasksApi addTagForTask POST /tasks/{task_gid}/addTag Add a tag to a task
Asana.TasksApi createSubtaskForTask POST /tasks/{task_gid}/subtasks Create a subtask
Asana.TasksApi createTask POST /tasks Create a task
Asana.TasksApi deleteTask DELETE /tasks/{task_gid} Delete a task
Asana.TasksApi duplicateTask POST /tasks/{task_gid}/duplicate Duplicate a task
Asana.TasksApi getDependenciesForTask GET /tasks/{task_gid}/dependencies Get dependencies from a task
Asana.TasksApi getDependentsForTask GET /tasks/{task_gid}/dependents Get dependents from a task
Asana.TasksApi getSubtasksForTask GET /tasks/{task_gid}/subtasks Get subtasks from a task
Asana.TasksApi getTask GET /tasks/{task_gid} Get a task
Asana.TasksApi getTaskForCustomID GET /workspaces/{workspace_gid}/tasks/custom_id/{custom_id} Get a task for a given custom ID
Asana.TasksApi getTasks GET /tasks Get multiple tasks
Asana.TasksApi getTasksForProject GET /projects/{project_gid}/tasks Get tasks from a project
Asana.TasksApi getTasksForSection GET /sections/{section_gid}/tasks Get tasks from a section
Asana.TasksApi getTasksForTag GET /tags/{tag_gid}/tasks Get tasks from a tag
Asana.TasksApi getTasksForUserTaskList GET /user_task_lists/{user_task_list_gid}/tasks Get tasks from a user task list
Asana.TasksApi removeDependenciesForTask POST /tasks/{task_gid}/removeDependencies Unlink dependencies from a task
Asana.TasksApi removeDependentsForTask POST /tasks/{task_gid}/removeDependents Unlink dependents from a task
Asana.TasksApi removeFollowerForTask POST /tasks/{task_gid}/removeFollowers Remove followers from a task
Asana.TasksApi removeProjectForTask POST /tasks/{task_gid}/removeProject Remove a project from a task
Asana.TasksApi removeTagForTask POST /tasks/{task_gid}/removeTag Remove a tag from a task
Asana.TasksApi searchTasksForWorkspace GET /workspaces/{workspace_gid}/tasks/search Search tasks in a workspace
Asana.TasksApi setParentForTask POST /tasks/{task_gid}/setParent Set the parent of a task
Asana.TasksApi updateTask PUT /tasks/{task_gid} Update a task
Asana.TeamMembershipsApi getTeamMembership GET /team_memberships/{team_membership_gid} Get a team membership
Asana.TeamMembershipsApi getTeamMemberships GET /team_memberships Get team memberships
Asana.TeamMembershipsApi getTeamMembershipsForTeam GET /teams/{team_gid}/team_memberships Get memberships from a team
Asana.TeamMembershipsApi getTeamMembershipsForUser GET /users/{user_gid}/team_memberships Get memberships from a user
Asana.TeamsApi addUserForTeam POST /teams/{team_gid}/addUser Add a user to a team
Asana.TeamsApi createTeam POST /teams Create a team
Asana.TeamsApi getTeam GET /teams/{team_gid} Get a team
Asana.TeamsApi getTeamsForUser GET /users/{user_gid}/teams Get teams for a user
Asana.TeamsApi getTeamsForWorkspace GET /workspaces/{workspace_gid}/teams Get teams in a workspace
Asana.TeamsApi removeUserForTeam POST /teams/{team_gid}/removeUser Remove a user from a team
Asana.TeamsApi updateTeam PUT /teams/{team_gid} Update a team
Asana.TimePeriodsApi getTimePeriod GET /time_periods/{time_period_gid} Get a time period
Asana.TimePeriodsApi getTimePeriods GET /time_periods Get time periods
Asana.TimeTrackingEntriesApi createTimeTrackingEntry POST /tasks/{task_gid}/time_tracking_entries Create a time tracking entry
Asana.TimeTrackingEntriesApi deleteTimeTrackingEntry DELETE /time_tracking_entries/{time_tracking_entry_gid} Delete a time tracking entry
Asana.TimeTrackingEntriesApi getTimeTrackingEntriesForTask GET /tasks/{task_gid}/time_tracking_entries Get time tracking entries for a task
Asana.TimeTrackingEntriesApi getTimeTrackingEntry GET /time_tracking_entries/{time_tracking_entry_gid} Get a time tracking entry
Asana.TimeTrackingEntriesApi updateTimeTrackingEntry PUT /time_tracking_entries/{time_tracking_entry_gid} Update a time tracking entry
Asana.TypeaheadApi typeaheadForWorkspace GET /workspaces/{workspace_gid}/typeahead Get objects via typeahead
Asana.UserTaskListsApi getUserTaskList GET /user_task_lists/{user_task_list_gid} Get a user task list
Asana.UserTaskListsApi getUserTaskListForUser GET /users/{user_gid}/user_task_list Get a user's task list
Asana.UsersApi getFavoritesForUser GET /users/{user_gid}/favorites Get a user's favorites
Asana.UsersApi getUser GET /users/{user_gid} Get a user
Asana.UsersApi getUsers GET /users Get multiple users
Asana.UsersApi getUsersForTeam GET /teams/{team_gid}/users Get users in a team
Asana.UsersApi getUsersForWorkspace GET /workspaces/{workspace_gid}/users Get users in a workspace or organization
Asana.WebhooksApi createWebhook POST /webhooks Establish a webhook
Asana.WebhooksApi deleteWebhook DELETE /webhooks/{webhook_gid} Delete a webhook
Asana.WebhooksApi getWebhook GET /webhooks/{webhook_gid} Get a webhook
Asana.WebhooksApi getWebhooks GET /webhooks Get multiple webhooks
Asana.WebhooksApi updateWebhook PUT /webhooks/{webhook_gid} Update a webhook
Asana.WorkspaceMembershipsApi getWorkspaceMembership GET /workspace_memberships/{workspace_membership_gid} Get a workspace membership
Asana.WorkspaceMembershipsApi getWorkspaceMembershipsForUser GET /users/{user_gid}/workspace_memberships Get workspace memberships for a user
Asana.WorkspaceMembershipsApi getWorkspaceMembershipsForWorkspace GET /workspaces/{workspace_gid}/workspace_memberships Get the workspace memberships for a workspace
Asana.WorkspacesApi addUserForWorkspace POST /workspaces/{workspace_gid}/addUser Add a user to a workspace or organization
Asana.WorkspacesApi getWorkspace GET /workspaces/{workspace_gid} Get a workspace
Asana.WorkspacesApi getWorkspaces GET /workspaces Get multiple workspaces
Asana.WorkspacesApi removeUserForWorkspace POST /workspaces/{workspace_gid}/removeUser Remove a user from a workspace or organization
Asana.WorkspacesApi updateWorkspace PUT /workspaces/{workspace_gid} Update a workspace

Optional fields

Our opt_fields feature allows you to request for properties of a resource that you want to be returned in the response (more information here).

NOTE: by default, endpoints that return an array of results (EX: Get multiple tasks, Get multiple projects), will return a compact version of those results (EX: Get multiple tasks returns an array of TaskCompact objects).

EX: Get multiple tasks / getTasks without opt_fields

Example Request

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let opts = {
    "limit": 2,
    "project": "<YOUR_PROJECT_GID>"
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log(JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

Example Response

[
  {
    "gid": "123",
    "name": "Task 1",
    "resource_type": "task",
    "resource_subtype": "default_task"
  },
  {
    "gid": "456",
    "name": "Task 2",
    "resource_type": "task",
    "resource_subtype": "default_task"
  }
]

EX: Get multiple tasks / getTasks with opt_fields

Example Request

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let opts = { 
    "limit": 1,
    "project": "<YOUR_PROJECT_GID>",
    "opt_fields": "actual_time_minutes,approval_status,assignee,assignee.name,assignee_section,assignee_section.name,assignee_status,completed,completed_at,completed_by,completed_by.name,created_at,created_by,custom_fields,custom_fields.asana_created_field,custom_fields.created_by,custom_fields.created_by.name,custom_fields.currency_code,custom_fields.custom_label,custom_fields.custom_label_position,custom_fields.date_value,custom_fields.date_value.date,custom_fields.date_value.date_time,custom_fields.description,custom_fields.display_value,custom_fields.enabled,custom_fields.enum_options,custom_fields.enum_options.color,custom_fields.enum_options.enabled,custom_fields.enum_options.name,custom_fields.enum_value,custom_fields.enum_value.color,custom_fields.enum_value.enabled,custom_fields.enum_value.name,custom_fields.format,custom_fields.has_notifications_enabled,custom_fields.is_formula_field,custom_fields.is_global_to_workspace,custom_fields.is_value_read_only,custom_fields.multi_enum_values,custom_fields.multi_enum_values.color,custom_fields.multi_enum_values.enabled,custom_fields.multi_enum_values.name,custom_fields.name,custom_fields.number_value,custom_fields.people_value,custom_fields.people_value.name,custom_fields.precision,custom_fields.resource_subtype,custom_fields.text_value,custom_fields.type,dependencies,dependents,due_at,due_on,external,external.data,followers,followers.name,hearted,hearts,hearts.user,hearts.user.name,html_notes,is_rendered_as_separator,liked,likes,likes.user,likes.user.name,memberships,memberships.project,memberships.project.name,memberships.section,memberships.section.name,modified_at,name,notes,num_hearts,num_likes,num_subtasks,offset,parent,parent.created_by,parent.name,parent.resource_subtype,path,permalink_url,projects,projects.name,resource_subtype,start_at,start_on,tags,tags.name,uri,workspace,workspace.name"
};

// GET - get multiple tasks
tasksApiInstance.getTasks(opts).then((result) => {
    console.log(JSON.stringify(result.data, null, 2));
}, (error) => {
    console.error(error.response.body);
});

Example Response

[
  {
    "gid": "129839839",
    "actual_time_minutes": null,
    "assignee": {
      "gid": "120938293",
      "name": "[email protected]"
    },
    "assignee_status": "upcoming",
    "assignee_section": {
      "gid": "1094838938",
      "name": "Recently assigned"
    },
    "completed": false,
    "completed_at": null,
    "completed_by": null,
    "created_at": "2023-01-01T20:31:21.717Z",
    "created_by": {
      "gid": "1201784467042440",
      "resource_type": "user"
    },
    "custom_fields": [
      {
        "gid": "191859815",
        "enabled": true,
        "name": "Estimated time",
        "description": "Asana-created. Estimate time to complete a task.",
        "number_value": null,
        "precision": 0,
        "format": "duration",
        "currency_code": null,
        "custom_label": null,
        "created_by": null,
        "custom_label_position": null,
        "display_value": null,
        "resource_subtype": "number",
        "is_formula_field": false,
        "is_value_read_only": false,
        "type": "number"
      }
    ],
    "dependencies": [],
    "dependents": [],
    "due_at": "2025-01-20T02:06:58.000Z",
    "due_on": "2025-01-19",
    "followers": [
      {
        "gid": "120938293",
        "name": "[email protected]"
      }
    ],
    "hearted": true,
    "hearts": [
      {
        "gid": "594849843",
        "user": {
          "gid": "120938293",
          "name": "[email protected]"
        }
      }
    ],
    "html_notes": "<body>Example task notes</body>",
    "is_rendered_as_separator": false,
    "liked": true,
    "likes": [
      {
        "gid": "58303939",
        "user": {
          "gid": "120938293",
          "name": "[email protected]"
        }
      }
    ],
    "memberships": [
      {
        "project": {
          "gid": "4567",
          "name": "Example Project"
        },
        "section": {
          "gid": "8900",
          "name": "Untitled section"
        }
      }
    ],
    "modified_at": "2023-01-25T21:24:06.996Z",
    "name": "Task 1",
    "notes": "Example task notes",
    "num_hearts": 1,
    "num_likes": 1,
    "num_subtasks": 0,
    "parent": null,
    "permalink_url": "https://app.asana.com/0/58303939/129839839",
    "projects": [
      {
        "gid": "4567",
        "name": "Example Project"
      }
    ],
    "start_at": null,
    "start_on": null,
    "tags": [],
    "resource_subtype": "default_task",
    "workspace": {
      "gid": "111111",
      "name": "Example Workspace"
    }
  }
]

Pagination

By default, endpoints that return an array of results (EX: Get multiple tasks, Get multiple projects), will return a Collection object. This collection object contains a nextPage method that can be used to fetch for the next page of results. NOTE: in order to use nextPage you must have provided a limit query parameter argument in the initial request.

Use case

You may run into the following error when making a request to an endpoint that has >1000 results:

"The result is too large. You should use pagination (may require specifying a workspace)!"

In this scenario you will want to use pagaintion to gather your results. To do this, you will need to provide a limit query parameter argument in your request. This limit query parameter represents the number of results per page. NOTE: the limit can only be between 1 and 100.

EX: Pagination gather all resources

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let opts = {
    "project": "<YOUR_PROJECT_GID>",
    "limit": 100,
};

async function getAllTasks(opts) {
    let tasks = await tasksApiInstance.getTasks(opts).then(async (response) => {
        let result = [];
        let page = response;
        while(true) {
            // Add items on page to list of results
            result = result.concat(page.data);
            // Fetch the next page
            page = await page.nextPage();
            // If the there is no data in the next page break from the loop
            if (!page.data) {
                break;
            }
        }
        return result;
    }, (error) => {
        console.error(error.response.body);
    });
    // Do something with the tasks. EX: print out results
    console.log('Tasks: ' + JSON.stringify(tasks, null, 2));
}

getAllTasks(opts);

Sample output:

Tasks: [
    {
      "gid": "123",
      "name": "task 1",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "456",
      "name": "task 2",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "789",
      "name": "task 3",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "101112",
      "name": "task 4",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "131415",
      "name": "task 5",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "161718",
      "name": "task 6",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "192021",
      "name": "task 7",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "222324",
      "name": "task 8",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "252627",
      "name": "task 9",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "282930",
      "name": "task 10",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
    {
      "gid": "313233",
      "name": "task 11",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
]

EX: Pagination do something per page

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let opts = {
    'project': "<YOUR_PROJECT_GID>",
    "limit": 5,
};

let pageIndex = 1;

tasksApiInstance.getTasks(opts).then(async (response) => {
    let page = response;
    while(true) {
        // Do something with the page results
        // EX: print the name of the tasks on that page
        console.log(`Page ${pageIndex}: `);
        page.data.forEach(task => {
            console.log(`    ${task.name}`);
        });
        pageIndex += 1;

        page = await page.nextPage();
        // If the there is no data in the next page break from the loop
        if (!page.data) {
            break;
        }
    }
}, (error) => {
    console.error(error.response.body);
});

Sample output:

Page 1:
    task 1
    task 2
    task 3
    task 4
    task 5
Page 2:
    task 6
    task 7
    task 8
    task 9
    task 10
Page 3:
    task 11
    task 12
    task 13
    task 14
    task 15

Turning off Pagination

If you do not want a Collection object returned and want to implement your own pagination, you can disable pagination by setting RETURN_COLLECTION to false:

EX: Turning off pagination

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// Turn off pagination
client.RETURN_COLLECTION = false;

let tasksApiInstance = new Asana.TasksApi();
let opts = {
    'project': "<YOUR_PROJECT_GID>",
    'limit': 1
};
tasksApiInstance.getTasks(opts).then((result) => {
    console.log('API called successfully. Returned data: ' + JSON.stringify(result, null, 2));
})

Sample response:

API called successfully. Returned data: {
  "data": [
    {
      "gid": "<TASK_GID>",
      "name": "Task 1",
      "resource_type": "task",
      "resource_subtype": "default_task"
    },
  ],
  "next_page": {
    "offset": "gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8",
    "path": "/tasks?project=123456&limit=1&offset=gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8",
    "uri": "https://app.asana.com/api/1.0/tasks?project=123456&limit=1&offset=gjJl2xAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJib3JkZXJfcmHilbI6IltcIlZ5IixcIjlaWlhVMkkzUUdOoXcEIsMTIwNDYxNTc0NTypNDI3MF0iLCJpYXQiOjE2OTc4MjgsSkjjQsImV4cCI6MTY5NzgyOTM2NH0.5VuMfKvqexoEsKfoPFtayWBNWiKvfR7_hN6MJaaIkx8"
  }
}

Getting events

In order to get events you will need a sync token. This sync token can be acquired in the error message from the initial request to getEvents.

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let eventsApiInstance = new Asana.EventsApi();
let resource = "<YOUR_TASK_OR_PROJECT_GID>"; // String | A resource ID to subscribe to. The resource can be a task or project.
let opts = {
    "sync": ""
};
const timeouts = 5000

// Used to fetch for initial sync token
const setSyncToken = async () => {
    await eventsApiInstance.getEvents(resource, opts).then((result) => {
        console.log(JSON.stringify(result.data, null, 2));
    }, (error) => {
        let syncToken = error.response.body.sync;
        opts['sync'] = syncToken;
    });
}

const getEvents = async () => {
    console.log("Setting sync token");
    await setSyncToken();
    // Fetch for new events every 5 seconds
    console.log(`Fetching events every ${timeouts/1000} second(s)`);
    while(true) {
        await eventsApiInstance.getEvents(resource, opts).then((result) => {
            // Print response
            console.log(`Fetching events since sync: ${opts['sync']}`);
            console.log(JSON.stringify(result.data, null, 2));

            // Update the sync token with the new sync token provided in the response
            opts['sync'] = result._response.sync;
        }, (error) => {
            if (error.status === 412) {
                let syncToken = error.response.body.sync;
                opts['sync'] = syncToken;
                console.log(`412 error new sync token: ${syncToken}`);
            } else{
                console.error(error.response.text);
            }
        });
        await new Promise(resolve => setTimeout(resolve, timeouts));
    }
}

getEvents();

Accessing repsonse data

.
.
.
tasksApiInstance.getTask(task_gid, opts).then((task) => {
    let taskName = task.data.name;
    let taskNotes = task.data.notes;
    console.log(`taskName: ${taskName}`);
    console.log(`taskNotes: ${taskNotes}`);
}, (error) => {
    console.error(error.response.body);
});

Accessing response status code and headers

Use the <METHOD_NAME>WithHttpInfo (EX: getTaskWithHttpInfo) method to make a request that returns a response with headers.

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

let tasksApiInstance = new Asana.TasksApi();
let task_gid = "<YOUR_TASK_GID>";
let opts = {};

tasksApiInstance.getTaskWithHttpInfo(task_gid, opts).then((response_and_data) => {
    let data = response_and_data.data;
    let response = response_and_data.response;
    let task = data.data;
    let headers = response.headers;
    console.log(task);
    console.log(headers);
}, (error) => {
    console.error(error.response.body);
});

Adding deprecation flag: "asana-enable" or "asana-disable" header

EX: Asana-Enable header

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// Add asana-enable header for the client
client.defaultHeaders['asana-enable'] = 'new_goal_memberships';

EX: Asana-Disable header

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// Add asana-disable header for the client
client.defaultHeaders['asana-disable'] = 'new_goal_memberships';

Using the callApi method

Use the callApi method to make http calls when the endpoint does not exist in the current library version or has bugs

Example: GET, POST, PUT, DELETE on tasks

GET - get a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// GET - get a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='GET',
    pathParams={"task_gid": "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});

GET - get multiple tasks -> with opt_fields

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// GET - get multiple tasks -> with opt_fields
client.callApi(
    path='/tasks',
    httpMethod='GET',
    pathParams={},
    queryParams={
        "limit": 50,
        "modified_since": '2012-02-22T02:06:58.158Z', // OR new Date("2012-02-22T02:06:58.158Z")
        "project": '<YOUR_PROJECT_GID>',
        "opt_fields": 'name,notes'
    },
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let tasks = result.data;
    if (tasks.length > 0) {
        console.log(`Task 1 Name: ${tasks[0].name}`);
        console.log(`Task 1 Notes: ${tasks[0].notes}`);
    }
}, (error) => {
    console.error(error.response.body);
});

POST - create a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// POST - create a task
client.callApi(
    path='/tasks',
    httpMethod='POST',
    pathParams={},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam={
        data: {
            "name": "New Task",
            "approval_status": "pending",
            "assignee_status": "upcoming",
            "completed": false,
            "html_notes": "<body>Mittens <em>really</em> likes the stuff from Humboldt.</body>",
            "is_rendered_as_separator": false,
            "liked": true,
            "assignee": "me",
            "projects": ["<YOUR_PROJECT_GID>"],
        }
    },
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});

PUT - update a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// PUT - update a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='PUT',
    pathParams={task_gid: "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam={
        "data": {
            "name": "Updated Task",
            "html_notes": "<body>Updated task notes</body>",
            "due_at": "2025-01-20T02:06:58.147Z"
        }
    },
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let task = result.data;
    console.log(task.name);
}, (error) => {
    console.error(error.response.body);
});

DELETE - delete a task

const Asana = require('asana');

let client = Asana.ApiClient.instance;
let token = client.authentications['token'];
token.accessToken = '<YOUR_ACCESS_TOKEN>';

// DELETE - delete a task
client.callApi(
    path='/tasks/{task_gid}',
    httpMethod='DELETE',
    pathParams={"task_gid": "<YOUR_TASK_GID>"},
    queryParams={},
    headerParams={},
    formParams={},
    bodyParam=null,
    authNames=['token'],
    contentTypes=[],
    accepts=['application/json; charset=UTF-8'],
    returnType='Blob'
).then((response_and_data) => {
    let result = response_and_data.data;
    let result = result.data;
    console.log(result);
}, (error) => {
    console.error(error.response.body);
});

node-asana's People

Contributors

0xcaff avatar agnoster avatar asana-publish-client-libraries[bot] avatar asanabot avatar aw-asana avatar barslev avatar bastian1993 avatar cw-sebastian avatar dependabot[bot] avatar epelz avatar eyalronel avatar jjschnei avatar joetrollo avatar jv-asana avatar markchua avatar pmacmillan avatar praecipula avatar pspeter3 avatar puthranps avatar rossgrambo-zz avatar rv-vmartyniuk avatar slobak avatar snyk-bot avatar stremlau avatar svnh avatar tasyp avatar theaeolianmachine avatar troyastorino avatar unityoffairfax avatar zzmp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

node-asana's Issues

Cryptic error when using OAuth refresh token

I'm trying to use a refresh_token to authenticate using OAuth. Here's what I've got:

var asana = require('asana');
var client = asana.Client.create({
    clientId : myClientId,
    clientSecret : myClientSecret

});

client.useOauth({
    credentials : {
        refresh_token: myRefreshToken
    }
});

client.users.me().then(function(me) {
    console.log('Hello ' + me.name);
});

Unfortunately, this throws the following error:

> Unhandled rejection TypeError: Cannot read property 'hasOwnProperty' of null
    at appendFormValue (/Users/me/project/node_modules/asana/node_modules/request/request.js:330:16)
    at Request.init (/Users/me/project/node_modules/asana/node_modules/request/request.js:344:11)
    at new Request (/Users/me/project/node_modules/asana/node_modules/request/request.js:140:8)
    at request (/Users/me/project/node_modules/asana/node_modules/request/index.js:55:10)
    at /Users/me/project/node_modules/asana/lib/auth/app.js:13:5
    at tryCatcher (/Users/me/project/node_modules/asana/node_modules/bluebird/js/main/util.js:26:23)
    at Promise._resolveFromResolver (/Users/me/project/node_modules/asana/node_modules/bluebird/js/main/promise.js:480:31)
    at new Promise (/Users/me/project/node_modules/asana/node_modules/bluebird/js/main/promise.js:70:37)
    at doRequest (/Users/me/project/node_modules/asana/lib/auth/app.js:12:10)
    at App.accessTokenFromRefreshToken (/Users/me/project/node_modules/asana/lib/auth/app.js:131:10)
    at OauthAuthenticator.refreshCredentials (/Users/me/project/node_modules/asana/lib/auth/oauth_authenticator.js:95:34)
    at Dispatcher.maybeReauthorize [as handleUnauthorized] (/Users/me/project/node_modules/asana/lib/dispatcher.js:82:29)
    at Request._callback (/Users/me/project/node_modules/asana/lib/dispatcher.js:153:33)
    at Request.self.callback (/Users/me/project/node_modules/asana/node_modules/request/request.js:198:22)
    at Request.emit (events.js:110:17)
    at Request.<anonymous> (/Users/me/project/node_modules/asana/node_modules/request/request.js:1063:14)

What's happening here? I'm pretty sure my auth details are correct, and the above code works fine when I supply an access_token instead.

Stopping an event stream

Hi,

Just wondering how one would stop an event stream. Say, if you wanted to change it to watch a different project.

Thanks

How to set/retreive custom external ID?

Can't find any working example and the documentation in Asana API is not very helpful.

I tried adding the external ID and created the task (with other params not shown here) like below

params['external'] = [ {id: '12345'}]
Asana.tasks.create(params).then (response) ->

This did not show any errors. However, when I tried to retrieve this, I get a invalid request

Asana.tasks.findByExternalId("12345").then (response) -> .....

Using addProject route with newly created task list (template duplication)

Having an issue, don't know if API related and wondering if anyone else is having issue. I'm trying to duplicate a list of tasks from one project into a newly created project, and put them in the same order. So far, I am querying from template, creating new project, then creating the tasks in the new project, then using addProject route to update task location with insert_after. The result is the tasks do update location but the wrong location. I can also confirm I am passing the properid of each for insert_after. Any help is appreciated and thanks for the great SDK.

Preferred way to get node-asana to work in Google Apps Script?

Hey team - big fan of Asana and have made some cool integrations with Google Apps Script (with a small client I wrote myself). Was considering making the node-asana library work instead and would appreciate any thoughts on best way to do it.

My thought is to either allow configuring another dispatcher that uses Google's UrlFetchApp or to build something like google-request that can be subbed in using browserify.

Any thoughts on best way to do this or if this has been done already?

CORS request rejected v0.7.9

XMLHttpRequest cannot load https://app.asana.com/api/1.0/users/me. Request header field X-Asana-Client-Lib is not allowed by Access-Control-Allow-Headers.

asana.js:4238 Unhandled rejection Error: CORS request rejected: https://app.asana.com/api/1.0/users/me
    at on_response (http://localhost/wp-content/themes/asana-2014/src/js/lib/asana.js:8589:22)
    at XMLHttpRequest.on_state_change (http://localhost/wp-content/themes/asana-2014/src/js/lib/asana.js:8572:7)

Receiving error regarding popup window using Oauth flow

I'm using the popup Oauth flow, and after the popup_receiver.html pops up and hides again (eg: when an application has already been authorized), it throws this error into the console. It's not preventing me from using the application, but it always shows up.
screen shot 2015-12-09 at 4 10 05 pm

Bluebird Array Issue

Unhandled rejection TypeError: expecting an array, a promise or a thenable

See http://goo.gl/s8MMhc

at MappingPromiseArray.init [as _init$] (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/promise_array.js:42:27)
at Promise._settlePromiseAt (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/promise.js:579:21)
at Promise._settlePromises (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/promise.js:697:14)
at Async._drainQueue (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/async.js:123:16)
at Async._drainQueues (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/async.js:133:10)
at Immediate.Async.drainQueues [as _onImmediate] (/home/pubuser/www/node_modules/asana/node_modules/bluebird/js/main/async.js:15:14)
at processImmediate [as _immediateCallback] (timers.js:358:17)

client.users.me()
 .then(function(user) {
 return client.tasks.findByProject(projectId);
 })
 .then(function(response) {
 try{
 console.log("Got Response");
 tasks = response.data;
 console.log(tasks);
 return;
 }catch(e){}
 })
 .filter(function(data) {
 console.log("In Filter");
 return ;
 })
 .then(function(list) {
 console.log("List");
 return;
 }); 

Got Response
[ { id: 62477966911872, name: 'Test Task 2' },
{ id: 62477966911869, name: 'Test Task' } ]

dispatchOptions not being respected

I was trying to populate expand the assignee field when calling client.tasks.create and it doesn't appear the dispatchOptions are actually being used anywhere. Here's the relevant dispatch call

/**
 * Dispatches a request to the Asana API. The request parameters are passed to
 * the request module.
 * @param  {Object}  params The params for request
 * @param  {Object}  [dispatchOptions] Options for handling request/response
 * @return {Promise}        The response for the request
 */
Dispatcher.prototype.dispatch = function(params, dispatchOptions) {
 var me = this;
 // TODO: actually honor these options as overriding defaults
 dispatchOptions = dispatchOptions || {};

if (this.requestTimeout) {
 params.timeout = this.requestTimeout;
 }

return new Bluebird(function(resolve, reject) {
 function doRequest() {
 if (me.authenticator !== null) {
 me.authenticator.authenticateRequest(params);
 }
 me._addVersionInfo(params);
 request(params, function(err, res, payload) {
 if (err) {
 return reject(err);
 }
 if (STATUS_MAP[res.statusCode]) {
 var error = new STATUS_MAP[res.statusCode](payload);

if (me.retryOnRateLimit &&
 error instanceof (errors.RateLimitEnforced)) {
 // Maybe attempt retry for rate limiting.
 // Delay a half-second more in case of rounding error.
 // TODO: verify Asana is always being conservative with duration
 setTimeout(doRequest, error.retryAfterSeconds * 1000 + 500);

} else if (me.handleUnauthorized &&
 error instanceof (errors.NoAuthorization)) {
 // Maybe attempt to retry unauthorized requests after getting
 // a new access token.
 Bluebird.resolve(me.handleUnauthorized()).then(function(reauth) {
 if (reauth) {
 doRequest();
 } else {
 reject(error);
 }
 });

} else {
 // Not an error we can handle.
 return reject(error);
 }
 } else {
 return resolve(payload);
 }
 });
 }
 doRequest();
 });
};

As a quick test, passing it inside of dispatch.post explicitly does work

/**
 * Dispatches a POST request to the Asana API.
 * @param  {String} path The path of the API
 * @param  {Object} data The data to be sent
 * @param  {Object}  [dispatchOptions] Options for handling the request and
 *     response. See `dispatch`.
 * @return {Promise}     The response for the request
 */
Dispatcher.prototype.post = function(path, data, dispatchOptions) {
 var params = {
 method: 'POST',
 url: this.url(path),
 json: {
 data: data,
 options: dispatchOptions // this works
 }
 };
 return this.dispatch(params, dispatchOptions);
};

I'm happy to work on a pull request, but would like a little guidance on implementation. Are dispatchOptions only used for PUT and POST? Looks like it's in the function signature for GET and DELETE as well though for GET I think those options should be passed in the query string?

ECONNREFUSED

Assuming this is probably the wrong place to put this, but here goes:

We're using library version 0.6.0, and are getting an ECONNREFUSED. We haven't been getting this at all before, so I'm assuming that we're getting rate-limited by the Asana servers or something?

Require packge.json and readline errors with webpack

Hey.

We've been getting issues with using this webpack. Kinda came as a double error

ERROR in ./~/asana/package.json
Module parse failed: /Users/kevin/projects/.../node_modules/asana/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
|   "_args": [
|     [
|       "asana",
 @ ./~/asana/index.js 7:18-43

ERROR in ./~/asana/lib/auth/native_flow.js
Module not found: Error: Cannot resolve module 'readline' in /Users/kevin/projects/.../node_modules/asana/lib/auth
 @ ./~/asana/lib/auth/native_flow.js 1:15-34

Resolution to the first was to add .json to our webpack resolve extensions config.

resolve: {
 extensions: ['', '.js', '.jsx', '.json', '.scss']
}

This is all because teh dispatcher.js does var VERSION = require('../package.json').version

Second was kinda weirder, we added to our webpack config

node: {
 readline: 'empty'
}

We've got it running now, but it was a bit of a pain.

Hope that helps someone

CORS request rejected v0.13.0 on accessing Projects

Hi,

Getting the following error on accessing workspaces, "Only for some users".

asana.js:4776 Unhandled rejection Error: CORS request rejected: https://app.asana.com/api/1.0/workspaces?limit=50
at on_response (http://176.9.35.233:8080/asana/asana.js:8971:22)
at XMLHttpRequest.on_state_change (http://176.9.35.233:8080/asana/asana.js:8954:7)

Browser: Chrome 46 (Incognito mode with No extension)

With one user, everything works just fine and the workspaces, tasks are being pulled. But with another user, CORS rejection always happen.

screen shot 2015-11-24 at 9

Update errors

Long story short, I'm trying to write my own Asana/iDoneThis integration.

I've got as far as passing Asana's completed tasks to iDoneThis, and now I want to set a custom field to use to exclude these from future sweeps.

Here's my code, but it doesn't seem to be adding the 'external' data:

tasks is the array of tasks.

tasks.forEach(function (task) {
            var extStr = JSON.stringify({
                "id": task.id,
                "data": 'passedToIDT'
            });
            var data = {
              notes: task.notes ? task.notes + '\nDone...' : 'Done...',
              external: extStr
            }
            client.tasks.update(task.id, data)
            .then(function (resp) {
                console.log(resp);
            });
        });

I get 'Unhandled rejection Error: Server Error' when running the code as above.

I also tried JSON.stringify(data) as the second argument to the update method, but that just did nothing (there was no error, but the external data was not set).

support for pagination

Does this library support pagination? It looks like the request can be manually retried by passing the offset string as a param, but would it be possible to have the library do this automatically?

No provision for specifying HTTP proxy for machines behind firewall

I am trying to use this module from a machine that is behind a firewall. I need to provide proxy for making requests. I am unable to see any provision to set proxy for the request.

The node module uses 'request' as base to make the request. The request module has in-built proxy support. It would be great if you could just provide a setter method for the same.

Basic authentication not working in browserified version

Using the basicAuth client on the browserified lib (dist/asana.js) always sends an invalid authorization header.

This is caused by this bug: iriscouch/browser-request#41

A workaround patch could be:

Client.basicAuth = function(apiKey) {
  return new Client(new Dispatcher('auth', {
    user: apiKey,
    pass: '',
    // Workaround for browser-request issue #41
    username: apiKey,
    password: ''
  }));
};

Retrieve tags broken in 0.9.1

Hi. This piece of code works on 0.4.1 (enter in the promise then), do not work in 0.9.1 (enter in the catch). Error message is just: Invalid Request

client.tags.findAll()
  .then(function(n) {
    // do something..
  })
  .catch(function(err) {
    // handle error
  });

But the 0.4.1 is missing the teams.findByOrganization function..

Examples

Could you provide some basic examples on how to create Tasks. I can see some advanced examples but no basic stuff on how to create tasks, etc.

Thanks

Keep getting - The `code` provided was invalid.

I'm doing the Authorization Code Grant. Here is what I do:

Creating an Asana client

var createClient = function () {
    return Asana.Client.create({
        clientId: clientId,
        clientSecret: clientSecret,
        redirectUri: redirectUri
    });
}

Take the url to redirect the user

var client = createClient();
var url = client.app.asanaAuthorizeUrl();

Use the code to request access_token

var client = createClient();

client.app.accessTokenFromCode(code)
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })

I keep getting this error

{
  "error": "invalid_grant",
  "error_uri": "https://asana.com/developers/documentation/getting-started/authentication",
  "error_description": "The `code` provided was invalid."
}

Am I missing something here or this should be the correct way of doing this?

Add support for setting request timeout

There's currently no way of setting the request timeout. This could be achieved by exposing an option requestTimeout when creating the asana object, and passing this as a timeout param into the request lib.

examples/oauth/chrome_extension doesn't run

I encountered 3 problems running this example:

  1. Empty README.md. Should probably add a word about how to run gulp ... maybe describe what this example demonstrates?
  2. Code expects asana.js to be copied into dist/ directory, but it isn't. This results in a Uncaught ReferenceError: Asana is not defined error.
  3. I also encountered a

Denying load of chrome-extension://ealgjjlepahaihgcoomhpimmfpgjdonm/asana_oauth_receiver.ht…arer&expires_in=3600&data=&state=asana_0.qhubf9tp1h6e9jkq2bcd0wwmiiy35fjk4. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension.

error. This error went away when I added "web_accessible_resources": ["*"] to my manifest.json ... but that' probably not the best idea.

projects.findAll() giving error

projects.findAll() is outputing a stack trace.

The underlying error is an HTTP 400 from Asana
"Need to specify a workspace or team to paginate!"

Using curl, getting the following correctly returns the entire project list across
workspaceshttps://app.asana.com/api/1.0/projects/

But adding a limit causes the same HTTP 400
workspaceshttps://app.asana.com/api/1.0/projects/?limit=50
"Need to specify a workspace or team to paginate!"

Is this normal? Basically is a workspace for projects.findAll() ?

Unable to call client.users.findAll() without arguments

Whenever I call client.users.findAll() I get an Invalid Request

However, if I call client.users.findAll(true) I'm returned the full user list.

I assume this is a bug since I don't have to do this for other implementations of findAll().

Thanks in advance!

State not passed through when using PopupFlow

The url being used to initiate the popup flow does not contain the state parameter, so the authorization process doesn't complete correctly.

(PopupFlow.prototype.startAuthorization)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.