diff --git a/src/clients/core/groups.js b/src/clients/core/groups.js index ec89b26c..722e8cbb 100644 --- a/src/clients/core/groups.js +++ b/src/clients/core/groups.js @@ -1,6 +1,30 @@ // Groups.js: Client for the zendesk API. const {Client} = require('../client'); +/** + * @typedef {object} RecursivePartial + * @template T + * @property {T[P]} [P] - The property of the object. + */ + +/** + * @typedef {object} Group + * @property {string} created_at - The time the group was created + * @property {boolean} default - If the group is the default one for the account + * @property {boolean} deleted - Deleted groups get marked as such + * @property {string} [description] - The description of the group + * @property {number} id - Automatically assigned when creating groups + * @property {boolean} [is_public] - If true, the group is public. If false, the group is private. You can't change a private group to a public group + * @property {string} name - The name of the group + * @property {string} updated_at - The time of the last update of the group + * @property {string} url - The API url of the group + */ + +/** + * @typedef {object} CreateOrUpdateGroup + * @property {RecursivePartial} group - The group to create or update + */ + /** * A client for interfacing with the Zendesk Groups API. * @see {@link https://developer.zendesk.com/api-reference/ticketing/groups/groups/} @@ -16,7 +40,7 @@ class Groups extends Client { /** * Retrieves a list of all groups. - * @returns {Promise} A promise that resolves to the list of groups. + * @returns {Promise>} A promise that resolves to the list of groups. * @throws {Error} Throws an error if the request fails. * @see {@link https://developer.zendesk.com/api-reference/ticketing/groups/groups/#list-groups} * @example @@ -67,7 +91,7 @@ class Groups extends Client { /** * Retrieves details of a specific group by its ID. * @param {number} groupID - The ID of the group. - * @returns {Promise} A promise that resolves to the group's details. + * @returns {Promise<{result: Group}>} A promise that resolves to the group's details. * @throws {Error} Throws an error if the request fails. * @see {@link https://developer.zendesk.com/api-reference/ticketing/groups/groups/#show-group} * @example @@ -79,10 +103,8 @@ class Groups extends Client { /** * Creates a new group. - * @param {object} group - The group details to create. - * @param {string} group.name - The name of the group (mandatory). - * @param {string} [group.description] - The description of the group. - * @returns {Promise} A promise that resolves to the details of the created group. + * @param {CreateOrUpdateGroup} group - The group details to create. + * @returns {Promise<{result: Group}>} A promise that resolves to the details of the created group. * @throws {Error} Throws an error if the request fails. * @see {@link https://developer.zendesk.com/api-reference/ticketing/groups/groups/#create-group} * @example @@ -99,10 +121,8 @@ class Groups extends Client { /** * Updates a specified group. * @param {number} groupID - The ID of the group to update. - * @param {object} group - The updated group details. - * @param {string} [group.name] - The updated name of the group. - * @param {string} [group.description] - The updated description of the group. - * @returns {Promise} A promise that resolves to the details of the updated group. + * @param {CreateOrUpdateGroup} group - The updated group details. + * @returns {Promise<{result: Group}>} A promise that resolves to the details of the updated group. * @throws {Error} Throws an error if the request fails. * @see {@link https://developer.zendesk.com/api-reference/ticketing/groups/groups/#update-group} * @example diff --git a/src/clients/core/sideconversations.js b/src/clients/core/sideconversations.js new file mode 100644 index 00000000..aa2ef133 --- /dev/null +++ b/src/clients/core/sideconversations.js @@ -0,0 +1,179 @@ +// File: sideconversations.js +const {Client} = require('../client'); +const {ApiTypes} = require('../../constants'); + +/** + * @typedef {object} Participant + * @property {number} [user_id] - If the participant is an agent, the agent's user id + * @property {string} [name] - The name of the participant + * @property {string} [email] - The email address of the participant + * @property {string} [slack_workspace_id] - If the participant is a Slack user or channel, the Slack workspace id + * @property {string} [slack_channel_id] - If the participant is a Slack channel, the Slack channel id + * @property {string} [support_group_id] - If the participant is a Support ticket, the support group id + * @property {string} [support_agent_id] - If the participant is a Support ticket, the support agent id + * @property {string} [msteams_channel_id] - If the participant is a Microsoft teams channel, the Teams channel id + */ + +/** + * @typedef {object} Message + * @property {string} [subject] - The subject of the message + * @property {string} [preview_text] - A plain text string describing the message + * @property {string} [body] - The plain text version of the body of the message + * @property {string} [html_body] - The HTML version of the body of the message + * @property {Participant} [from] - The participant who sent the message. See Participants + * @property {Participant[]} to - The list of participants the message was sent to. See Participants + * @property {string[]} [attachment_ids] - List of tokens received from uploading files for comment attachments. The files are attached by creating or updating tickets with the tokens. See Attaching files in Tickets + * @property {Object.} [external_ids] - A key-value object where all values are strings. Used for message metadata + */ + +/** + * @typedef {object} UpdateSideConversation + * @property {string} [subject] - The subject of the side conversation + * @property {'open' | 'closed'} [state] - A plain text string describing the side conversation + */ + +/** + * @typedef {object} SideConversation + * @property {string} created_at - The time the side conversation was created + * @property {Object.} [external_ids] - A key-value store of metadata. All values must be strings + * @property {string} id - Automatically assigned when the side conversation is created + * @property {string} message_added_at - The time of the last message on the side conversation + * @property {Participant[]} participants - An array of participants in the side conversation. See Participants + * @property {string} preview_text - A plain text text describing the side conversation + * @property {string} [state] - The state of the side conversation + * @property {string} state_updated_at - The time of the update of the state of the side conversation + * @property {string} [subject] - The subject of the side conversation + * @property {number} ticket_id - The parent ticket id of the side conversation + * @property {string} updated_at - The time of the last update of the side conversation + * @property {string} url - The API url of the side conversation + */ + +/** + * @typedef {object} SideConversationAttachment + * @property {string} content_type - The content type of the attachment. This is read-only. + * @property {number} height - The height of the attachment image. This is read-only. + * @property {string} id - The id of the side conversation attachment. This is read-only. + * @property {string} name - The name of the attachment. + * @property {number} size - The size of the attachment. This is read-only. + * @property {number} width - The width of the attachment image. This is read-only. + */ + +/** + * @typedef {object} CreateSideConversation + * @property {Message} message - The side conversation object. + * @property {Object.} [external_ids] - A key-value object where all values are strings. Used for conversation metadata + */ + +/** + * @typedef {object} SideConversationResponse + * @property {SideConversation} side_conversation - The side conversation object. + */ + +class SideConversations extends Client { + /** + * @constructs SideConversations + * @param {import('../client').ClientOptions} options - The client options. + */ + constructor(options) { + super(options, ApiTypes.core); + this.jsonAPINames = ['side_conversations']; + } + + /** + * Create a Side Conversation. + * @param {number} ticketId - The ID of the ticket. + * @param {CreateSideConversation} message - The side conversation object. + * @returns {Promise<{result: SideConversationResponse}>} The created ticket details. + * @async + * @throws {Error} If the details are not provided or invalid. + * @see https://developer.zendesk.com/api-reference/ticketing/side_conversation/side_conversation/#create-side-conversation + */ + async create(ticketId, message) { + return this.post(['tickets', ticketId, 'side_conversations'], message); + } + + /** + * Reply to a Side Conversation. + * @param {number} ticketId - The ID of the ticket. + * @param {string} sideConversationId - The ID of the side conversation. + * @param {{message: Message}} message - The reply object. + * @returns {Promise<{result: SideConversationResponse}>} The created ticket details. + * @async + * @throws {Error} If the details are not provided or invalid. + * @see https://developer.zendesk.com/api-reference/ticketing/side_conversation/side_conversation/#reply-to-side-conversation + */ + async reply(ticketId, sideConversationId, message) { + return this.post( + ['tickets', ticketId, 'side_conversations', sideConversationId, 'reply'], + message, + ); + } + + /** + * Update to a Side Conversation. + * @param {number} ticketId - The ID of the ticket. + * @param {string} sideConversationId - The ID of the side conversation. + * @param {{side_conversation: Partial}} update - The update object. + * @returns {Promise<{result: SideConversationResponse}>} The updated ticket details. + * @async + * @throws {Error} If the details are not provided or invalid. + * @see https://developer.zendesk.com/api-reference/ticketing/side_conversation/side_conversation/#update-side-conversation + */ + async update(ticketId, sideConversationId, update) { + return this.put( + ['tickets', ticketId, 'side_conversations', sideConversationId], + update, + ); + } + + /** + * List all the Side Conversations tickets. + * @param ticketID + * @returns {Promise<{result: Array}>} An array of tickets. + * @async + * @see https://developer.zendesk.com/api-reference/ticketing/side_conversation/side_conversation/#list-side-conversations + * @example + * const tickets = await client.sideconversations.list(123); + */ + async list(ticketID) { + return this.getAll(['tickets', ticketID, 'side_conversations']); + } + + /** + * Retrieve a specific ticket by its ID. + * @param {number} ticketId - The ID of the ticket. + * @param {string} sideConversationId - The ID of the side conversation. + * @returns {Promise<{result: SideConversation}>} Details of the side conversation. + * @async + * @throws {Error} If the ticket ID is not provided or invalid. + * @see https://developer.zendesk.com/api-reference/ticketing/side_conversation/side_conversation/#show-side-conversation + * @example + * const ticket = await client.sideconversations.show(12345, 12333); + */ + async show(ticketId, sideConversationId) { + return this.get([ + 'tickets', + ticketId, + 'side_conversations', + sideConversationId, + ]); + } + + /** + * Upload a file to be attached to a ticket comment. + * @param {ArrayBuffer} file - The file data. + * @param {object} options - The file options. + * @param options.filename + * @returns {Promise} The attachment details. + */ + async attachments(file, {filename}) { + const form = new FormData(); + form.append('file', new Blob([file]), filename); + return this.requestUpload( + ['tickets', 'side_conversations', 'attachments'], + form, + ); + } +} + +exports.SideConversations = SideConversations; diff --git a/src/clients/core/tickets.js b/src/clients/core/tickets.js index d96cc5f3..e5841d40 100644 --- a/src/clients/core/tickets.js +++ b/src/clients/core/tickets.js @@ -1,47 +1,104 @@ // File: tickets.js const {Client} = require('../client'); +/** + * @typedef {object} RecursivePartial + * @template T + * @property {T[P]} [P] - The property of the object. + */ + +/** + * @typedef {object} Attachment + * @property {string} content_type - The content type of the image. Example value: "image/png" + * @property {string} content_url - A full URL where the attachment image file can be downloaded. The file may be hosted externally so take care not to inadvertently send Zendesk authentication credentials. See Working with url properties + * @property {boolean} deleted - If true, the attachment has been deleted + * @property {string} file_name - The name of the image file + * @property {string} height - The height of the image file in pixels. If height is unknown, returns null + * @property {number} id - Automatically assigned when created + * @property {boolean} inline - If true, the attachment is excluded from the attachment list and the attachment's URL can be referenced within the comment of a ticket. Default is false + * @property {boolean} malware_access_override - If true, you can download an attachment flagged as malware. If false, you can't download such an attachment. + * @property {string} malware_scan_result - The result of the malware scan. There is a delay between the time the attachment is uploaded and when the malware scan is completed. Usually the scan is done within a few seconds, but high load conditions can delay the scan results. Possible values: "malware_found", "malware_not_found", "failed_to_scan", "not_scanned" + * @property {string} mapped_content_url - The URL the attachment image file has been mapped to + * @property {number} size - The size of the image file in bytes + * @property {object[]} thumbnails - An array of attachment objects. Note that photo thumbnails do not have thumbnails + * @property {string} url - A URL to access the attachment details + * @property {string} width - The width of the image file in pixels. If width is unknown, returns null + */ + +/** + * @typedef {object} TicketComment + * @property {Attachment[]} [attachments] - Attachments, if any. See Attachment + * @property {number} audit_id - The id of the ticket audit record. See Show Audit + * @property {number} author_id - The id of the comment author. See Author id + * @property {string} body - The comment string. See Bodies + * @property {string} created_at - The time the comment was created + * @property {string} html_body - The comment formatted as HTML. See Bodies + * @property {number} id - Automatically assigned when the comment is created + * @property {object} [metadata] - System information (web client, IP address, etc.) and comment flags, if any. See Comment flags + * @property {string} plain_body - The comment presented as plain text. See Bodies + * @property {boolean} public - true if a public comment; false if an internal note. The initial value set on ticket creation persists for any additional comment unless you change it + * @property {string} type - Comment or VoiceComment. The JSON object for adding voice comments to tickets is different. See Adding voice comments to tickets + * @property {string[]} [uploads] - List of tokens received from uploading files for comment attachments. The files are attached by creating or updating tickets with the tokens. See Attaching files in Tickets + * @property {object} [via] - Describes how the object was created. See the Via object reference + */ + /** * Tickets are the means through which your end users (customers) communicate with agents in Zendesk Support. * @typedef {object} Ticket * @property {boolean} allow_attachments - Permission for agents to add add attachments to a comment. Defaults to true * @property {boolean} allow_channelback - Is false if channelback is disabled, true otherwise. Only applicable for channels framework ticket - * @property {number|null} assignee_id - The agent currently assigned to the ticket - * @property {number|null} brand_id - Enterprise only. The id of the brand this ticket is associated with - * @property {Array} collaborator_ids - The ids of users currently CC'ed on the ticket + * @property {string} [assignee_email] - Write only. The email address of the agent to assign the ticket to + * @property {number} [assignee_id] - The agent currently assigned to the ticket + * @property {number[]} [attribute_value_ids] - Write only. An array of the IDs of attribute values to be associated with the ticket + * @property {number} [brand_id] - Enterprise only. The id of the brand this ticket is associated with + * @property {number[]} [collaborator_ids] - The ids of users currently CC'ed on the ticket + * @property {object[]} [collaborators] - POST requests only. Users to add as cc's when creating a ticket. See Setting Collaborators + * @property {TicketComment} [comment] - Write only. An object that adds a comment to the ticket. See Ticket comments. To include an attachment with the comment, see Attaching files * @property {string} created_at - When this record was created - * @property {Array} custom_fields - Custom fields for the ticket - * @property {number} custom_status_id - The custom ticket status id of the ticket - * @property {string} description - Read-only first comment on the ticket. When creating a ticket, use comment to set the description - * @property {string|null} due_at - If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format - * @property {Array} email_cc_ids - The ids of agents or end users currently CC'ed on the ticket - * @property {string|null} external_id - An id you can use to link Zendesk Support tickets to local records - * @property {Array} follower_ids - The ids of agents currently following the ticket - * @property {Array} followup_ids - The ids of the followups created from this ticket. Ids are only visible once the ticket is closed - * @property {number|null} forum_topic_id - The topic in the Zendesk Web portal this ticket originated from, if any. The Web portal is deprecated + * @property {Array} [custom_fields] - Custom fields for the ticket. See Setting custom field values + * @property {number} [custom_status_id] - The custom ticket status id of the ticket. See custom ticket statuses + * @property {string} description - Read-only first comment on the ticket. When creating a ticket, use comment to set the description. See Description and first comment + * @property {string} [due_at] - If this is a ticket of type "task" it has a due date. Due date format uses ISO 8601 format. + * @property {number[]} [email_cc_ids] - The ids of agents or end users currently CC'ed on the ticket. See CCs and followers resources in the Support Help Center + * @property {object} [email_ccs] - Write only. An array of objects that represent agent or end users email CCs to add or delete from the ticket. See Setting email CCs + * @property {string} [external_id] - An id you can use to link Zendesk Support tickets to local records + * @property {number[]} [follower_ids] - The ids of agents currently following the ticket. See CCs and followers resources + * @property {object} [followers] - Write only. An array of objects that represent agent followers to add or delete from the ticket. See Setting followers + * @property {number[]} followup_ids - The ids of the followups created from this ticket. Ids are only visible once the ticket is closed + * @property {number} [forum_topic_id] - The topic in the Zendesk Web portal this ticket originated from, if any. The Web portal is deprecated * @property {boolean} from_messaging_channel - If true, the ticket's via type is a messaging channel. - * @property {number|null} group_id - The group this ticket is assigned to + * @property {number} [group_id] - The group this ticket is assigned to * @property {boolean} has_incidents - Is true if a ticket is a problem type and has one or more incidents linked to it. Otherwise, the value is false. * @property {number} id - Automatically assigned when the ticket is created * @property {boolean} is_public - Is true if any comments are public, false otherwise - * @property {number|null} organization_id - The organization of the requester. You can only specify the ID of an organization associated with the requester - * @property {Priority} priority - The urgency with which the ticket should be addressed. Allowed values are "urgent", "high", "normal", or "low" - * @property {number|null} problem_id - For tickets of type "incident", the ID of the problem the incident is linked to - * @property {string} raw_subject - The dynamic content placeholder, if present, or the "subject" value, if not - * @property {string|null} recipient - The original recipient e-mail address of the ticket. Notification emails for the ticket are sent from this address + * @property {number} [macro_id] - Write only. A macro ID to be recorded in the ticket audit + * @property {number[]} [macro_ids] - POST requests only. List of macro IDs to be recorded in the ticket audit + * @property {object} [metadata] - Write only. Metadata for the audit. In the audit object, the data is specified in the custom property of the metadata object. See Setting Metadata + * @property {number} [organization_id] - The organization of the requester. You can only specify the ID of an organization associated with the requester. See Organization Memberships + * @property {Priority} [priority] - The urgency with which the ticket should be addressed. Allowed values are "urgent", "high", "normal", or "low". + * @property {number} [problem_id] - For tickets of type "incident", the ID of the problem the incident is linked to + * @property {string} [raw_subject] - The dynamic content placeholder, if present, or the "subject" value, if not. See Dynamic Content Items + * @property {string} [recipient] - The original recipient e-mail address of the ticket. Notification emails for the ticket are sent from this address + * @property {object} [requester] - Write only. See Creating a ticket with a new requester * @property {number} requester_id - The user who requested this ticket - * @property {object} satisfaction_rating - The satisfaction rating of the ticket, if it exists, or the state of satisfaction, "offered" or "unoffered". The value is null for plan types that don't support CSAT - * @property {Array} sharing_agreement_ids - The ids of the sharing agreements used for this ticket - * @property {Status} status - The state of the ticket. If your account has activated custom ticket statuses, this is the ticket's status category. See custom ticket statuses. Allowed values are "new", "open", "pending", "hold", "solved", or "closed". - * @property {string} subject - The value of the subject field for this ticket - * @property {number} submitter_id - The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket - * @property {Array} tags - The array of tags applied to this ticket - * @property {number} ticket_form_id - Enterprise only. The id of the ticket form to render for the ticket - * @property {Type} type - The type of this ticket. Allowed values are "problem", "incident", "question", or "task". + * @property {boolean} [safe_update] - Write only. Optional boolean. When true and an update_stamp date is included, protects against ticket update collisions and returns a message to let you know if one occurs. See Protecting against ticket update collisions. A value of false has the same effect as true. Omit the property to force the updates to not be safe + * @property {object} [satisfaction_rating] - The satisfaction rating of the ticket, if it exists, or the state of satisfaction, "offered" or "unoffered". The value is null for plan types that don't support CSAT + * @property {number[]} [sharing_agreement_ids] - The ids of the sharing agreements used for this ticket + * @property {Status} [status] - The state of the ticket. If your account has activated custom ticket statuses, this is the ticket's status category. See custom ticket statuses. Allowed values are "new", "open", "pending", "hold", "solved", or "closed". + * @property {string} [subject] - The value of the subject field for this ticket + * @property {number} [submitter_id] - The user who submitted the ticket. The submitter always becomes the author of the first comment on the ticket + * @property {string[]} [tags] - The array of tags applied to this ticket + * @property {number} [ticket_form_id] - Enterprise only. The id of the ticket form to render for the ticket + * @property {Type} [type] - The type of this ticket. Allowed values are "problem", "incident", "question", or "task". * @property {string} updated_at - When this record last got updated + * @property {string} [updated_stamp] - Write only. Datetime of last update received from API. See the safe_update property * @property {string} url - The API url of this ticket - * @property {object} via - For more information, see the Via object reference + * @property {object} [via] - For more information, see the Via object reference + * @property {number} [via_followup_source_id] - POST requests only. The id of a closed ticket when creating a follow-up ticket. See Creating a follow-up ticket + * @property {number} [via_id] - Write only. For more information, see the Via object reference + * @property {object} [voice_comment] - Write only. See Creating voicemail ticket */ + /** * @typedef {object} CustomField * @property {number} id - The ID of the custom field. @@ -57,6 +114,11 @@ const {Client} = require('../client'); * @typedef {'problem' |'incident' | 'question' | 'task'} Type */ +/** + * @typedef {T extends object ? { [K in keyof T]?: RecursivePartial } : T} RecursivePartial + * @template T + */ + /** * @class * Client for the Zendesk API - Tickets. @@ -215,7 +277,7 @@ class Tickets extends Client { /** * Retrieve a specific ticket by its ID. * @param {number} ticketId - The ID of the ticket. - * @returns {Promise} Details of the ticket. + * @returns {Promise<{result: Ticket}>} Details of the ticket. * @async * @throws {Error} If the ticket ID is not provided or invalid. * @see {@link https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#show-ticket} @@ -241,8 +303,8 @@ class Tickets extends Client { /** * Create a new ticket. - * @param {object} ticket - Details of the ticket to be created. - * @returns {Promise} The created ticket details. + * @param {CreateOrUpdateTicket} ticket - Details of the ticket to be created. + * @returns {Promise<{result: Ticket}>} The created ticket details. * @async * @throws {Error} If the ticket details are not provided or invalid. * @see {@link https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#create-ticket} @@ -255,7 +317,7 @@ class Tickets extends Client { /** * Create multiple new tickets. - * @param {Array} tickets - An array of ticket objects to create. + * @param {Array} tickets - An array of ticket objects to create. * @returns {Promise>} A promise that resolves to an array of created ticket objects. * @async * @throws {Error} If the provided `tickets` is not an array or is empty. @@ -275,8 +337,8 @@ class Tickets extends Client { /** * Update an existing ticket by its ID. * @param {number} ticketId - The ID of the ticket to update. - * @param {object} ticket - The updated ticket data as an object. - * @returns {Promise} A promise that resolves to the updated ticket object. + * @param {CreateOrUpdateTicket} ticket - The updated ticket data as an object. + * @returns {Promise<{result: Ticket}>} A promise that resolves to the updated ticket object. * @async * @throws {Error} If `ticketId` is not a number or if `ticket` is not an object. * @see {@link https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/#update-ticket} diff --git a/src/clients/core/users.js b/src/clients/core/users.js index 197f8ab9..1759998d 100644 --- a/src/clients/core/users.js +++ b/src/clients/core/users.js @@ -1,6 +1,49 @@ // File: users.js const {Client} = require('../client'); +/** + * @typedef {object} User + * @property {boolean} active - false if the user has been deleted + * @property {string} [alias] - An alias displayed to end users + * @property {boolean} chat_only - Whether or not the user is a chat-only agent + * @property {string} created_at - The time the user was created + * @property {number} [custom_role_id] - A custom role if the user is an agent on the Enterprise plan or above + * @property {number} [default_group_id] - The id of the user's default group + * @property {string} [details] - Any details you want to store about the user, such as an address + * @property {string} [email] - The user's primary email address. *Writeable on create only. On update, a secondary email is added. See Email Address + * @property {string} [external_id] - A unique identifier from another system. The API treats the id as case insensitive. Example: "ian1" and "IAN1" are the same value. + * @property {string} iana_time_zone - The time zone for the user + * @property {number} id - Automatically assigned when the user is created + * @property {string} last_login_at - Last time the user signed in to Zendesk Support or made an API request using an API token or basic authentication + * @property {string} [locale] - The user's locale. A BCP-47 compliant tag for the locale. If both "locale" and "locale_id" are present on create or update, "locale_id" is ignored and only "locale" is used. + * @property {number} [locale_id] - The user's language identifier + * @property {boolean} [moderator] - Designates whether the user has forum moderation capabilities + * @property {string} name - The user's name + * @property {string} [notes] - Any notes you want to store about the user + * @property {boolean} [only_private_comments] - true if the user can only create private comments + * @property {number} [organization_id] - The id of the user's organization. If the user has more than one organization memberships, the id of the user's default organization. If updating, see Organization ID + * @property {string} [phone] - The user's primary phone number. See Phone Number below + * @property {object} [photo] - The user's profile picture represented as an Attachment object + * @property {string} [remote_photo_url] - A URL pointing to the user's profile picture. + * @property {boolean} report_csv - This parameter is inert and has no effect. It may be deprecated in the future. Previously, this parameter determined whether a user could access a CSV report in a legacy Guide dashboard. This dashboard has been removed. See Announcing Guide legacy reporting upgrade to Explore + * @property {boolean} [restricted_agent] - If the agent has any restrictions; false for admins and unrestricted agents, true for other agents + * @property {string} [role] - The user's role. Possible values are "end-user", "agent", or "admin" + * @property {number} role_type - The user's role id. 0 for a custom agent, 1 for a light agent, 2 for a chat agent, 3 for a chat agent added to the Support account as a contributor (Chat Phase 4), 4 for an admin, and 5 for a billing admin + * @property {boolean} shared - If the user is shared from a different Zendesk Support instance. Ticket sharing accounts only + * @property {boolean} shared_agent - If the user is a shared agent from a different Zendesk Support instance. Ticket sharing accounts only + * @property {boolean} [shared_phone_number] - Whether the phone number is shared or not. See Phone Number below + * @property {string} [signature] - The user's signature. Only agents and admins can have signatures + * @property {boolean} [suspended] - If the agent is suspended. Tickets from suspended users are also suspended, and these users cannot sign in to the end user portal + * @property {string[]} [tags] - The user's tags. Only present if your account has user tagging enabled + * @property {string} [ticket_restriction] - Specifies which tickets the user has access to. Possible values are: "organization", "groups", "assigned", "requested", null. "groups" and "assigned" are valid only for agents. If you pass an invalid value to an end user (for example, "groups"), they will be assigned to "requested", regardless of their previous access + * @property {string} [time_zone] - The user's time zone. See Time Zone + * @property {boolean} two_factor_auth_enabled - If two factor authentication is enabled + * @property {string} updated_at - The time the user was last updated + * @property {string} url - The user's API url + * @property {object} [user_fields] - Values of custom fields in the user's profile. See User Fields + * @property {boolean} [verified] - Any of the user's identities is verified. See User Identities + */ + /** * Client for the Zendesk Users API. * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/} @@ -42,7 +85,7 @@ class Users extends Client { /** * Lists all users. - * @returns {Promise>} An array of user objects. + * @returns {Promise>} An array of user objects. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#list-users} * @example @@ -56,7 +99,7 @@ class Users extends Client { * Lists users with a specific filter. * @param {string} type - The type of filter. * @param {string|number} value - The value for the filter. - * @returns {Promise>} An array of user objects. + * @returns {Promise>} An array of user objects. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#list-users} * @example @@ -69,7 +112,7 @@ class Users extends Client { /** * Lists users by group ID. * @param {number} id - The ID of the group. - * @returns {Promise>} An array of user objects. + * @returns {Promise>} An array of user objects. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#list-users} * @example @@ -82,7 +125,7 @@ class Users extends Client { /** * Lists users by organization ID. * @param {number} id - The ID of the organization. - * @returns {Promise>} An array of user objects. + * @returns {Promise>} An array of user objects. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#list-users} * @example @@ -95,7 +138,7 @@ class Users extends Client { /** * Shows details of a user by ID. * @param {number} id - The ID of the user. - * @returns {Promise} The user's details. + * @returns {Promise} The user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#show-user} * @example @@ -108,7 +151,7 @@ class Users extends Client { /** * Shows details of multiple users by their IDs. * @param {Array} userIds - An array of user IDs. - * @returns {Promise>} An array of user details. + * @returns {Promise>} An array of user details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#show-many-users} * @example @@ -121,7 +164,7 @@ class Users extends Client { /** * Creates a new user. * @param {object} user - The user details. - * @returns {Promise} The created user's details. + * @returns {Promise} The created user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#create-user} * @example @@ -134,7 +177,7 @@ class Users extends Client { /** * Creates multiple users. * @param {Array} users - An array of user details. - * @returns {Promise>} An array of created user details. + * @returns {Promise>} An array of created user details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#create-many-users} * @example @@ -147,7 +190,7 @@ class Users extends Client { /** * Creates or updates a user. * @param {object} user - The user details. - * @returns {Promise} The created or updated user's details. + * @returns {Promise} The created or updated user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#create-or-update-user} * @example @@ -160,7 +203,7 @@ class Users extends Client { /** * Creates or updates multiple users. * @param {Array} users - An array of user details. - * @returns {Promise>} An array of created or updated user details. + * @returns {Promise>} An array of created or updated user details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#create-or-update-many-users} * @example @@ -174,7 +217,7 @@ class Users extends Client { * Updates a user by ID. * @param {number} id - The ID of the user. * @param {object} user - The updated user details. - * @returns {Promise} The updated user's details. + * @returns {Promise} The updated user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#update-user} * @example @@ -187,7 +230,7 @@ class Users extends Client { /** * Updates multiple users. * @param {...*} args - Arguments including optional IDs and user details. - * @returns {Promise>} An array of updated user details. + * @returns {Promise>} An array of updated user details. * @async * @throws {Error} Throws an error if not enough arguments are provided. * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#update-many-users} @@ -248,7 +291,7 @@ class Users extends Client { /** * Suspends a user by ID. * @param {number} id - The ID of the user to suspend. - * @returns {Promise} The suspended user's details. + * @returns {Promise} The suspended user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#suspend-user} * @example @@ -261,7 +304,7 @@ class Users extends Client { /** * Unsuspends a user by ID. * @param {number} id - The ID of the user to unsuspend. - * @returns {Promise} The unsuspended user's details. + * @returns {Promise} The unsuspended user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#unsuspend-user} * @example @@ -349,7 +392,7 @@ class Users extends Client { /** * Searches for users based on specific parameters. * @param {object} parameters - The search parameters. - * @returns {Promise>} An array of user objects that match the search criteria. + * @returns {Promise>} An array of user objects that match the search criteria. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#search-users} * @example @@ -361,7 +404,7 @@ class Users extends Client { /** * Retrieves details of the currently authenticated user. - * @returns {Promise} The user's details.The authenticated user's details. + * @returns {Promise<{result: User}>} The user's details.The authenticated user's details. * @async * @see {@link https://developer.zendesk.com/api-reference/ticketing/users/users/#show-the-currently-authenticated-user} * @example diff --git a/src/clients/transporter.js b/src/clients/transporter.js index 89475090..686e8e19 100644 --- a/src/clients/transporter.js +++ b/src/clients/transporter.js @@ -55,19 +55,25 @@ class Transporter { async upload(uri, file) { const method = 'POST'; - const isBinary = file instanceof require('node:stream').Stream; + const isStream = file instanceof require('node:stream').Stream; + const isFormData = file instanceof FormData; const headers = this.getHeadersForRequest(); - if (isBinary) { + if (isFormData) { + headers['Content-Type'] = 'multipart/form-data'; + } + + if (isStream) { headers['Content-Type'] = 'application/binary'; } + const isDirectUpload = isStream || isFormData; const options = { ...this.options, headers, uri: assembleUrl(this, method, uri), method, - body: isBinary ? file : require('node:fs').createReadStream(file), + body: isDirectUpload ? file : require('node:fs').createReadStream(file), }; return this.sendRequest(options); } @@ -96,6 +102,10 @@ class Transporter { const bodyContent = isBinary ? body : this.getBodyForRequest(method, body); const headers = this.getHeadersForRequest(); + if (body instanceof FormData) { + headers['Content-Type'] = 'multipart/form-data'; + } + if (isBinary) { headers['Content-Type'] = 'application/binary'; } diff --git a/src/index.js b/src/index.js index e720c0a9..d490b2c8 100644 --- a/src/index.js +++ b/src/index.js @@ -127,6 +127,9 @@ class ZendeskClient { return this._instantiate(GroupMemberships); } + /** + * @returns {Groups} + */ get groups() { const {Groups} = require('./clients/core/groups'); return this._instantiate(Groups); @@ -219,6 +222,14 @@ class ZendeskClient { return this._instantiate(SharingAgreement); } + /** + * @returns {SideConversations} + */ + get sideconversations() { + const {SideConversations} = require('./clients/core/sideconversations'); + return this._instantiate(SideConversations); + } + get suspendedtickets() { const {SuspendedTickets} = require('./clients/core/suspendedtickets'); return this._instantiate(SuspendedTickets); @@ -264,11 +275,17 @@ class ZendeskClient { return this._instantiate(TicketImport); } + /** + * @returns {TicketMetrics} + */ get ticketmetrics() { const {TicketMetrics} = require('./clients/core/ticketmetrics'); return this._instantiate(TicketMetrics); } + /** + * @returns {Tickets} + */ get tickets() { const {Tickets} = require('./clients/core/tickets'); return this._instantiate(Tickets); @@ -289,6 +306,9 @@ class ZendeskClient { return this._instantiate(UserIdentities); } + /** + * @returns {Users} + */ get users() { const {Users} = require('./clients/core/users'); return this._instantiate(Users); diff --git a/test/setup.js b/test/setup.js index 015b55eb..1398dc8d 100644 --- a/test/setup.js +++ b/test/setup.js @@ -8,7 +8,8 @@ dotenv.config({ path: '.env.test', }); -const {ZENDESK_USERNAME, ZENDESK_SUBDOMAIN, ZENDESK_TOKEN} = process.env; +const {ZENDESK_USERNAME, ZENDESK_SUBDOMAIN, ZENDESK_PASSWORD, ZENDESK_TOKEN} = + process.env; export const generateOrganizationName = (id) => { return `Test Organization ${id}`; @@ -33,10 +34,16 @@ export const initializeClient = (config) => { }); }; +/** + * + * @param {import('../src/clients/client').ClientOptions} config + * @returns {ZendeskClient} + */ export const setupClient = (config = {}) => createClient({ username: ZENDESK_USERNAME, subdomain: ZENDESK_SUBDOMAIN, + password: ZENDESK_PASSWORD, token: ZENDESK_TOKEN, ...config, });