Create a custom field

Creates a new custom field in a workspace. Every custom field is required to be created in a specific workspace, and this workspace cannot be changed once set. A custom field’s name must be unique within a workspace and not conflict with names of existing task properties such as `Due Date` or `Assignee`. A custom field’s type must be one of `text`, `enum`, `multi_enum`, `number`, `date`, or `people`. Returns the full record of the newly created custom field.

Script asana Verified

by hugo697 · 10/31/2023

The script

Submitted by hugo697 Typescript (fetch-only)
Verified 383 days ago
1
type Asana = {
2
  token: string;
3
};
4
/**
5
 * Create a custom field
6
 * Creates a new custom field in a workspace. Every custom field is required
7
to be created in a specific workspace, and this workspace cannot be
8
changed once set.
9

10
A custom field’s name must be unique within a workspace and not conflict
11
with names of existing task properties such as `Due Date` or `Assignee`.
12
A custom field’s type must be one of `text`, `enum`, `multi_enum`, `number`,
13
`date`, or `people`.
14

15
Returns the full record of the newly created custom field.
16
 */
17
export async function main(
18
  auth: Asana,
19
  opt_pretty: string | undefined,
20
  opt_fields: string | undefined,
21
  limit: string | undefined,
22
  offset: string | undefined,
23
  body: {
24
    data?: (({ gid?: string; resource_type?: string; [k: string]: unknown } & {
25
      date_value?: { date?: string; date_time?: string; [k: string]: unknown };
26
      display_value?: string;
27
      enabled?: boolean;
28
      enum_options?: ({
29
        gid?: string;
30
        resource_type?: string;
31
        [k: string]: unknown;
32
      } & {
33
        color?: string;
34
        enabled?: boolean;
35
        name?: string;
36
        [k: string]: unknown;
37
      })[];
38
      enum_value?: ({
39
        gid?: string;
40
        resource_type?: string;
41
        [k: string]: unknown;
42
      } & {
43
        color?: string;
44
        enabled?: boolean;
45
        name?: string;
46
        [k: string]: unknown;
47
      }) & { [k: string]: unknown };
48
      multi_enum_values?: ({
49
        gid?: string;
50
        resource_type?: string;
51
        [k: string]: unknown;
52
      } & {
53
        color?: string;
54
        enabled?: boolean;
55
        name?: string;
56
        [k: string]: unknown;
57
      })[];
58
      name?: string;
59
      number_value?: number;
60
      resource_subtype?:
61
        | "text"
62
        | "enum"
63
        | "multi_enum"
64
        | "number"
65
        | "date"
66
        | "people";
67
      text_value?: string;
68
      type?: "text" | "enum" | "multi_enum" | "number";
69
      [k: string]: unknown;
70
    }) & {
71
      asana_created_field?:
72
        | "a_v_requirements"
73
        | "account_name"
74
        | "actionable"
75
        | "align_shipping_link"
76
        | "align_status"
77
        | "allotted_time"
78
        | "appointment"
79
        | "approval_stage"
80
        | "approved"
81
        | "article_series"
82
        | "board_committee"
83
        | "browser"
84
        | "campaign_audience"
85
        | "campaign_project_status"
86
        | "campaign_regions"
87
        | "channel_primary"
88
        | "client_topic_type"
89
        | "complete_by"
90
        | "contact"
91
        | "contact_email_address"
92
        | "content_channels"
93
        | "content_channels_needed"
94
        | "content_stage"
95
        | "content_type"
96
        | "contract"
97
        | "contract_status"
98
        | "cost"
99
        | "creation_stage"
100
        | "creative_channel"
101
        | "creative_needed"
102
        | "creative_needs"
103
        | "data_sensitivity"
104
        | "deal_size"
105
        | "delivery_appt"
106
        | "delivery_appt_date"
107
        | "department"
108
        | "department_responsible"
109
        | "design_request_needed"
110
        | "design_request_type"
111
        | "discussion_category"
112
        | "do_this_task"
113
        | "editorial_content_status"
114
        | "editorial_content_tag"
115
        | "editorial_content_type"
116
        | "effort"
117
        | "effort_level"
118
        | "est_completion_date"
119
        | "estimated_time"
120
        | "estimated_value"
121
        | "expected_cost"
122
        | "external_steps_needed"
123
        | "favorite_idea"
124
        | "feedback_type"
125
        | "financial"
126
        | "funding_amount"
127
        | "grant_application_process"
128
        | "hiring_candidate_status"
129
        | "idea_status"
130
        | "ids_link"
131
        | "ids_patient_link"
132
        | "implementation_stage"
133
        | "insurance"
134
        | "interview_area"
135
        | "interview_question_score"
136
        | "itero_scan_link"
137
        | "job_s_applied_to"
138
        | "lab"
139
        | "launch_status"
140
        | "lead_status"
141
        | "localization_language"
142
        | "localization_market_team"
143
        | "localization_status"
144
        | "meeting_minutes"
145
        | "meeting_needed"
146
        | "minutes"
147
        | "mrr"
148
        | "must_localize"
149
        | "name_of_foundation"
150
        | "need_to_follow_up"
151
        | "next_appointment"
152
        | "next_steps_sales"
153
        | "num_people"
154
        | "number_of_user_reports"
155
        | "office_location"
156
        | "onboarding_activity"
157
        | "owner"
158
        | "participants_needed"
159
        | "patient_date_of_birth"
160
        | "patient_email"
161
        | "patient_phone"
162
        | "patient_status"
163
        | "phone_number"
164
        | "planning_category"
165
        | "point_of_contact"
166
        | "position"
167
        | "post_format"
168
        | "prescription"
169
        | "priority"
170
        | "priority_level"
171
        | "product"
172
        | "product_stage"
173
        | "progress"
174
        | "project_size"
175
        | "project_status"
176
        | "proposed_budget"
177
        | "publish_status"
178
        | "reason_for_scan"
179
        | "referral"
180
        | "request_type"
181
        | "research_status"
182
        | "responsible_department"
183
        | "responsible_team"
184
        | "risk_assessment_status"
185
        | "room_name"
186
        | "sales_counterpart"
187
        | "sentiment"
188
        | "shipping_link"
189
        | "social_channels"
190
        | "stage"
191
        | "status"
192
        | "status_design"
193
        | "status_of_initiative"
194
        | "system_setup"
195
        | "task_progress"
196
        | "team"
197
        | "team_marketing"
198
        | "team_responsible"
199
        | "time_it_takes_to_complete_tasks"
200
        | "timeframe"
201
        | "treatment_type"
202
        | "type_work_requests_it"
203
        | "use_agency"
204
        | "user_name"
205
        | "vendor_category"
206
        | "vendor_type"
207
        | "word_count";
208
      currency_code?: string;
209
      custom_label?: string;
210
      custom_label_position?: "prefix" | "suffix";
211
      description?: string;
212
      enum_options?: ({
213
        gid?: string;
214
        resource_type?: string;
215
        [k: string]: unknown;
216
      } & {
217
        color?: string;
218
        enabled?: boolean;
219
        name?: string;
220
        [k: string]: unknown;
221
      })[];
222
      format?: "currency" | "identifier" | "percentage" | "custom" | "none";
223
      has_notifications_enabled?: boolean;
224
      is_global_to_workspace?: boolean;
225
      precision?: number;
226
      [k: string]: unknown;
227
    }) & { people_value?: string[]; workspace: string; [k: string]: unknown };
228
    [k: string]: unknown;
229
  }
230
) {
231
  const url = new URL(`https://app.asana.com/api/1.0/custom_fields`);
232
  for (const [k, v] of [
233
    ["opt_pretty", opt_pretty],
234
    ["opt_fields", opt_fields],
235
    ["limit", limit],
236
    ["offset", offset],
237
  ]) {
238
    if (v !== undefined && v !== "") {
239
      url.searchParams.append(k, v);
240
    }
241
  }
242
  const response = await fetch(url, {
243
    method: "POST",
244
    headers: {
245
      "Content-Type": "application/json",
246
      Authorization: "Bearer " + auth.token,
247
    },
248
    body: JSON.stringify(body),
249
  });
250
  if (!response.ok) {
251
    const text = await response.text();
252
    throw new Error(`${response.status} ${text}`);
253
  }
254
  return await response.json();
255
}
256