diff --git a/CHANGELOG.md b/CHANGELOG.md index 6294a7d1..38f3e633 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Added * Added support for sending drafts +* Added support for the contacts API ### Changed * Fixed issue with sending scheduled messages diff --git a/src/main/kotlin/com/nylas/models/Contact.kt b/src/main/kotlin/com/nylas/models/Contact.kt new file mode 100644 index 00000000..534d0537 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/Contact.kt @@ -0,0 +1,59 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a Nylas contact object + */ +data class Contact( + @Json(name = "id") + val id: String = "", + @Json(name = "grant_id") + val grantId: String = "", + @Json(name = "object") + private val obj: String = "contact", + @Json(name = "birthday") + val birthday: String? = null, + @Json(name = "company_name") + val companyName: String? = null, + @Json(name = "display_name") + val displayName: String = "", + @Json(name = "emails") + val emails: List? = null, + @Json(name = "im_addresses") + val imAddresses: List? = null, + @Json(name = "given_name") + val givenName: String? = null, + @Json(name = "job_title") + val jobTitle: String? = null, + @Json(name = "manager_name") + val managerName: String? = null, + @Json(name = "middle_name") + val middleName: String? = null, + @Json(name = "nickname") + val nickname: String? = null, + @Json(name = "notes") + val notes: String? = null, + @Json(name = "office_location") + val officeLocation: String? = null, + @Json(name = "picture_url") + val pictureUrl: String? = null, + @Json(name = "picture") + val picture: String? = null, + @Json(name = "suffix") + val suffix: String? = null, + @Json(name = "surname") + val surname: String? = null, + @Json(name = "source") + val source: SourceType? = null, + @Json(name = "phone_numbers") + val phoneNumbers: List? = null, + @Json(name = "physical_addresses") + val physicalAddresses: List? = null, + @Json(name = "web_pages") + val webPages: List? = null, + @Json(name = "groups") + val groups: List? = null, +) { + fun getObject() = obj +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/ContactEmail.kt b/src/main/kotlin/com/nylas/models/ContactEmail.kt new file mode 100644 index 00000000..1f4cdf2c --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ContactEmail.kt @@ -0,0 +1,18 @@ +package com.nylas.models + +/** + * Interface for email addresses in a contact. + */ +data class ContactEmail( + val email: String? = null, + val type: ContactType? = null, +) { + class Builder { + private var email: String? = null + private var type: ContactType? = null + + fun email(email: String) = apply { this.email = email } + fun type(type: ContactType) = apply { this.type = type } + fun build() = ContactEmail(email, type) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/ContactGroup.kt b/src/main/kotlin/com/nylas/models/ContactGroup.kt new file mode 100644 index 00000000..664ab5f4 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ContactGroup.kt @@ -0,0 +1,15 @@ +package com.nylas.models + +/** + * Class representing a contact group. + */ +data class ContactGroup( + val id: String, + val grantId: String? = null, + val groupType: GroupType? = null, + val name: String? = null, + val path: String? = null, + private val obj: String = "contact_group", +) { + fun getObject() = obj +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/ContactGroupId.kt b/src/main/kotlin/com/nylas/models/ContactGroupId.kt new file mode 100644 index 00000000..7b770ae6 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ContactGroupId.kt @@ -0,0 +1,8 @@ +package com.nylas.models + +/** + * Class representing an object that points to a contact group ID. + */ +data class ContactGroupId( + val id: String, +) \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/ContactType.kt b/src/main/kotlin/com/nylas/models/ContactType.kt new file mode 100644 index 00000000..2b816aa7 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ContactType.kt @@ -0,0 +1,14 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +enum class ContactType { + @Json(name = "work") + WORK, + + @Json(name = "home") + HOME, + + @Json(name = "other") + OTHER, +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/CreateContactRequest.kt b/src/main/kotlin/com/nylas/models/CreateContactRequest.kt new file mode 100644 index 00000000..fb7a823c --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateContactRequest.kt @@ -0,0 +1,113 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class CreateContactRequest( + @Json(name = "display_name") + val displayName: String? = null, + @Json(name = "birthday") + val birthday: String? = null, + @Json(name = "company_name") + val companyName: String? = null, + @Json(name = "emails") + val emails: List? = null, + @Json(name = "given_name") + val givenName: String? = null, + @Json(name = "im_addresses") + val imAddresses: List? = null, + @Json(name = "job_title") + val jobTitle: String? = null, + @Json(name = "manager_name") + val managerName: String? = null, + @Json(name = "middle_name") + val middleName: String? = null, + @Json(name = "nickname") + val nickname: String? = null, + @Json(name = "notes") + val notes: String? = null, + @Json(name = "office_location") + val officeLocation: String? = null, + @Json(name = "phone_numbers") + val phoneNumbers: List? = null, + @Json(name = "physical_addresses") + val physicalAddresses: List? = null, + @Json(name = "suffix") + val suffix: String? = null, + @Json(name = "surname") + val surname: String? = null, + @Json(name = "web_pages") + val webPages: List? = null, + @Json(name = "picture") + val picture: String? = null, + @Json(name = "source") + val source: SourceType? = null, + @Json(name = "groups") + val groups: List? = null, +) { + class Builder { + private var displayName: String? = null + private var birthday: String? = null + private var companyName: String? = null + private var emails: List? = null + private var givenName: String? = null + private var imAddresses: List? = null + private var jobTitle: String? = null + private var managerName: String? = null + private var middleName: String? = null + private var nickname: String? = null + private var notes: String? = null + private var officeLocation: String? = null + private var phoneNumbers: List? = null + private var physicalAddresses: List? = null + private var suffix: String? = null + private var surname: String? = null + private var webPages: List? = null + private var picture: String? = null + private var source: SourceType? = null + private var groups: List? = null + + fun displayName(displayName: String?) = apply { this.displayName = displayName } + fun birthday(birthday: String?) = apply { this.birthday = birthday } + fun companyName(companyName: String?) = apply { this.companyName = companyName } + fun emails(emails: List?) = apply { this.emails = emails } + fun givenName(givenName: String?) = apply { this.givenName = givenName } + fun imAddresses(imAddresses: List?) = apply { this.imAddresses = imAddresses } + fun jobTitle(jobTitle: String?) = apply { this.jobTitle = jobTitle } + fun managerName(managerName: String?) = apply { this.managerName = managerName } + fun middleName(middleName: String?) = apply { this.middleName = middleName } + fun nickname(nickname: String?) = apply { this.nickname = nickname } + fun notes(notes: String?) = apply { this.notes = notes } + fun officeLocation(officeLocation: String?) = apply { this.officeLocation = officeLocation } + fun phoneNumbers(phoneNumbers: List?) = apply { this.phoneNumbers = phoneNumbers } + fun physicalAddresses(physicalAddresses: List?) = apply { this.physicalAddresses = physicalAddresses } + fun suffix(suffix: String?) = apply { this.suffix = suffix } + fun surname(surname: String?) = apply { this.surname = surname } + fun webPages(webPages: List?) = apply { this.webPages = webPages } + fun picture(picture: String?) = apply { this.picture = picture } + fun source(source: SourceType?) = apply { this.source = source } + fun groups(groups: List?) = apply { this.groups = groups } + + fun build() = CreateContactRequest( + displayName = displayName, + birthday = birthday, + companyName = companyName, + emails = emails, + givenName = givenName, + imAddresses = imAddresses, + jobTitle = jobTitle, + managerName = managerName, + middleName = middleName, + nickname = nickname, + notes = notes, + officeLocation = officeLocation, + phoneNumbers = phoneNumbers, + physicalAddresses = physicalAddresses, + suffix = suffix, + surname = surname, + webPages = webPages, + picture = picture, + source = source, + groups = groups, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/FindContactQueryParams.kt b/src/main/kotlin/com/nylas/models/FindContactQueryParams.kt new file mode 100644 index 00000000..9fefb24a --- /dev/null +++ b/src/main/kotlin/com/nylas/models/FindContactQueryParams.kt @@ -0,0 +1,8 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class FindContactQueryParams( + @Json(name = "profile_picture") + val profilePicture: Boolean? = null, +): IQueryParams diff --git a/src/main/kotlin/com/nylas/models/GroupType.kt b/src/main/kotlin/com/nylas/models/GroupType.kt new file mode 100644 index 00000000..6900f2b2 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/GroupType.kt @@ -0,0 +1,12 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +enum class GroupType { + @Json(name = "user") + USER, + @Json(name = "system") + SYSTEM, + @Json(name = "other") + OTHER +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/InstantMessagingAddress.kt b/src/main/kotlin/com/nylas/models/InstantMessagingAddress.kt new file mode 100644 index 00000000..6db3b788 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/InstantMessagingAddress.kt @@ -0,0 +1,18 @@ +package com.nylas.models + +/** + * Class representation for an IM address in a contact. + */ +data class InstantMessagingAddress( + val imAddress: String? = null, + val type: ContactType? = null, +) { + class Builder { + private var imAddress: String? = null + private var type: ContactType? = null + + fun imAddress(imAddress: String) = apply { this.imAddress = imAddress } + fun type(type: ContactType) = apply { this.type = type } + fun build() = InstantMessagingAddress(imAddress, type) + } +} diff --git a/src/main/kotlin/com/nylas/models/ListContactGroupsQueryParams.kt b/src/main/kotlin/com/nylas/models/ListContactGroupsQueryParams.kt new file mode 100644 index 00000000..880e5fed --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ListContactGroupsQueryParams.kt @@ -0,0 +1,48 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class ListContactGroupsQueryParams( + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + @Json(name = "limit") + val limit: Int? = null, + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + @Json(name = "page_token") + val pageToken: String? = null, +) : IQueryParams { + /** + * Builder for [ListContactGroupsQueryParams]. + */ + class Builder { + private var limit: Int? = null + private var pageToken: String? = null + + /** + * Set the maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + * @param limit The maximum number of objects to return. + * @return The builder. + */ + fun limit(limit: Int?) = apply { this.limit = limit } + + /** + * Set the identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + * @param pageToken The identifier that specifies which page of data to return. + * @return The builder. + */ + fun pageToken(pageToken: String?) = apply { this.pageToken = pageToken } + + /** + * Build the [ListContactGroupsQueryParams] object. + * @return The [ListContactGroupsQueryParams] object. + */ + fun build() = ListContactGroupsQueryParams(limit, pageToken) + } +} diff --git a/src/main/kotlin/com/nylas/models/ListContactsQueryParams.kt b/src/main/kotlin/com/nylas/models/ListContactsQueryParams.kt new file mode 100644 index 00000000..7b3406ad --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ListContactsQueryParams.kt @@ -0,0 +1,123 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for listing calendars. + */ +data class ListContactsQueryParams( + /** + * The maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + */ + @Json(name = "limit") + val limit: Int? = null, + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + @Json(name = "page_token") + val pageToken: String? = null, + /** + * Returns the contacts matching the exact contact's email. + */ + @Json(name = "email") + val email: String? = null, + /** + * Returns the contacts matching the contact's exact phone number + */ + @Json(name = "phone_number") + val phoneNumber: String? = null, + /** + * Returns the contacts matching from the address book or auto-generated contacts from emails. + * For example of contacts only from the address book: /contacts?source=address_bookor for only autogenerated contacts:/contacts?source=inbox` + */ + @Json(name = "source") + val source: SourceType? = null, + /** + * Returns the contacts belonging to the Contact Group matching this ID + */ + @Json(name = "group") + val group: String? = null, + /** + * When set to true, returns the contacts also within the specified Contact Group subgroups, if the group parameter is set. + */ + @Json(name = "recurse") + val recurse: Boolean? = null, +): IQueryParams { + class Builder { + private var limit: Int? = null + private var pageToken: String? = null + private var email: String? = null + private var phoneNumber: String? = null + private var source: SourceType? = null + private var group: String? = null + private var recurse: Boolean? = null + + /** + * Sets the maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + * @param limit The maximum number of objects to return. + * @return The builder. + */ + fun limit(limit: Int?) = apply { this.limit = limit } + + /** + * Sets the identifier that specifies which page of data to return. + * This value should be taken from the next_cursor response field. + * @param pageToken The identifier that specifies which page of data to return. + * @return The builder. + */ + fun pageToken(pageToken: String?) = apply { this.pageToken = pageToken } + + /** + * Sets the contacts matching the exact contact's email. + * @param email The contacts matching the exact contact's email. + * @return The builder. + */ + fun email(email: String?) = apply { this.email = email } + + /** + * Sets the contacts matching the contact's exact phone number + * @param phoneNumber The contacts matching the contact's exact phone number + * @return The builder. + */ + fun phoneNumber(phoneNumber: String?) = apply { this.phoneNumber = phoneNumber } + + /** + * Sets the contacts matching from the address book or auto-generated contacts from emails. + * For example of contacts only from the address book: /contacts?source=address_bookor for only autogenerated contacts:/contacts?source=inbox` + * @param source The contacts matching from the address book or auto-generated contacts from emails. + * @return The builder. + */ + fun source(source: SourceType?) = apply { this.source = source } + + /** + * Sets the contacts belonging to the Contact Group matching this ID + * @param group The contacts belonging to the Contact Group matching this ID + * @return The builder. + */ + fun group(group: String?) = apply { this.group = group } + + /** + * Sets the contacts also within the specified Contact Group subgroups, if the group parameter is set. + * @param recurse The contacts also within the specified Contact Group subgroups, if the group parameter is set. + * @return The builder. + */ + fun recurse(recurse: Boolean?) = apply { this.recurse = recurse } + + /** + * Builds a [ListContactsQueryParams] instance. + * @return The [ListContactsQueryParams] instance. + */ + fun build() = ListContactsQueryParams( + limit = limit, + pageToken = pageToken, + email = email, + phoneNumber = phoneNumber, + source = source, + group = group, + recurse = recurse, + ) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/PhoneNumber.kt b/src/main/kotlin/com/nylas/models/PhoneNumber.kt new file mode 100644 index 00000000..bd4d8719 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/PhoneNumber.kt @@ -0,0 +1,18 @@ +package com.nylas.models + +/** + * Class representation for phone numbers in a contact. + */ +data class PhoneNumber( + val number: String? = null, + val type: ContactType? = null, +) { + class Builder { + private var number: String? = null + private var type: ContactType? = null + + fun number(number: String) = apply { this.number = number } + fun type(type: ContactType) = apply { this.type = type } + fun build() = PhoneNumber(number, type) + } +} diff --git a/src/main/kotlin/com/nylas/models/PhysicalAddress.kt b/src/main/kotlin/com/nylas/models/PhysicalAddress.kt new file mode 100644 index 00000000..3479e47c --- /dev/null +++ b/src/main/kotlin/com/nylas/models/PhysicalAddress.kt @@ -0,0 +1,42 @@ +package com.nylas.models + +/** + * Class representation for a physical address in a contact. + */ +data class PhysicalAddress( + val format: String? = null, + val streetAddress: String? = null, + val city: String? = null, + val postalCode: String? = null, + val state: String? = null, + val country: String? = null, + val type: ContactType? = null, +) { + class Builder { + private var format: String? = null + private var streetAddress: String? = null + private var city: String? = null + private var postalCode: String? = null + private var state: String? = null + private var country: String? = null + private var type: ContactType? = null + + fun format(format: String) = apply { this.format = format } + fun streetAddress(streetAddress: String) = apply { this.streetAddress = streetAddress } + fun city(city: String) = apply { this.city = city } + fun postalCode(postalCode: String) = apply { this.postalCode = postalCode } + fun state(state: String) = apply { this.state = state } + fun country(country: String) = apply { this.country = country } + fun type(type: ContactType) = apply { this.type = type } + + fun build() = PhysicalAddress( + format = format, + streetAddress = streetAddress, + city = city, + postalCode = postalCode, + state = state, + country = country, + type = type, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/SourceType.kt b/src/main/kotlin/com/nylas/models/SourceType.kt new file mode 100644 index 00000000..8d7f5887 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/SourceType.kt @@ -0,0 +1,12 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +enum class SourceType { + @Json(name = "address_book") + ADDRESS_BOOK, + @Json(name = "inbox") + INBOX, + @Json(name = "domain") + DOMAIN +} \ No newline at end of file diff --git a/src/main/kotlin/com/nylas/models/UpdateContactRequest.kt b/src/main/kotlin/com/nylas/models/UpdateContactRequest.kt new file mode 100644 index 00000000..0e006d26 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/UpdateContactRequest.kt @@ -0,0 +1,113 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class UpdateContactRequest( + @Json(name = "display_name") + val displayName: String? = null, + @Json(name = "birthday") + val birthday: String? = null, + @Json(name = "company_name") + val companyName: String? = null, + @Json(name = "emails") + val emails: List? = null, + @Json(name = "given_name") + val givenName: String? = null, + @Json(name = "im_addresses") + val imAddresses: List? = null, + @Json(name = "job_title") + val jobTitle: String? = null, + @Json(name = "manager_name") + val managerName: String? = null, + @Json(name = "middle_name") + val middleName: String? = null, + @Json(name = "nickname") + val nickname: String? = null, + @Json(name = "notes") + val notes: String? = null, + @Json(name = "office_location") + val officeLocation: String? = null, + @Json(name = "phone_numbers") + val phoneNumbers: List? = null, + @Json(name = "physical_addresses") + val physicalAddresses: List? = null, + @Json(name = "suffix") + val suffix: String? = null, + @Json(name = "surname") + val surname: String? = null, + @Json(name = "web_pages") + val webPages: List? = null, + @Json(name = "picture") + val picture: String? = null, + @Json(name = "source") + val source: SourceType? = null, + @Json(name = "groups") + val groups: List? = null, +) { + class Builder { + private var displayName: String? = null + private var birthday: String? = null + private var companyName: String? = null + private var emails: List? = null + private var givenName: String? = null + private var imAddresses: List? = null + private var jobTitle: String? = null + private var managerName: String? = null + private var middleName: String? = null + private var nickname: String? = null + private var notes: String? = null + private var officeLocation: String? = null + private var phoneNumbers: List? = null + private var physicalAddresses: List? = null + private var suffix: String? = null + private var surname: String? = null + private var webPages: List? = null + private var picture: String? = null + private var source: SourceType? = null + private var groups: List? = null + + fun displayName(displayName: String?) = apply { this.displayName = displayName } + fun birthday(birthday: String?) = apply { this.birthday = birthday } + fun companyName(companyName: String?) = apply { this.companyName = companyName } + fun emails(emails: List?) = apply { this.emails = emails } + fun givenName(givenName: String?) = apply { this.givenName = givenName } + fun imAddresses(imAddresses: List?) = apply { this.imAddresses = imAddresses } + fun jobTitle(jobTitle: String?) = apply { this.jobTitle = jobTitle } + fun managerName(managerName: String?) = apply { this.managerName = managerName } + fun middleName(middleName: String?) = apply { this.middleName = middleName } + fun nickname(nickname: String?) = apply { this.nickname = nickname } + fun notes(notes: String?) = apply { this.notes = notes } + fun officeLocation(officeLocation: String?) = apply { this.officeLocation = officeLocation } + fun phoneNumbers(phoneNumbers: List?) = apply { this.phoneNumbers = phoneNumbers } + fun physicalAddresses(physicalAddresses: List?) = apply { this.physicalAddresses = physicalAddresses } + fun suffix(suffix: String?) = apply { this.suffix = suffix } + fun surname(surname: String?) = apply { this.surname = surname } + fun webPages(webPages: List?) = apply { this.webPages = webPages } + fun picture(picture: String?) = apply { this.picture = picture } + fun source(source: SourceType?) = apply { this.source = source } + fun groups(groups: List?) = apply { this.groups = groups } + + fun build() = UpdateContactRequest( + displayName = displayName, + birthday = birthday, + companyName = companyName, + emails = emails, + givenName = givenName, + imAddresses = imAddresses, + jobTitle = jobTitle, + managerName = managerName, + middleName = middleName, + nickname = nickname, + notes = notes, + officeLocation = officeLocation, + phoneNumbers = phoneNumbers, + physicalAddresses = physicalAddresses, + suffix = suffix, + surname = surname, + webPages = webPages, + picture = picture, + source = source, + groups = groups, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/WebPage.kt b/src/main/kotlin/com/nylas/models/WebPage.kt new file mode 100644 index 00000000..e8e997f4 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/WebPage.kt @@ -0,0 +1,22 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation for web pages in a contact. + */ +data class WebPage( + @Json(name = "url") + val url: String? = null, + @Json(name = "type") + val type: ContactType? = null, +) { + class Builder { + private var url: String? = null + private var type: ContactType? = null + + fun url(url: String) = apply { this.url = url } + fun type(type: ContactType) = apply { this.type = type } + fun build() = WebPage(url, type) + } +} diff --git a/src/main/kotlin/com/nylas/resources/Contacts.kt b/src/main/kotlin/com/nylas/resources/Contacts.kt new file mode 100644 index 00000000..b2a82870 --- /dev/null +++ b/src/main/kotlin/com/nylas/resources/Contacts.kt @@ -0,0 +1,76 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.util.JsonHelper +import com.squareup.moshi.Types + +class Contacts(client: NylasClient) : Resource(client, Contact::class.java) { + /** + * Return all contacts + * @param identifier The identifier of the grant to act upon + * @param queryParams The query parameters to include in the request + * @return The list of contacts + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun list(identifier: String, queryParams: ListContactsQueryParams? = null): ListResponse { + val path = String.format("v3/grants/%s/contacts", identifier) + return listResource(path, queryParams) + } + + /** + * Return a contact + * @param identifier The identifier of the grant to act upon + * @param contactId The id of the contact to retrieve. + * @param queryParams The query parameters to include in the request + * @return The contact + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun find(identifier: String, contactId: String, queryParams: FindContactQueryParams? = null): Response { + val path = String.format("v3/grants/%s/contacts/%s", identifier, contactId) + return findResource(path) + } + + /** + * Update a Contact + * @param identifier The identifier of the grant to act upon + * @param contactId The id of the contact to update. + * @param requestBody The values to update the Contact with + * @return The updated contact + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + fun update(identifier: String, contactId: String, requestBody: UpdateContactRequest): Response { + val path = String.format("v3/grants/%s/contacts/%s", identifier, contactId) + val adapter = JsonHelper.moshi().adapter(UpdateContactRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return updateResource(path, serializedRequestBody) + } + + /** + * Delete a Contact + * @param identifier The identifier of the grant to act upon + * @param contactId The id of the Contact to delete. + * @return The deletion response + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + fun destroy(identifier: String, contactId: String): DeleteResponse { + val path = String.format("v3/grants/%s/contacts/%s", identifier, contactId) + return destroyResource(path) + } + + /** + * Return all contact groups + * @param identifier The identifier of the grant to act upon + * @param queryParams The query parameters to include in the request + * @return The scheduled message + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun listGroups(identifier: String, queryParams: ListContactGroupsQueryParams? = null): ListResponse { + val path = String.format("v3/grants/%s/messages/contacts/groups", identifier) + val responseType = Types.newParameterizedType(ListResponse::class.java, ContactGroup::class.java) + return client.executeGet(path, responseType, queryParams) + } +}