├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── CBPMigration.md ├── LICENSE ├── README.md ├── appveyor.yml ├── fixture ├── GET │ ├── apps.json │ ├── attachment.json │ ├── automation.json │ ├── automations.json │ ├── brand.json │ ├── brands.json │ ├── dynamic_content │ │ └── items.json │ ├── group.json │ ├── group_memberships.json │ ├── groups.json │ ├── locales.json │ ├── macro.json │ ├── macros.json │ ├── organization.json │ ├── organization_fields.json │ ├── organization_memberships.json │ ├── organizations.json │ ├── search_count_ticket.json │ ├── search_group.json │ ├── search_ticket.json │ ├── search_user.json │ ├── sla_policies.json │ ├── sla_policy.json │ ├── tags.json │ ├── target.json │ ├── targets.json │ ├── ticket.json │ ├── ticket_audit.json │ ├── ticket_audits.json │ ├── ticket_comments.json │ ├── ticket_custom_field.json │ ├── ticket_field.json │ ├── ticket_fields.json │ ├── ticket_form.json │ ├── ticket_forms.json │ ├── ticket_show_many.json │ ├── tickets.json │ ├── trigger.json │ ├── triggers.json │ ├── user.json │ ├── user_fields.json │ ├── user_related.json │ ├── users.json │ ├── view.json │ ├── views.json │ ├── views_ticket_count.json │ └── webhook.json ├── POST │ ├── automations.json │ ├── brands.json │ ├── dynamic_content │ │ └── items.json │ ├── groups.json │ ├── macro.json │ ├── organization.json │ ├── organization_fields.json │ ├── organization_membership.json │ ├── sla_policies.json │ ├── target.json │ ├── ticket.json │ ├── ticket_fields.json │ ├── ticket_form.json │ ├── triggers.json │ ├── upload.json │ ├── users.json │ └── webhooks.json ├── PUT │ ├── automations.json │ ├── brands.json │ ├── groups.json │ ├── macro.json │ ├── organization.json │ ├── organization_membership.json │ ├── redact_ticket_comment.json │ ├── redact_ticket_comment_attachment.json │ ├── sla_policies.json │ ├── tags.json │ ├── target.json │ ├── ticket.json │ ├── ticket_field.json │ ├── ticket_form.json │ ├── triggers.json │ └── user.json └── ticket_result.json ├── go.mod ├── go.sum ├── script ├── codegen │ └── main.go └── create_locale_types.rb └── zendesk ├── action_types.go ├── action_types_test.go ├── all_ticket_audit_generated.go ├── api.go ├── app.go ├── app_test.go ├── attachment.go ├── attachment_test.go ├── automation.go ├── automation_generated.go ├── automation_test.go ├── brand.go ├── brand_test.go ├── collaborators.go ├── collaborators_test.go ├── condition_types.go ├── condition_types_test.go ├── credential.go ├── credential_test.go ├── cursor.go ├── custom_field_option.go ├── custom_object.go ├── custom_role.go ├── dynamic_content.go ├── dynamic_content_generated.go ├── dynamic_content_test.go ├── error.go ├── error_test.go ├── group.go ├── group_generated.go ├── group_membership.go ├── group_membership_generated.go ├── group_membership_test.go ├── group_test.go ├── iterator.go ├── iterator_test.go ├── locale.go ├── locale_test.go ├── locale_types.go ├── locale_types_test.go ├── macro.go ├── macro_generated.go ├── macro_test.go ├── main_test.go ├── mock ├── api.go └── client.go ├── organization.go ├── organization_field.go ├── organization_field_generated.go ├── organization_field_test.go ├── organization_generated.go ├── organization_membership.go ├── organization_membership_generated.go ├── organization_membership_test.go ├── organization_test.go ├── organization_tickets_generated.go ├── organization_users_generated.go ├── page.go ├── page_test.go ├── search.go ├── search_generated.go ├── search_test.go ├── sla_policy.go ├── sla_policy_generated.go ├── sla_policy_test.go ├── tag.go ├── tag_test.go ├── target.go ├── target_test.go ├── ticket.go ├── ticket_audit.go ├── ticket_audit_generated.go ├── ticket_audit_test.go ├── ticket_comment.go ├── ticket_comment_generated.go ├── ticket_comment_test.go ├── ticket_field.go ├── ticket_field_generated.go ├── ticket_field_test.go ├── ticket_form.go ├── ticket_form_generated.go ├── ticket_form_test.go ├── ticket_generated.go ├── ticket_metrics.go ├── ticket_test.go ├── tickets_from_view_generated.go ├── topics.go ├── trigger.go ├── trigger_generated.go ├── trigger_test.go ├── user.go ├── user_field.go ├── user_field_generated.go ├── user_field_test.go ├── user_generated.go ├── user_test.go ├── via_types.go ├── via_types_test.go ├── view.go ├── view_generated.go ├── view_test.go ├── webhook.go ├── webhook_test.go ├── zendesk.go └── zendesk_test.go /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | day: "saturday" 13 | time: "10:00" 14 | timezone: "Asia/Tokyo" 15 | - package-ecosystem: "github-actions" 16 | directory: "/" 17 | schedule: 18 | interval: "weekly" 19 | day: "saturday" 20 | time: "10:00" 21 | timezone: "Asia/Tokyo" 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | matrix: 9 | go-version: 10 | - 1.18.x 11 | - 1.19.x 12 | - 1.20.x 13 | - 1.21.x 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Set up Go 1.x 17 | uses: actions/setup-go@v5 18 | with: 19 | go-version: ${{ matrix.go-version }} 20 | 21 | - name: Check out code into the Go module directory 22 | uses: actions/checkout@v4 23 | 24 | - uses: actions/cache@v4 25 | with: 26 | path: | 27 | ~/go/pkg/mod 28 | ~/.cache/go-build 29 | key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} 30 | restore-keys: | 31 | ${{ runner.os }}-go-${{ matrix.go-version }} 32 | 33 | - name: Get dependencies 34 | run: go mod download 35 | 36 | - name: Test 37 | run: go test -v -coverprofile=profile.cov ./... 38 | 39 | - name: Send coverage 40 | uses: shogo82148/actions-goveralls@v1 41 | with: 42 | path-to-profile: profile.cov 43 | flag-name: Go-${{ matrix.go-version }} 44 | parallel: true 45 | ignore: zendesk/mock/client.go, zendesk/*_generated.go 46 | 47 | finalize: 48 | needs: test 49 | runs-on: ubuntu-latest 50 | steps: 51 | - uses: shogo82148/actions-goveralls@v1 52 | with: 53 | parallel-finished: true 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | vendor/ 16 | 17 | # coverage by go test 18 | coverage.txt 19 | profile.cov 20 | 21 | .idea 22 | *.iml 23 | .pre-commit-config.yaml 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2023 nukosuke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # go-zendesk 2 | 3 | [![Actions Status](https://github.com/nukosuke/go-zendesk/workflows/CI/badge.svg)](https://github.com/nukosuke/go-zendesk/actions) 4 | [![Build status](https://ci.appveyor.com/api/projects/status/ce4p1mswjkdftv6o/branch/master?svg=true)](https://ci.appveyor.com/project/nukosuke/go-zendesk/branch/master) 5 | [![Coverage Status](https://coveralls.io/repos/github/nukosuke/go-zendesk/badge.svg?branch=master)](https://coveralls.io/github/nukosuke/go-zendesk?branch=master) 6 | [![Go Report Card](https://goreportcard.com/badge/github.com/nukosuke/go-zendesk)](https://goreportcard.com/report/github.com/nukosuke/go-zendesk) 7 | [![GoDoc](https://godoc.org/github.com/zenform/go-zendesk?status.svg)](https://pkg.go.dev/github.com/nukosuke/go-zendesk/zendesk) 8 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnukosuke%2Fgo-zendesk.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnukosuke%2Fgo-zendesk?ref=badge_shield) 9 | 10 | Zendesk API client library for Go 11 | 12 | - [Reference](https://pkg.go.dev/github.com/nukosuke/go-zendesk/zendesk) 13 | 14 | ## Installation 15 | 16 | ```shell 17 | $ go get github.com/nukosuke/go-zendesk 18 | ``` 19 | 20 | ## Usage 21 | 22 | ```go 23 | package main 24 | 25 | import ( 26 | "context" 27 | 28 | "github.com/nukosuke/go-zendesk/zendesk" 29 | ) 30 | 31 | func main() { 32 | // You can set custom *http.Client here 33 | client, _ := zendesk.NewClient(nil) 34 | 35 | // example.zendesk.com 36 | client.SetSubdomain("example") 37 | 38 | // Authenticate with API token 39 | client.SetCredential(zendesk.NewAPITokenCredential("john.doe@example.com", "apitoken")) 40 | 41 | // Authenticate with agent password 42 | client.SetCredential(zendesk.NewBasicAuthCredential("john.doe@example.com", "password")) 43 | 44 | // Create resource 45 | client.CreateGroup(context.Background(), zendesk.Group{ 46 | Name: "support team", 47 | }) 48 | } 49 | ``` 50 | 51 | ## Want to mock API? 52 | 53 | go-zendesk has a [mock package](https://pkg.go.dev/github.com/nukosuke/go-zendesk/zendesk/mock) generated by [uber-go/mock](https://github.com/uber-go/mock). 54 | You can simulate the response from Zendesk API with it. 55 | 56 | ## To regenerate the mock client 57 | 58 | `go generate ./...` 59 | 60 | ## Zendesk OBP(Offset Based Pagination) to CBP(Cursor Based Pagination) migration guide 61 | [CBPMigration](CBPMigration.md) 62 | 63 | ## Maintainer 64 | 65 | - [nukosuke](https://github.com/nukosuke) 66 | 67 | ## License 68 | 69 | MIT License. 70 | 71 | See the file [LICENSE](./LICENSE). 72 | 73 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnukosuke%2Fgo-zendesk.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnukosuke%2Fgo-zendesk?ref=badge_large) 74 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | build: off 2 | 3 | clone_folder: c:\github.com\nukosuke\go-zendesk 4 | 5 | environment: 6 | GOPATH: c:\gopath 7 | GO111MODULE: on 8 | 9 | cache: 10 | - '%LocalAppData%\go-build' 11 | - '%GOPATH%\pkg\mod' 12 | 13 | stack: go 1.19 14 | 15 | install: 16 | - go mod download 17 | 18 | before_test: 19 | - go vet ./... 20 | 21 | test_script: 22 | - go test ./... 23 | -------------------------------------------------------------------------------- /fixture/GET/apps.json: -------------------------------------------------------------------------------- 1 | { 2 | "installations": [ 3 | { 4 | "id": 42, 5 | "app_id": 913, 6 | "product": "support", 7 | "settings": { 8 | "name": "Mystery App", 9 | "title": "Mystery App" 10 | }, 11 | "settings_objects": [ 12 | { 13 | "name": "setting-one", 14 | "value": "value-one" 15 | }, 16 | { 17 | "name": "setting-two", 18 | "value": "value-two" 19 | } 20 | ], 21 | "enabled": true, 22 | "created_at": "2023-01-01T01:01:01Z", 23 | "updated_at": "2023-01-01T01:01:01Z", 24 | "paid": false 25 | }, 26 | { 27 | "id": 42, 28 | "app_id": 917, 29 | "product": "support", 30 | "settings": { 31 | "name": "Mystery App 2", 32 | "title": "Mystery App 2" 33 | }, 34 | "settings_objects": [ 35 | { 36 | "name": "foo", 37 | "value": "bar" 38 | } 39 | ], 40 | "enabled": true, 41 | "created_at": "2023-02-02T02:02:02Z", 42 | "updated_at": "2023-02-02T02:02:02Z", 43 | "paid": false 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /fixture/GET/attachment.json: -------------------------------------------------------------------------------- 1 | { 2 | "attachment": { 3 | "id": 498483, 4 | "name": "myfile.dat", 5 | "content_url": "https://company.zendesk.com/attachments/myfile.dat", 6 | "content_type": "application/binary", 7 | "size": 2532, 8 | "thumbnails": [], 9 | "url": "https://company.zendesk.com/api/v2/attachments/498483.json" 10 | } 11 | } -------------------------------------------------------------------------------- /fixture/GET/automation.json: -------------------------------------------------------------------------------- 1 | { 2 | "automation": { 3 | "url": "https://example.zendesk.com/api/v2/automations/360017421099.json", 4 | "id": 360017421099, 5 | "title": "Close ticket 4 days after status is set to solved", 6 | "active": true, 7 | "updated_at": "2019-09-17T21:22:20Z", 8 | "created_at": "2019-09-17T21:22:20Z", 9 | "actions": [ 10 | { 11 | "field": "status", 12 | "value": "closed" 13 | } 14 | ], 15 | "conditions": { 16 | "all": [ 17 | { 18 | "field": "status", 19 | "operator": "is", 20 | "value": "solved" 21 | }, 22 | { 23 | "field": "SOLVED", 24 | "operator": "greater_than", 25 | "value": "96" 26 | } 27 | ], 28 | "any": [] 29 | }, 30 | "position": 0, 31 | "raw_title": "Close ticket 4 days after status is set to solved" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fixture/GET/automations.json: -------------------------------------------------------------------------------- 1 | { 2 | "automations": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/automations/360017421099.json", 5 | "id": 360017421099, 6 | "title": "Close ticket 4 days after status is set to solved", 7 | "active": true, 8 | "updated_at": "2019-09-17T21:22:20Z", 9 | "created_at": "2019-09-17T21:22:20Z", 10 | "actions": [ 11 | { 12 | "field": "status", 13 | "value": "closed" 14 | } 15 | ], 16 | "conditions": { 17 | "all": [ 18 | { 19 | "field": "status", 20 | "operator": "is", 21 | "value": "solved" 22 | }, 23 | { 24 | "field": "SOLVED", 25 | "operator": "greater_than", 26 | "value": "96" 27 | } 28 | ], 29 | "any": [] 30 | }, 31 | "position": 0, 32 | "raw_title": "Close ticket 4 days after status is set to solved" 33 | }, 34 | { 35 | "url": "https://example.zendesk.com/api/v2/automations/360017421119.json", 36 | "id": 360017421119, 37 | "title": "Pending notification 24 hours", 38 | "active": false, 39 | "updated_at": "2019-09-17T21:22:20Z", 40 | "created_at": "2019-09-17T21:22:20Z", 41 | "actions": [ 42 | { 43 | "field": "notification_user", 44 | "value": [ 45 | "requester_and_ccs", 46 | "[{{ticket.account}}] Pending request: {{ticket.title}}", 47 | "This is an email to remind you that your request (#{{ticket.id}}) is pending and awaits your feedback.\n\n{{ticket.comments_formatted}}" 48 | ] 49 | } 50 | ], 51 | "conditions": { 52 | "all": [ 53 | { 54 | "field": "PENDING", 55 | "operator": "is", 56 | "value": "24" 57 | }, 58 | { 59 | "field": "ticket_is_public", 60 | "operator": "is", 61 | "value": "public" 62 | } 63 | ], 64 | "any": [] 65 | }, 66 | "position": 9998, 67 | "raw_title": "Pending notification 24 hours" 68 | }, 69 | { 70 | "url": "https://example.zendesk.com/api/v2/automations/360017421139.json", 71 | "id": 360017421139, 72 | "title": "Pending notification 5 days", 73 | "active": false, 74 | "updated_at": "2019-09-17T21:22:20Z", 75 | "created_at": "2019-09-17T21:22:20Z", 76 | "actions": [ 77 | { 78 | "field": "notification_user", 79 | "value": [ 80 | "requester_and_ccs", 81 | "[{{ticket.account}}] Pending request: {{ticket.title}}", 82 | "This is an email to remind you that your request (#{{ticket.id}}) has been pending for 5 days and awaits your feedback.\n\n{{ticket.comments_formatted}}" 83 | ] 84 | } 85 | ], 86 | "conditions": { 87 | "all": [ 88 | { 89 | "field": "PENDING", 90 | "operator": "is", 91 | "value": "120" 92 | }, 93 | { 94 | "field": "ticket_is_public", 95 | "operator": "is", 96 | "value": "public" 97 | } 98 | ], 99 | "any": [] 100 | }, 101 | "position": 9999, 102 | "raw_title": "Pending notification 5 days" 103 | } 104 | ], 105 | "next_page": null, 106 | "previous_page": null, 107 | "count": 3 108 | } -------------------------------------------------------------------------------- /fixture/GET/brand.json: -------------------------------------------------------------------------------- 1 | { 2 | "brand": 3 | { 4 | "url": "https://example.zendesk.com/api/v2/brands/360002143133.json", 5 | "id": 360002143133, 6 | "name": "brand2", 7 | "brand_url": "https://example-brand2.zendesk.com", 8 | "subdomain": "example-brand2", 9 | "has_help_center": false, 10 | "help_center_state": "disabled", 11 | "active": true, 12 | "default": false, 13 | "is_deleted": false, 14 | "logo": { 15 | "url": "https://example.zendesk.com/api/v2/attachments/360000142813.json", 16 | "id": 360000142813, 17 | "file_name": "zendesk_logo.jpeg", 18 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 19 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 20 | "content_type": "image/jpeg", 21 | "size": 4060, 22 | "width": 80, 23 | "height": 80, 24 | "inline": false, 25 | "thumbnails": [ 26 | { 27 | "url": "https://example.zendesk.com/api/v2/attachments/360000142833.json", 28 | "id": 360000142833, 29 | "file_name": "zendesk_logo_thumb.jpeg", 30 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 31 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 32 | "content_type": "image/jpeg", 33 | "size": 2040, 34 | "width": 32, 35 | "height": 32, 36 | "inline": false 37 | }, 38 | { 39 | "url": "https://example.zendesk.com/api/v2/attachments/360000142853.json", 40 | "id": 360000142853, 41 | "file_name": "zendesk_logo_small.jpeg", 42 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 43 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 44 | "content_type": "image/jpeg", 45 | "size": 1322, 46 | "width": 24, 47 | "height": 24, 48 | "inline": false 49 | } 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /fixture/GET/brands.json: -------------------------------------------------------------------------------- 1 | { 2 | "brands": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/brands/360002143133.json", 5 | "id": 360002143133, 6 | "name": "brand2", 7 | "brand_url": "https://example-brand2.zendesk.com", 8 | "subdomain": "example-brand2", 9 | "has_help_center": false, 10 | "help_center_state": "disabled", 11 | "active": true, 12 | "default": false, 13 | "is_deleted": false, 14 | "logo": { 15 | "url": "https://example.zendesk.com/api/v2/attachments/360000142813.json", 16 | "id": 360000142813, 17 | "file_name": "zendesk_logo.jpeg", 18 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 19 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 20 | "content_type": "image/jpeg", 21 | "size": 4060, 22 | "width": 80, 23 | "height": 80, 24 | "inline": false, 25 | "thumbnails": [ 26 | { 27 | "url": "https://example.zendesk.com/api/v2/attachments/360000142833.json", 28 | "id": 360000142833, 29 | "file_name": "zendesk_logo_thumb.jpeg", 30 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 31 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 32 | "content_type": "image/jpeg", 33 | "size": 2040, 34 | "width": 32, 35 | "height": 32, 36 | "inline": false 37 | }, 38 | { 39 | "url": "https://example.zendesk.com/api/v2/attachments/360000142853.json", 40 | "id": 360000142853, 41 | "file_name": "zendesk_logo_small.jpeg", 42 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 43 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 44 | "content_type": "image/jpeg", 45 | "size": 1322, 46 | "width": 24, 47 | "height": 24, 48 | "inline": false 49 | } 50 | ] 51 | }, 52 | "ticket_form_ids": [ 53 | 360000124108, 54 | 360000124128, 55 | 360000124148, 56 | 360000124168, 57 | 360000124188, 58 | 360000128407, 59 | 360000128427, 60 | 360000128447 61 | ], 62 | "signature_template": "{{agent.signature}}", 63 | "created_at": "2019-03-15T03:12:57Z", 64 | "updated_at": "2019-03-15T03:23:23Z", 65 | "host_mapping": null 66 | }, 67 | { 68 | "url": "https://example.zendesk.com/api/v2/brands/360000021288.json", 69 | "id": 360000021288, 70 | "name": "サンドボックス", 71 | "brand_url": "https://example.zendesk.com", 72 | "subdomain": "example", 73 | "has_help_center": true, 74 | "help_center_state": "restricted", 75 | "active": true, 76 | "default": true, 77 | "is_deleted": false, 78 | "logo": null, 79 | "ticket_form_ids": [ 80 | 360000124108, 81 | 360000124128, 82 | 360000124148, 83 | 360000124168, 84 | 360000124188, 85 | 360000128407, 86 | 360000128427, 87 | 360000128447 88 | ], 89 | "signature_template": "{{agent.signature}}", 90 | "created_at": "2018-07-13T06:20:01Z", 91 | "updated_at": "2018-07-13T06:20:01Z", 92 | "host_mapping": null 93 | } 94 | ], 95 | "next_page": null, 96 | "previous_page": null, 97 | "count": 2 98 | } 99 | -------------------------------------------------------------------------------- /fixture/GET/group.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": { 3 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/groups/360002440594.json", 4 | "id": 360002440594, 5 | "name": "Support", 6 | "deleted": false, 7 | "created_at": "2018-11-23T16:05:12Z", 8 | "updated_at": "2018-11-23T16:05:15Z" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixture/GET/group_memberships.json: -------------------------------------------------------------------------------- 1 | { 2 | "group_memberships": [ 3 | { 4 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/group_memberships/360002440594.json", 5 | "id": 360002440594, 6 | "user_id": 15439980, 7 | "group_id": 98907558, 8 | "default": false, 9 | "created_at": "2018-11-23T16:05:12Z", 10 | "updated_at": "2018-11-23T16:05:15Z" 11 | }, 12 | { 13 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/group_memberships/360002440595.json", 14 | "id": 360002440595, 15 | "user_id": 15439981, 16 | "group_id": 98907557, 17 | "default": false, 18 | "created_at": "2018-11-23T16:05:12Z", 19 | "updated_at": "2018-11-23T16:05:15Z" 20 | } 21 | ], 22 | "next_page": null, 23 | "previous_page": null, 24 | "count": 1 25 | } 26 | -------------------------------------------------------------------------------- /fixture/GET/groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [ 3 | { 4 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/groups/360002440594.json", 5 | "id": 360002440594, 6 | "name": "Support", 7 | "deleted": false, 8 | "created_at": "2018-11-23T16:05:12Z", 9 | "updated_at": "2018-11-23T16:05:15Z" 10 | } 11 | ], 12 | "next_page": null, 13 | "previous_page": null, 14 | "count": 1 15 | } -------------------------------------------------------------------------------- /fixture/GET/locales.json: -------------------------------------------------------------------------------- 1 | { 2 | "locales": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/locales/en-US.json", 5 | "id": 1, 6 | "locale": "en-US", 7 | "name": "English", 8 | "native_name": "English", 9 | "presentation_name": "English", 10 | "rtl": false, 11 | "created_at": null, 12 | "updated_at": "2018-11-30T20:42:59Z", 13 | "default": true 14 | }, 15 | { 16 | "url": "https://example.zendesk.com/api/v2/locales/ja.json", 17 | "id": 67, 18 | "locale": "ja", 19 | "name": "日本語 (Japanese)", 20 | "native_name": "日本語", 21 | "presentation_name": "Japanese - 日本語", 22 | "rtl": false, 23 | "created_at": "2009-03-23T19:42:53Z", 24 | "updated_at": "2018-11-30T15:00:47Z", 25 | "default": false 26 | }, 27 | { 28 | "url": "https://example.zendesk.com/api/v2/locales/zh-tw.json", 29 | "id": 9, 30 | "locale": "zh-tw", 31 | "name": "繁體中文 (Traditional Chinese)", 32 | "native_name": "繁體中文", 33 | "presentation_name": "Traditional Chinese - 繁體中文", 34 | "rtl": false, 35 | "created_at": "2009-02-18T03:48:45Z", 36 | "updated_at": "2018-12-03T03:19:51Z", 37 | "default": false 38 | } 39 | ], 40 | "next_page": null, 41 | "previous_page": null, 42 | "count": 3 43 | } -------------------------------------------------------------------------------- /fixture/GET/macro.json: -------------------------------------------------------------------------------- 1 | { 2 | "macro":{ 3 | "actions": [ 4 | { 5 | "field": "status", 6 | "value": "solved" 7 | }, 8 | { 9 | "field": "priority", 10 | "value": "normal" 11 | }, 12 | { 13 | "field": "type", 14 | "value": "incident" 15 | }, 16 | { 17 | "field": "assignee_id", 18 | "value": "current_user" 19 | }, 20 | { 21 | "field": "group_id", 22 | "value": "current_groups" 23 | }, 24 | { 25 | "field": "comment_value", 26 | "value": "Thanks for your request. This issue you reported is a known issue. For more information, please visit our forums. " 27 | } 28 | ], 29 | "active": true, 30 | "created_at": "2019-09-16T02:17:38Z", 31 | "description": null, 32 | "id": 360111062754, 33 | "position": 9999, 34 | "restriction": null, 35 | "title": "Close and redirect to topics", 36 | "updated_at": "2019-09-16T02:17:38Z", 37 | "url": "https://subdomain.zendesk.com/api/v2/macros/360111062754.json" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /fixture/GET/macros.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "macros": [ 4 | { 5 | "actions": [], 6 | "active": true, 7 | "description": "Sets the ticket status to `solved`", 8 | "id": 25, 9 | "position": 42, 10 | "restriction": {}, 11 | "title": "Close and Save" 12 | }, 13 | { 14 | "actions": [], 15 | "active": false, 16 | "description": "Adds a `priority` tag to the ticket", 17 | "id": 26, 18 | "restriction": {}, 19 | "title": "Assign priority tag" 20 | } 21 | ], 22 | "next_page": null, 23 | "previous_page": null 24 | } 25 | -------------------------------------------------------------------------------- /fixture/GET/organization.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization": { 3 | "url": "https://example.zendesk.com/api/v2/organizations/361898904439.json", 4 | "id": 361898904439, 5 | "name": "Rebel Alliance", 6 | "shared_tickets": true, 7 | "shared_comments": true, 8 | "created_at": "2019-09-17T21:22:18Z", 9 | "updated_at": "2019-09-17T21:22:18Z", 10 | "domain_names": [ 11 | "hoth.com", 12 | "dantooine.com" 13 | ], 14 | "group_id": null, 15 | "tags": [ 16 | "test" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fixture/GET/organization_fields.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization_fields": [ 3 | { 4 | "id": 1110988024701, 5 | "url": "https://example.zendesk.com/api/v2/organization_fields/1110988024701.json", 6 | "title": "Title", 7 | "type": "lookup", 8 | "relationship_target_type": "zen:user", 9 | "relationship_filter": { 10 | "all": [ 11 | { 12 | "field": "role", 13 | "operator": "is", 14 | "value": "4" 15 | }, 16 | { 17 | "field": "tags", 18 | "operator": "includes", 19 | "value": "goofy" 20 | } 21 | ], 22 | "any": [ 23 | { 24 | "field": "role", 25 | "operator": "is_not", 26 | "value": "0" 27 | } 28 | ] 29 | }, 30 | "active": true, 31 | "description": "Test description", 32 | "key": "test_key", 33 | "raw_description": "This is just at test description", 34 | "raw_title": "Raw test title", 35 | "created_at": "2023-02-02T15:36:25Z", 36 | "updated_at": "2023-02-23T10:24:49Z" 37 | }, 38 | { 39 | "id": 9170294642017, 40 | "url": "https://example.zendesk.com/api/v2/organization_fields/9170294642017.json", 41 | "title": "External Test ID", 42 | "type": "text", 43 | "relationship_target_type": "", 44 | "relationship_filter": { 45 | "all": null, 46 | "any": null 47 | }, 48 | "active": true, 49 | "description": "This field contains an external testing ID", 50 | "key": "test_external_id", 51 | "position": 1, 52 | "raw_description": "This field contains an external testing ID", 53 | "raw_title": "External testing ID", 54 | "created_at": "2023-02-06T14:43:05Z", 55 | "updated_at": "2023-02-06T14:43:05Z" 56 | } 57 | ] 58 | } -------------------------------------------------------------------------------- /fixture/GET/organization_memberships.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization_memberships": [ 3 | { 4 | "created_at": "2009-05-13T00:07:08Z", 5 | "default": true, 6 | "id": 4, 7 | "organization_id": 361898904439, 8 | "organization_name": "Rebel Alliance", 9 | "updated_at": "2011-07-22T00:11:12Z", 10 | "user_id": 369531345753, 11 | "view_tickets": true 12 | }, 13 | { 14 | "created_at": "2012-03-13T22:01:32Z", 15 | "default": null, 16 | "id": 49, 17 | "organization_id": 361898904439, 18 | "organization_name": "Rebel Alliance", 19 | "updated_at": "2012-03-13T22:01:32Z", 20 | "user_id": 369537351454, 21 | "view_tickets": true 22 | } 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /fixture/GET/organizations.json: -------------------------------------------------------------------------------- 1 | { 2 | "organizations": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/organizations/361898904439.json", 5 | "id": 361898904439, 6 | "name": "Rebel Alliance", 7 | "shared_tickets": true, 8 | "shared_comments": true, 9 | "created_at": "2019-09-17T21:22:18Z", 10 | "updated_at": "2019-09-17T21:22:18Z", 11 | "domain_names": [ 12 | "hoth.com", 13 | "dantooine.com" 14 | ], 15 | "group_id": null, 16 | "tags": [ 17 | "test" 18 | ] 19 | }, 20 | { 21 | "url": "https://example.zendesk.com/api/v2/organizations/361898904440.json", 22 | "id": 361898904440, 23 | "name": "Imperial Senate", 24 | "shared_tickets": true, 25 | "shared_comments": true, 26 | "created_at": "2019-09-17T21:22:18Z", 27 | "updated_at": "2019-09-17T21:22:18Z", 28 | "domain_names": [ 29 | "coruscant.com" 30 | ], 31 | "group_id": null, 32 | "tags": [ 33 | "test" 34 | ] 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /fixture/GET/search_count_ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 10 3 | } 4 | -------------------------------------------------------------------------------- /fixture/GET/search_group.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": [ 3 | { 4 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/groups/360007194452.json", 5 | "id": 360007194452, 6 | "name": "nyan", 7 | "description": "", 8 | "deleted": false, 9 | "created_at": "2019-12-09T02:40:11Z", 10 | "updated_at": "2019-12-09T02:40:11Z", 11 | "result_type": "group" 12 | } 13 | ], 14 | "facets": null, 15 | "next_page": null, 16 | "previous_page": null, 17 | "count": 1 18 | } -------------------------------------------------------------------------------- /fixture/GET/search_ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": [ 3 | { 4 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/4.json", 5 | "id": 4, 6 | "external_id": null, 7 | "via": { 8 | "channel": "api", 9 | "source": { 10 | "from": {}, 11 | "to": {}, 12 | "rel": null 13 | } 14 | }, 15 | "created_at": "2019-06-06T10:02:04Z", 16 | "updated_at": "2019-06-06T10:02:04Z", 17 | "type": null, 18 | "subject": "nyanyanyanya", 19 | "raw_subject": "nyanyanyanya", 20 | "description": "(●ↀ ω ↀ )", 21 | "priority": "urgent", 22 | "status": "new", 23 | "recipient": null, 24 | "requester_id": 377922500012, 25 | "submitter_id": 377922500012, 26 | "assignee_id": null, 27 | "organization_id": 360363695492, 28 | "group_id": 360004077472, 29 | "collaborator_ids": [ 30 | 377922500012 31 | ], 32 | "follower_ids": [ 33 | 377922500012 34 | ], 35 | "email_cc_ids": [], 36 | "forum_topic_id": null, 37 | "problem_id": null, 38 | "has_incidents": false, 39 | "is_public": true, 40 | "due_at": null, 41 | "tags": [], 42 | "custom_fields": [], 43 | "satisfaction_rating": null, 44 | "sharing_agreement_ids": [], 45 | "fields": [], 46 | "followup_ids": [], 47 | "ticket_form_id": 360000389592, 48 | "brand_id": 360002256672, 49 | "satisfaction_probability": null, 50 | "allow_channelback": false, 51 | "allow_attachments": true, 52 | "result_type": "ticket" 53 | } 54 | ], 55 | "facets": null, 56 | "next_page": null, 57 | "previous_page": null, 58 | "count": 1 59 | } -------------------------------------------------------------------------------- /fixture/GET/search_user.json: -------------------------------------------------------------------------------- 1 | { 2 | "results": [ 3 | { 4 | "id": 1234, 5 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/users/1234.json", 6 | "name": "Foo Bar", 7 | "email": "a@a.com", 8 | "created_at": "2019-03-18T05:48:08Z", 9 | "updated_at": "2019-12-09T06:48:10Z", 10 | "time_zone": "Eastern Time (US & Canada)", 11 | "iana_time_zone": "America/New_York", 12 | "phone": null, 13 | "shared_phone_number": null, 14 | "photo": { 15 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/attachments/360215133211.json", 16 | "id": 360215133211, 17 | "file_name": "profile_image_1234_9184218.png", 18 | "content_url": "https://d3v-terraform-provider.zendesk.com/system/photos/3602/1513/3211/profile_image_1234_9184218.png", 19 | "mapped_content_url": "https://d3v-terraform-provider.zendesk.com/system/photos/3602/1513/3211/profile_image_1234_9184218.png", 20 | "content_type": "image/png", 21 | "size": 1979, 22 | "width": 80, 23 | "height": 80, 24 | "inline": false, 25 | "deleted": false, 26 | "thumbnails": [ 27 | { 28 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/attachments/360215133231.json", 29 | "id": 360215133231, 30 | "file_name": "profile_image_1234_9184218_thumb.png", 31 | "content_url": "https://d3v-terraform-provider.zendesk.com/system/photos/3602/1513/3211/profile_image_1234_9184218_thumb.png", 32 | "mapped_content_url": "https://d3v-terraform-provider.zendesk.com/system/photos/3602/1513/3211/profile_image_1234_9184218_thumb.png", 33 | "content_type": "image/png", 34 | "size": 784, 35 | "width": 32, 36 | "height": 32, 37 | "inline": false, 38 | "deleted": false 39 | } 40 | ] 41 | }, 42 | "locale_id": 1, 43 | "locale": "en-US", 44 | "organization_id": 360363695492, 45 | "role": "admin", 46 | "verified": true, 47 | "external_id": null, 48 | "tags": [], 49 | "alias": "", 50 | "active": true, 51 | "shared": false, 52 | "shared_agent": false, 53 | "last_login_at": "2019-12-09T06:48:10Z", 54 | "two_factor_auth_enabled": null, 55 | "signature": "", 56 | "details": "", 57 | "notes": "", 58 | "role_type": null, 59 | "custom_role_id": null, 60 | "moderator": true, 61 | "ticket_restriction": null, 62 | "only_private_comments": false, 63 | "restricted_agent": false, 64 | "suspended": false, 65 | "chat_only": false, 66 | "default_group_id": 360004077472, 67 | "report_csv": false, 68 | "user_fields": { 69 | "github_profile": "https://github.com/foobar", 70 | "nickname": "foo bar", 71 | "twitter_account": "https://twitter.com/foobar1345" 72 | }, 73 | "result_type": "user" 74 | } 75 | ], 76 | "facets": null, 77 | "next_page": null, 78 | "previous_page": null, 79 | "count": 1 80 | } -------------------------------------------------------------------------------- /fixture/GET/sla_policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "sla_policy": { 3 | "id": 360000068060, 4 | "title": "Incidents", 5 | "description": "For urgent incidents, we will respond to tickets in 10 minutes", 6 | "position": 3, 7 | "filter": { 8 | "all": [ 9 | { 10 | "field": "type", 11 | "operator": "is", 12 | "value": "incident" 13 | } 14 | ], 15 | "any": [] 16 | }, 17 | "policy_metrics": [ 18 | { 19 | "priority": "normal", 20 | "metric": "first_reply_time", 21 | "target": 30, 22 | "business_hours": false 23 | }, 24 | { 25 | "priority": "urgent", 26 | "metric": "first_reply_time", 27 | "target": 10, 28 | "business_hours": false 29 | }, 30 | { 31 | "priority": "low", 32 | "metric": "requester_wait_time", 33 | "target": 180, 34 | "business_hours": false 35 | }, 36 | { 37 | "priority": "normal", 38 | "metric": "requester_wait_time", 39 | "target": 160, 40 | "business_hours": false 41 | }, 42 | { 43 | "priority": "high", 44 | "metric": "requester_wait_time", 45 | "target": 140, 46 | "business_hours": false 47 | }, 48 | { 49 | "priority": "urgent", 50 | "metric": "requester_wait_time", 51 | "target": 120, 52 | "business_hours": false 53 | } 54 | ] 55 | } 56 | } -------------------------------------------------------------------------------- /fixture/GET/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "exchange", 4 | "important" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /fixture/GET/target.json: -------------------------------------------------------------------------------- 1 | { 2 | "target": { 3 | "url": "https://example.zendesk.com/api/v2/targets/360000217439.json", 4 | "id": 360000217439, 5 | "created_at": "2019-09-29T08:11:03Z", 6 | "type": "http_target", 7 | "title": "target :: http :: postbin", 8 | "active": true, 9 | "method": "post", 10 | "username": "", 11 | "password": null, 12 | "content_type": "application/json", 13 | "target_url": "https://postb.in/WERcssi2" 14 | } 15 | } -------------------------------------------------------------------------------- /fixture/GET/targets.json: -------------------------------------------------------------------------------- 1 | { 2 | "targets": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/targets/360000217438.json", 5 | "id": 360000217438, 6 | "created_at": "2019-09-29T08:11:03Z", 7 | "type": "http_target", 8 | "title": "target :: http :: postbin", 9 | "active": true, 10 | "method": "post", 11 | "username": "", 12 | "password": null, 13 | "content_type": "application/json", 14 | "target_url": "https://postb.in/WERcssi2" 15 | }, 16 | { 17 | "url": "https://example.zendesk.com/api/v2/targets/360000217439.json", 18 | "id": 360000217439, 19 | "created_at": "2019-09-29T08:11:03Z", 20 | "type": "email_target", 21 | "title": "target :: email :: john.doe@example.com", 22 | "active": true, 23 | "email": "john.doe@example.com", 24 | "subject": "New ticket created" 25 | } 26 | ], 27 | "next_page": null, 28 | "previous_page": null, 29 | "count": 2 30 | } -------------------------------------------------------------------------------- /fixture/GET/ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket": { 3 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/2.json", 4 | "id": 2, 5 | "external_id": null, 6 | "via": { 7 | "channel": "email", 8 | "source": { 9 | "from": { 10 | "address": "nukosuke@lavabit.com", 11 | "name": "Yosuke Tamura" 12 | }, 13 | "to": { 14 | "name": "Terraform Zendesk provider", 15 | "address": "support@d3v-terraform-provider.zendesk.com" 16 | }, 17 | "rel": null 18 | } 19 | }, 20 | "created_at": "2019-06-03T02:23:47Z", 21 | "updated_at": "2019-06-05T01:13:24Z", 22 | "type": null, 23 | "subject": "Mail to create fixture ticket for testing", 24 | "raw_subject": "Mail to create fixture ticket for testing", 25 | "description": "Mail to create fixture ticket for testing\n\nnukosuke (●ↀ ω ↀ●)", 26 | "priority": null, 27 | "status": "solved", 28 | "custom_status_id": 12480498776781, 29 | "recipient": "support@d3v-terraform-provider.zendesk.com", 30 | "requester_id": 377922500012, 31 | "submitter_id": 377922500012, 32 | "assignee_id": 377922500012, 33 | "organization_id": 360363695492, 34 | "group_id": 360004077472, 35 | "collaborator_ids": [ 36 | 377922500012 37 | ], 38 | "follower_ids": [ 39 | 377922500012 40 | ], 41 | "email_cc_ids": [], 42 | "forum_topic_id": null, 43 | "problem_id": null, 44 | "has_incidents": false, 45 | "is_public": true, 46 | "due_at": null, 47 | "tags": [], 48 | "custom_fields": [], 49 | "satisfaction_rating": null, 50 | "sharing_agreement_ids": [], 51 | "fields": [], 52 | "followup_ids": [], 53 | "ticket_form_id": 360000389592, 54 | "brand_id": 360002256672, 55 | "satisfaction_probability": null, 56 | "allow_channelback": false, 57 | "allow_attachments": true 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /fixture/GET/ticket_audit.json: -------------------------------------------------------------------------------- 1 | { 2 | "audit": { 3 | "created_at": "2011-09-25T22:35:44Z", 4 | "via": { 5 | "channel": "web" 6 | }, 7 | "metadata": { 8 | "system": { 9 | "location": "San Francisco, CA, United States", 10 | "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1", 11 | "ip_address": "76.218.201.212" 12 | }, 13 | "custom": { 14 | } 15 | }, 16 | "id": 2127301143, 17 | "ticket_id": 666, 18 | "events": [ 19 | { 20 | "html_body": "

This is a new private comment

", 21 | "public": false, 22 | "body": "This is a new private comment", 23 | "id": 2127301148, 24 | "type": "Comment", 25 | "attachments": [ 26 | ] 27 | }, 28 | { 29 | "via": { 30 | "channel": "rule", 31 | "source": { 32 | "to": { }, 33 | "from": { 34 | "id": 35079792, 35 | "title": "Assign to first responder" 36 | }, 37 | "rel": "trigger" 38 | } 39 | }, 40 | "id": 2127301163, 41 | "value": "open", 42 | "type": "Change", 43 | "previous_value": "new", 44 | "field_name": "status" 45 | } 46 | ], 47 | "author_id": 5246746 48 | } 49 | } -------------------------------------------------------------------------------- /fixture/GET/ticket_audits.json: -------------------------------------------------------------------------------- 1 | { 2 | "audits": [ 3 | { 4 | "created_at": "2011-09-25T22:35:44Z", 5 | "via": { 6 | "channel": "web" 7 | }, 8 | "metadata": { 9 | "system": { 10 | "location": "San Francisco, CA, United States", 11 | "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.186 Safari/535.1", 12 | "ip_address": "76.218.201.212" 13 | }, 14 | "custom": { 15 | } 16 | }, 17 | "id": 2127301143, 18 | "ticket_id": 666, 19 | "events": [ 20 | { 21 | "html_body": "

This is a new private comment

", 22 | "public": false, 23 | "body": "This is a new private comment", 24 | "id": 2127301148, 25 | "type": "Comment", 26 | "attachments": [ 27 | ] 28 | }, 29 | { 30 | "via": { 31 | "channel": "rule", 32 | "source": { 33 | "to": { }, 34 | "from": { 35 | "id": 35079792, 36 | "title": "Assign to first responder" 37 | }, 38 | "rel": "trigger" 39 | } 40 | }, 41 | "id": 2127301163, 42 | "value": "open", 43 | "type": "Change", 44 | "previous_value": "new", 45 | "field_name": "status" 46 | } 47 | ], 48 | "author_id": 5246746 49 | } 50 | ], 51 | "next_page": null, 52 | "previous_page": null, 53 | "count": 1 54 | } -------------------------------------------------------------------------------- /fixture/GET/ticket_comments.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | { 4 | "id": 2, 5 | "type": "Comment", 6 | "body": "Mail to create fixture ticket for testing", 7 | "html_body": "", 8 | "plain_body": "", 9 | "public": true, 10 | "author_id": 377922500012, 11 | "attachments": [], 12 | "created_at": "2019-06-03T01:23:47Z" 13 | }, 14 | { 15 | "id": 3, 16 | "type": "Comment", 17 | "body": "Mail to create fixture ticket for testing", 18 | "html_body": "", 19 | "plain_body": "", 20 | "public": true, 21 | "author_id": 377922500012, 22 | "attachments": [], 23 | "created_at": "2019-06-03T02:23:47Z" 24 | } 25 | ], 26 | "meta": { 27 | "has_more": true, 28 | "after_cursor": "xxx", 29 | "before_cursor": "yyy" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fixture/GET/ticket_custom_field.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket": { 3 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/4.json", 4 | "id": 4, 5 | "external_id": null, 6 | "via": { 7 | "channel": "web", 8 | "source": { 9 | "from": {}, 10 | "to": {}, 11 | "rel": null 12 | } 13 | }, 14 | "created_at": "2019-06-03T02:34:52Z", 15 | "updated_at": "2019-06-03T02:35:05Z", 16 | "type": null, 17 | "subject": "Ticket containing a custom field", 18 | "raw_subject": "Ticket containing a custom field", 19 | "description": "Testing custom field value in a ticket.", 20 | "priority": null, 21 | "status": "solved", 22 | "recipient": null, 23 | "requester_id": 377922500012, 24 | "submitter_id": 377922500012, 25 | "assignee_id": 377922500012, 26 | "organization_id": 360363695492, 27 | "group_id": 360004077472, 28 | "collaborator_ids": [], 29 | "follower_ids": [], 30 | "email_cc_ids": [], 31 | "forum_topic_id": null, 32 | "problem_id": null, 33 | "has_incidents": false, 34 | "is_public": true, 35 | "due_at": null, 36 | "tags": [], 37 | "custom_fields": [ 38 | { 39 | "id": 360005657120, 40 | "value": "Custom field value for testing" 41 | }, 42 | { 43 | "id": 360005657121, 44 | "value": ["list", "of", "values"] 45 | }, 46 | { 47 | "id": 360005657122, 48 | "value": null 49 | }, 50 | { 51 | "id": 360005657123, 52 | "value": true 53 | } 54 | ], 55 | "satisfaction_rating": null, 56 | "sharing_agreement_ids": [], 57 | "fields": [], 58 | "followup_ids": [], 59 | "ticket_form_id": 360000389592, 60 | "brand_id": 360002256672, 61 | "satisfaction_probability": null, 62 | "allow_channelback": false, 63 | "allow_attachments": true 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /fixture/GET/ticket_field.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_field": { 3 | "url": "https://example.zendesk.com/api/v2/ticket_fields/360011737434.json", 4 | "id": 360011737434, 5 | "type": "subject", 6 | "title": "Subject", 7 | "raw_title": "Subject", 8 | "description": "", 9 | "raw_description": "", 10 | "position": 0, 11 | "active": true, 12 | "required": false, 13 | "collapsed_for_agents": false, 14 | "regexp_for_validation": null, 15 | "title_in_portal": "Subject", 16 | "raw_title_in_portal": "Subject", 17 | "visible_in_portal": true, 18 | "editable_in_portal": true, 19 | "required_in_portal": true, 20 | "tag": null, 21 | "created_at": "2018-11-23T16:05:12Z", 22 | "updated_at": "2018-11-24T10:54:05Z", 23 | "removable": false, 24 | "agent_description": null 25 | } 26 | } -------------------------------------------------------------------------------- /fixture/GET/ticket_form.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_form": { 3 | "id": 47, 4 | "url": "https://company.zendesk.com/api/v2/ticket_forms/47.json", 5 | "name": "Snowboard Problem", 6 | "raw_name": "Snowboard Problem", 7 | "display_name": "Snowboard Damage", 8 | "raw_display_name": "{{dc.my_display_name}}", 9 | "end_user_visible": true, 10 | "position": 9999, 11 | "ticket_field_ids": [2, 4, 5, 10, 100, 101, 102, 200], 12 | "active": true, 13 | "default": true, 14 | "in_all_brands": false, 15 | "restricted_brand_ids": [47, 33, 22], 16 | "agent_conditions": [ 17 | { 18 | "parent_field_id": 100, 19 | "value": "matching_value", 20 | "child_fields": [ 21 | { "id": 101, "is_required": false }, 22 | { "id": 200, "is_required": true } 23 | ] 24 | }, 25 | { 26 | "parent_field_id": 101, 27 | "value": "matching_value_2", 28 | "child_fields": [{ "id": 102, "is_required": true }] 29 | } 30 | ], 31 | "end_user_conditions": [ 32 | { 33 | "parent_field_id": 100, 34 | "value": "matching_value", 35 | "child_fields": [{ "id": 101, "is_required": true }] 36 | }, 37 | { 38 | "parent_field_id": 200, 39 | "value": "matching_value", 40 | "child_fields": [{ "id": 202, "is_required": false }] 41 | } 42 | ], 43 | "created_at": "2012-04-02T22:55:29Z", 44 | "updated_at": "2012-04-02T22:55:29Z" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /fixture/GET/ticket_forms.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_forms": [ 3 | { 4 | "url": "https://example.zendesk.com/api/v2/ticket_forms/360000124108.json", 5 | "id": 360000124108, 6 | "name": "デフォルトのチケットフォーム", 7 | "raw_name": "デフォルトのチケットフォーム", 8 | "display_name": "デフォルトのチケットフォーム", 9 | "raw_display_name": "デフォルトのチケットフォーム", 10 | "end_user_visible": true, 11 | "position": 1, 12 | "ticket_field_ids": [ 13 | 360000422488, 14 | 360000422508 15 | ], 16 | "active": true, 17 | "default": true, 18 | "created_at": "2018-07-13T06:20:04Z", 19 | "updated_at": "2018-07-13T06:20:04Z", 20 | "in_all_brands": true, 21 | "restricted_brand_ids": [] 22 | } 23 | ], 24 | "next_page": null, 25 | "previous_page": null, 26 | "count": 1 27 | } -------------------------------------------------------------------------------- /fixture/GET/ticket_show_many.json: -------------------------------------------------------------------------------- 1 | { 2 | "tickets": [ 3 | { 4 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/2.json", 5 | "id": 2, 6 | "external_id": null, 7 | "via": { 8 | "channel": "email", 9 | "source": { 10 | "from": { 11 | "address": "nukosuke@lavabit.com", 12 | "name": "Yosuke Tamura" 13 | }, 14 | "to": { 15 | "name": "Terraform Zendesk provider", 16 | "address": "support@d3v-terraform-provider.zendesk.com" 17 | }, 18 | "rel": null 19 | } 20 | }, 21 | "created_at": "2019-06-03T02:23:47Z", 22 | "updated_at": "2019-06-05T01:13:24Z", 23 | "type": null, 24 | "subject": "Mail to create fixture ticket for testing", 25 | "raw_subject": "Mail to create fixture ticket for testing", 26 | "description": "Mail to create fixture ticket for testing\n\nnukosuke (●ↀ ω ↀ●)", 27 | "priority": null, 28 | "status": "solved", 29 | "recipient": "support@d3v-terraform-provider.zendesk.com", 30 | "requester_id": 377922500012, 31 | "submitter_id": 377922500012, 32 | "assignee_id": 377922500012, 33 | "organization_id": 360363695492, 34 | "group_id": 360004077472, 35 | "collaborator_ids": [ 36 | 377922500012 37 | ], 38 | "follower_ids": [ 39 | 377922500012 40 | ], 41 | "email_cc_ids": [], 42 | "forum_topic_id": null, 43 | "problem_id": null, 44 | "has_incidents": false, 45 | "is_public": true, 46 | "due_at": null, 47 | "tags": [], 48 | "custom_fields": [], 49 | "satisfaction_rating": null, 50 | "sharing_agreement_ids": [], 51 | "fields": [], 52 | "followup_ids": [], 53 | "ticket_form_id": 360000389592, 54 | "brand_id": 360002256672, 55 | "satisfaction_probability": null, 56 | "allow_channelback": false, 57 | "allow_attachments": true 58 | }, 59 | { 60 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/3.json", 61 | "id": 3, 62 | "external_id": null, 63 | "via": { 64 | "channel": "web", 65 | "source": { 66 | "from": {}, 67 | "to": {}, 68 | "rel": null 69 | } 70 | }, 71 | "created_at": "2019-06-03T02:34:52Z", 72 | "updated_at": "2019-06-03T02:35:05Z", 73 | "type": null, 74 | "subject": "にゃー", 75 | "raw_subject": "にゃー", 76 | "description": "ぬこすけ", 77 | "priority": null, 78 | "status": "solved", 79 | "recipient": null, 80 | "requester_id": 377922500012, 81 | "submitter_id": 377922500012, 82 | "assignee_id": 377922500012, 83 | "organization_id": 360363695492, 84 | "group_id": 360004077472, 85 | "collaborator_ids": [], 86 | "follower_ids": [], 87 | "email_cc_ids": [], 88 | "forum_topic_id": null, 89 | "problem_id": null, 90 | "has_incidents": false, 91 | "is_public": true, 92 | "due_at": null, 93 | "tags": [], 94 | "custom_fields": [], 95 | "satisfaction_rating": null, 96 | "sharing_agreement_ids": [], 97 | "fields": [], 98 | "followup_ids": [], 99 | "ticket_form_id": 360000389592, 100 | "brand_id": 360002256672, 101 | "satisfaction_probability": null, 102 | "allow_channelback": false, 103 | "allow_attachments": true 104 | } 105 | ], 106 | "next_page": null, 107 | "previous_page": null, 108 | "count": 2 109 | } 110 | -------------------------------------------------------------------------------- /fixture/GET/tickets.json: -------------------------------------------------------------------------------- 1 | { 2 | "tickets": [ 3 | { 4 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/2.json", 5 | "id": 2, 6 | "external_id": null, 7 | "via": { 8 | "channel": "email", 9 | "source": { 10 | "from": { 11 | "address": "nukosuke@lavabit.com", 12 | "name": "Yosuke Tamura" 13 | }, 14 | "to": { 15 | "name": "Terraform Zendesk provider", 16 | "address": "support@d3v-terraform-provider.zendesk.com" 17 | }, 18 | "rel": null 19 | } 20 | }, 21 | "created_at": "2019-06-03T02:23:47Z", 22 | "updated_at": "2019-06-05T01:13:24Z", 23 | "type": null, 24 | "subject": "Mail to create fixture ticket for testing", 25 | "raw_subject": "Mail to create fixture ticket for testing", 26 | "description": "Mail to create fixture ticket for testing\n\nnukosuke (●ↀ ω ↀ●)", 27 | "priority": null, 28 | "status": "solved", 29 | "recipient": "support@d3v-terraform-provider.zendesk.com", 30 | "requester_id": 377922500012, 31 | "submitter_id": 377922500012, 32 | "assignee_id": 377922500012, 33 | "organization_id": 360363695492, 34 | "group_id": 360004077472, 35 | "collaborator_ids": [ 36 | 377922500012 37 | ], 38 | "follower_ids": [ 39 | 377922500012 40 | ], 41 | "email_cc_ids": [], 42 | "forum_topic_id": null, 43 | "problem_id": null, 44 | "has_incidents": false, 45 | "is_public": true, 46 | "due_at": null, 47 | "tags": [], 48 | "custom_fields": [], 49 | "satisfaction_rating": null, 50 | "sharing_agreement_ids": [], 51 | "fields": [], 52 | "followup_ids": [], 53 | "ticket_form_id": 360000389592, 54 | "brand_id": 360002256672, 55 | "satisfaction_probability": null, 56 | "allow_channelback": false, 57 | "allow_attachments": true 58 | }, 59 | { 60 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/3.json", 61 | "id": 3, 62 | "external_id": null, 63 | "via": { 64 | "channel": "web", 65 | "source": { 66 | "from": {}, 67 | "to": {}, 68 | "rel": null 69 | } 70 | }, 71 | "created_at": "2019-06-03T02:34:52Z", 72 | "updated_at": "2019-06-03T02:35:05Z", 73 | "type": null, 74 | "subject": "にゃー", 75 | "raw_subject": "にゃー", 76 | "description": "ぬこすけ", 77 | "priority": null, 78 | "status": "solved", 79 | "recipient": null, 80 | "requester_id": 377922500012, 81 | "submitter_id": 377922500012, 82 | "assignee_id": 377922500012, 83 | "organization_id": 360363695492, 84 | "group_id": 360004077472, 85 | "collaborator_ids": [], 86 | "follower_ids": [], 87 | "email_cc_ids": [], 88 | "forum_topic_id": null, 89 | "problem_id": null, 90 | "has_incidents": false, 91 | "is_public": true, 92 | "due_at": null, 93 | "tags": [], 94 | "custom_fields": [], 95 | "satisfaction_rating": null, 96 | "sharing_agreement_ids": [], 97 | "fields": [], 98 | "followup_ids": [], 99 | "ticket_form_id": 360000389592, 100 | "brand_id": 360002256672, 101 | "satisfaction_probability": null, 102 | "allow_channelback": false, 103 | "allow_attachments": true 104 | } 105 | ], 106 | "next_page": null, 107 | "previous_page": null, 108 | "count": 2 109 | } 110 | -------------------------------------------------------------------------------- /fixture/GET/trigger.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": { 3 | "url": "https://example.zendesk.com/api/v2/triggers/360056295714.json", 4 | "id": 360056295714, 5 | "title": "Notify requester of received request", 6 | "active": true, 7 | "updated_at": "2018-11-23T16:05:14Z", 8 | "created_at": "2018-11-23T16:05:12Z", 9 | "actions": [ 10 | { 11 | "field": "notification_user", 12 | "value": [ 13 | "requester_id", 14 | "[Request received]", 15 | "Your request ({{ticket.id}}) has been received and is being reviewed by our support staff.\n\nTo add additional comments, reply to this email." 16 | ] 17 | } 18 | ], 19 | "conditions": { 20 | "all": [ 21 | { 22 | "field": "update_type", 23 | "operator": "is", 24 | "value": "Create" 25 | }, 26 | { 27 | "field": "status", 28 | "operator": "is_not", 29 | "value": "solved" 30 | }, 31 | { 32 | "field": "ticket_is_public", 33 | "operator": "is", 34 | "value": "public" 35 | } 36 | ], 37 | "any": [] 38 | }, 39 | "description": null, 40 | "position": 0, 41 | "raw_title": "Notify requester of received request" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /fixture/GET/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "id": 369531345753, 4 | "url": "https://example.zendesk.com/api/v2/users/369531345753.json", 5 | "name": "Sample customer", 6 | "email": "customer@example.com", 7 | "created_at": "2018-11-23T16:05:13Z", 8 | "updated_at": "2018-11-23T16:05:14Z", 9 | "time_zone": "Osaka", 10 | "iana_time_zone": "Asia/Tokyo", 11 | "phone": null, 12 | "shared_phone_number": null, 13 | "photo": { 14 | "url": "https://example.zendesk.com/api/v2/attachments/360255188054.json", 15 | "id": 360255188054, 16 | "file_name": "profile_image_369531345753_9042965.jpg", 17 | "content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965.jpg", 18 | "mapped_content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965.jpg", 19 | "content_type": "image/jpeg", 20 | "size": 2587, 21 | "width": 40, 22 | "height": 40, 23 | "inline": false, 24 | "thumbnails": [ 25 | { 26 | "url": "https://example.zendesk.com/api/v2/attachments/360255188074.json", 27 | "id": 360255188074, 28 | "file_name": "profile_image_369531345753_9042965_thumb.jpg", 29 | "content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965_thumb.jpg", 30 | "mapped_content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965_thumb.jpg", 31 | "content_type": "image/jpeg", 32 | "size": 1973, 33 | "width": 32, 34 | "height": 32, 35 | "inline": false 36 | } 37 | ] 38 | }, 39 | "locale_id": 1, 40 | "locale": "en-US", 41 | "organization_id": null, 42 | "role": "end-user", 43 | "verified": false, 44 | "external_id": null, 45 | "tags": [], 46 | "alias": null, 47 | "active": true, 48 | "shared": false, 49 | "shared_agent": false, 50 | "last_login_at": null, 51 | "two_factor_auth_enabled": false, 52 | "signature": null, 53 | "details": null, 54 | "notes": null, 55 | "role_type": null, 56 | "custom_role_id": null, 57 | "moderator": false, 58 | "ticket_restriction": "requested", 59 | "only_private_comments": false, 60 | "restricted_agent": true, 61 | "suspended": false, 62 | "chat_only": false, 63 | "default_group_id": null, 64 | "report_csv": false, 65 | "user_fields": {} 66 | } 67 | } -------------------------------------------------------------------------------- /fixture/GET/user_fields.json: -------------------------------------------------------------------------------- 1 | { 2 | "user_fields": [ 3 | { 4 | "url": "https://company.zendesk.com/api/v2/user_fields/7.json", 5 | "id": 7, 6 | "type": "text", 7 | "key": "custom_field_1", 8 | "title": "Custom Field 1", 9 | "raw_title": "Custom Field 1", 10 | "description": "Description of Custom Field", 11 | "raw_description": "{{dc.my_description}}", 12 | "position": 9999, 13 | "active": true, 14 | "regexp_for_validation": null, 15 | "created_at": "2012-10-16T16:04:06Z", 16 | "updated_at": "2012-10-16T16:04:06Z" 17 | } 18 | ], 19 | "next_page": null, 20 | "previous_page": null, 21 | "count": 1 22 | } -------------------------------------------------------------------------------- /fixture/GET/user_related.json: -------------------------------------------------------------------------------- 1 | { 2 | "user_related": { 3 | "assigned_tickets": 5, 4 | "ccd_tickets": 3, 5 | "organization_subscriptions": 1, 6 | "requested_tickets": 10 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /fixture/GET/view.json: -------------------------------------------------------------------------------- 1 | { 2 | "view": { 3 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/views/360002440594.json", 4 | "id": 360002440594, 5 | "title": "Wonderful tickets", 6 | "active": true, 7 | "created_at": "2018-11-23T16:05:12Z", 8 | "updated_at": "2018-11-23T16:05:15Z", 9 | "position": 0, 10 | "description": "This is a wonderful view of your tickets", 11 | "execution": { 12 | "group_by": "status", 13 | "group_order": "asc", 14 | "sort_by": "nice_id", 15 | "sort_order": "desc", 16 | "group": { 17 | "id": "status", 18 | "title": "Status", 19 | "order": "asc" 20 | }, 21 | "sort": { 22 | "id": "ticket_id", 23 | "title": "ID", 24 | "order": "desc" 25 | }, 26 | "columns": [ 27 | { 28 | "id": "subject", 29 | "title": "Subject" 30 | }, 31 | { 32 | "id": "requester", 33 | "title": "Requester" 34 | }, 35 | { 36 | "id": "created", 37 | "title": "Requested" 38 | }, 39 | { 40 | "id": "type", 41 | "title": "Type" 42 | }, 43 | { 44 | "id": "priority", 45 | "title": "Priority" 46 | } 47 | ], 48 | "fields": [ 49 | { 50 | "id": "subject", 51 | "title": "Subject" 52 | }, 53 | { 54 | "id": "requester", 55 | "title": "Requester" 56 | }, 57 | { 58 | "id": "created", 59 | "title": "Requested" 60 | }, 61 | { 62 | "id": "type", 63 | "title": "Type" 64 | }, 65 | { 66 | "id": "priority", 67 | "title": "Priority" 68 | } 69 | ], 70 | "custom_fields": [] 71 | }, 72 | "conditions": { 73 | "all": [ 74 | { 75 | "field": "status", 76 | "operator": "less_than", 77 | "value": "solved" 78 | }, 79 | { 80 | "field": "assignee_id", 81 | "operator": "is", 82 | "value": "current_user" 83 | } 84 | ], 85 | "any": [] 86 | }, 87 | "restriction": null, 88 | "watchable": true, 89 | "raw_title": "{{zd.your_wonderful_tickets}}" 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /fixture/GET/views_ticket_count.json: -------------------------------------------------------------------------------- 1 | { 2 | "view_counts": [ 3 | { 4 | "fresh": true, 5 | "pretty": "~700", 6 | "url": "https://company.zendesk.com/api/v2/views/25/count.json", 7 | "value": 719, 8 | "view_id": 25 9 | }, 10 | { 11 | "fresh": false, 12 | "pretty": "...", 13 | "url": "https://company.zendesk.com/api/v2/views/78/count.json", 14 | "value": null, 15 | "view_id": 78 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /fixture/GET/webhook.json: -------------------------------------------------------------------------------- 1 | { 2 | "webhook": { 3 | "authentication": { 4 | "add_position": "header", 5 | "type": "basic_auth" 6 | }, 7 | "created_at": "2020-10-20T08:16:28Z", 8 | "created_by": "1234567", 9 | "endpoint": "https://example.com/status/200", 10 | "http_method": "POST", 11 | "id": "01EJFTSCC78X5V07NPY2MHR00M", 12 | "name": "Example Webhook", 13 | "request_format": "json", 14 | "status": "active", 15 | "subscriptions": [ 16 | "conditional_ticket_events" 17 | ], 18 | "updated_at": "2020-10-20T08:16:28Z", 19 | "updated_by": "1234567" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fixture/POST/automations.json: -------------------------------------------------------------------------------- 1 | { 2 | "automation": { 3 | "url": "https://example.zendesk.com/api/v2/automations/360017421099.json", 4 | "id": 360017421099, 5 | "title": "Close ticket 4 days after status is set to solved", 6 | "active": true, 7 | "updated_at": "2019-09-17T21:22:20Z", 8 | "created_at": "2019-09-17T21:22:20Z", 9 | "actions": [ 10 | { 11 | "field": "status", 12 | "value": "closed" 13 | } 14 | ], 15 | "conditions": { 16 | "all": [ 17 | { 18 | "field": "status", 19 | "operator": "is", 20 | "value": "solved" 21 | }, 22 | { 23 | "field": "SOLVED", 24 | "operator": "greater_than", 25 | "value": "96" 26 | } 27 | ], 28 | "any": [] 29 | }, 30 | "position": 0, 31 | "raw_title": "Close ticket 4 days after status is set to solved" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /fixture/POST/brands.json: -------------------------------------------------------------------------------- 1 | { 2 | "brand": { 3 | "url": "https://example.zendesk.com/api/v2/brands/360002143293.json", 4 | "id": 360002143293, 5 | "name": "Brand 1", 6 | "brand_url": "https://example-brand1.zendesk.com", 7 | "subdomain": "terraform-provider-zendesk-brand1", 8 | "has_help_center": false, 9 | "help_center_state": "disabled", 10 | "active": true, 11 | "default": false, 12 | "is_deleted": false, 13 | "logo": null, 14 | "ticket_form_ids": [ 15 | 360000124108, 16 | 360000124128, 17 | 360000124148, 18 | 360000124168, 19 | 360000124188, 20 | 360000128407, 21 | 360000128427, 22 | 360000128447 23 | ], 24 | "signature_template": null, 25 | "created_at": "2019-03-15T03:37:08Z", 26 | "updated_at": "2019-03-15T03:37:08Z", 27 | "host_mapping": null 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /fixture/POST/dynamic_content/items.json: -------------------------------------------------------------------------------- 1 | { 2 | "item": { 3 | "url": "https://example.zendesk.com/api/v2/dynamic_content/items/360000346774.json", 4 | "id": 360000346774, 5 | "name": "title", 6 | "placeholder": "{{dc.title}}", 7 | "default_locale_id": 1, 8 | "outdated": false, 9 | "created_at": "2018-12-03T14:09:14Z", 10 | "updated_at": "2018-12-03T14:14:23Z", 11 | "variants": [ 12 | { 13 | "url": "https://example.zendesk.com/api/v2/dynamic_content/items/360000346774/variants/360001100153.json", 14 | "id": 360001100153, 15 | "content": "ZendeskのためのTerraform provider", 16 | "locale_id": 67, 17 | "outdated": false, 18 | "active": true, 19 | "default": false, 20 | "created_at": "2018-12-03T14:13:56Z", 21 | "updated_at": "2018-12-03T14:13:56Z" 22 | }, 23 | { 24 | "url": "https://example.zendesk.com/api/v2/dynamic_content/items/360000346774/variants/360001113534.json", 25 | "id": 360001113534, 26 | "content": "Zendesk的Terraform provider", 27 | "locale_id": 9, 28 | "outdated": false, 29 | "active": true, 30 | "default": false, 31 | "created_at": "2018-12-03T14:14:23Z", 32 | "updated_at": "2018-12-03T14:14:23Z" 33 | }, 34 | { 35 | "url": "https://example.zendesk.com/api/v2/dynamic_content/items/360000346774/variants/360001113514.json", 36 | "id": 360001113514, 37 | "content": "Terraform provider for Zendesk", 38 | "locale_id": 1, 39 | "outdated": false, 40 | "active": true, 41 | "default": true, 42 | "created_at": "2018-12-03T14:09:14Z", 43 | "updated_at": "2018-12-03T14:09:14Z" 44 | } 45 | ] 46 | } 47 | } -------------------------------------------------------------------------------- /fixture/POST/groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": { 3 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/groups/360002440594.json", 4 | "id": 360002440594, 5 | "name": "Support", 6 | "deleted": false, 7 | "created_at": "2018-11-23T16:05:12Z", 8 | "updated_at": "2018-11-23T16:05:15Z" 9 | } 10 | } -------------------------------------------------------------------------------- /fixture/POST/macro.json: -------------------------------------------------------------------------------- 1 | { 2 | "macro": { 3 | "actions": [ 4 | { 5 | "field": "status", 6 | "value": "solved" 7 | } 8 | ], 9 | "id": 4, 10 | "restriction": {}, 11 | "title": "Roger Wilco" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /fixture/POST/organization.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization": { 3 | "url": "https://example.zendesk.com/api/v2/organizations/361898904439.json", 4 | "id": 361898904439, 5 | "name": "Rebel Alliance", 6 | "shared_tickets": true, 7 | "shared_comments": true, 8 | "created_at": "2019-09-17T21:22:18Z", 9 | "updated_at": "2019-09-17T21:22:18Z", 10 | "domain_names": [ 11 | "hoth.com", 12 | "dantooine.com" 13 | ], 14 | "group_id": null, 15 | "tags": [ 16 | "test" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fixture/POST/organization_fields.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization_field": 3 | { 4 | "id": 1110988024701, 5 | "url": "https://example.zendesk.com/api/v2/organization_fields/1110988024701.json", 6 | "title": "Title", 7 | "type": "lookup", 8 | "relationship_target_type": "zen:user", 9 | "relationship_filter": { 10 | "all": [ 11 | { 12 | "field": "role", 13 | "operator": "is", 14 | "value": "4" 15 | }, 16 | { 17 | "field": "tags", 18 | "operator": "includes", 19 | "value": "goofy" 20 | } 21 | ], 22 | "any": [ 23 | { 24 | "field": "role", 25 | "operator": "is_not", 26 | "value": "0" 27 | } 28 | ] 29 | }, 30 | "active": true, 31 | "description": "Test description", 32 | "key": "test_key", 33 | "raw_description": "This is just at test description", 34 | "raw_title": "Raw test title", 35 | "created_at": "2023-02-02T15:36:25Z", 36 | "updated_at": "2023-02-23T10:24:49Z" 37 | } 38 | } -------------------------------------------------------------------------------- /fixture/POST/organization_membership.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization_membership": { 3 | "created_at": "2009-05-13T00:07:08Z", 4 | "default": true, 5 | "id": 4, 6 | "organization_id": 361898904439, 7 | "updated_at": "2011-07-22T00:11:12Z", 8 | "user_id": 369531345753 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixture/POST/sla_policies.json: -------------------------------------------------------------------------------- 1 | { 2 | "sla_policy": { 3 | "title": "Incidents", 4 | "description": "For urgent incidents, we will respond to tickets in 10 minutes", 5 | "position": 3, 6 | "filter": { 7 | "all": [ 8 | { 9 | "field": "type", 10 | "operator": "is", 11 | "value": "incident" 12 | } 13 | ], 14 | "any": [] 15 | }, 16 | "policy_metrics": [ 17 | { 18 | "priority": "normal", 19 | "metric": "first_reply_time", 20 | "target": 30, 21 | "business_hours": false 22 | }, 23 | { 24 | "priority": "urgent", 25 | "metric": "first_reply_time", 26 | "target": 10, 27 | "business_hours": false 28 | }, 29 | { 30 | "priority": "low", 31 | "metric": "requester_wait_time", 32 | "target": 180, 33 | "business_hours": false 34 | }, 35 | { 36 | "priority": "normal", 37 | "metric": "requester_wait_time", 38 | "target": 160, 39 | "business_hours": false 40 | }, 41 | { 42 | "priority": "high", 43 | "metric": "requester_wait_time", 44 | "target": 140, 45 | "business_hours": false 46 | }, 47 | { 48 | "priority": "urgent", 49 | "metric": "requester_wait_time", 50 | "target": 120, 51 | "business_hours": false 52 | } 53 | ] 54 | } 55 | } -------------------------------------------------------------------------------- /fixture/POST/target.json: -------------------------------------------------------------------------------- 1 | { 2 | "target": { 3 | "url": "https://example.zendesk.com/api/v2/targets/360000217439.json", 4 | "id": 360000217439, 5 | "created_at": "2019-09-29T08:11:03Z", 6 | "type": "http_target", 7 | "title": "target :: http :: postbin", 8 | "active": true, 9 | "method": "post", 10 | "username": "", 11 | "password": null, 12 | "content_type": "application/json", 13 | "target_url": "https://postb.in/WERcssi2" 14 | } 15 | } -------------------------------------------------------------------------------- /fixture/POST/ticket_fields.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_field": { 3 | "url": "https://example.zendesk.com/api/v2/ticket_fields/360011737434.json", 4 | "id": 360011737434, 5 | "type": "subject", 6 | "title": "Subject", 7 | "raw_title": "Subject", 8 | "description": "", 9 | "raw_description": "", 10 | "position": 0, 11 | "active": true, 12 | "required": false, 13 | "collapsed_for_agents": false, 14 | "regexp_for_validation": null, 15 | "title_in_portal": "Subject", 16 | "raw_title_in_portal": "Subject", 17 | "visible_in_portal": true, 18 | "editable_in_portal": true, 19 | "required_in_portal": true, 20 | "tag": null, 21 | "created_at": "2018-11-23T16:05:12Z", 22 | "updated_at": "2018-11-24T10:54:05Z", 23 | "removable": false, 24 | "agent_description": null 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /fixture/POST/ticket_form.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_form": { 3 | "url": "https://example.zendesk.com/api/v2/ticket_forms/360000124108.json", 4 | "id": 360000124108, 5 | "name": "デフォルトのチケットフォーム", 6 | "raw_name": "デフォルトのチケットフォーム", 7 | "display_name": "デフォルトのチケットフォーム", 8 | "raw_display_name": "デフォルトのチケットフォーム", 9 | "end_user_visible": true, 10 | "position": 1, 11 | "ticket_field_ids": [ 12 | 360000422488, 13 | 360000422508 14 | ], 15 | "active": true, 16 | "default": true, 17 | "created_at": "2018-07-13T06:20:04Z", 18 | "updated_at": "2018-07-13T06:20:04Z", 19 | "in_all_brands": true, 20 | "restricted_brand_ids": [] 21 | } 22 | } -------------------------------------------------------------------------------- /fixture/POST/triggers.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": { 3 | "url": "https://example.zendesk.com/api/v2/triggers/360056295714.json", 4 | "id": 360056295714, 5 | "title": "Notify requester of received request", 6 | "active": true, 7 | "updated_at": "2018-11-23T16:05:14Z", 8 | "created_at": "2018-11-23T16:05:12Z", 9 | "actions": [ 10 | { 11 | "field": "notification_user", 12 | "value": [ 13 | "requester_id", 14 | "[Request received]", 15 | "Your request ({{ticket.id}}) has been received and is being reviewed by our support staff.\n\nTo add additional comments, reply to this email." 16 | ] 17 | } 18 | ], 19 | "conditions": { 20 | "all": [ 21 | { 22 | "field": "update_type", 23 | "operator": "is", 24 | "value": "Create" 25 | }, 26 | { 27 | "field": "status", 28 | "operator": "is_not", 29 | "value": "solved" 30 | }, 31 | { 32 | "field": "ticket_is_public", 33 | "operator": "is", 34 | "value": "public" 35 | } 36 | ], 37 | "any": [] 38 | }, 39 | "description": null, 40 | "position": 0, 41 | "raw_title": "Notify requester of received request" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /fixture/POST/upload.json: -------------------------------------------------------------------------------- 1 | { 2 | "upload": { 3 | "token": "6bk3gql82em5nmf", 4 | "attachment": { 5 | "id": 498483, 6 | "name": "crash.log", 7 | "content_url": "https://company.zendesk.com/attachments/crash.log", 8 | "content_type": "text/plain", 9 | "size": 2532, 10 | "thumbnails": [] 11 | }, 12 | "attachments": [ 13 | { 14 | "id": 498483, 15 | "name": "crash.log", 16 | "content_url": "https://company.zendesk.com/attachments/crash.log", 17 | "content_type": "text/plain", 18 | "size": 2532, 19 | "thumbnails": [] 20 | } 21 | ] 22 | } 23 | } -------------------------------------------------------------------------------- /fixture/POST/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "id": 369895320554, 4 | "url": "https://example.zendesk.com/api/v2/users/369895320554.json", 5 | "name": "testuser", 6 | "email": "test@example.com", 7 | "created_at": "2018-11-30T19:28:01Z", 8 | "updated_at": "2018-11-30T19:28:01Z", 9 | "time_zone": "Osaka", 10 | "iana_time_zone": "Asia/Tokyo", 11 | "phone": null, 12 | "shared_phone_number": null, 13 | "photo": null, 14 | "locale_id": 1, 15 | "locale": "en-US", 16 | "organization_id": null, 17 | "role": "end-user", 18 | "verified": false, 19 | "external_id": null, 20 | "tags": [], 21 | "alias": null, 22 | "active": true, 23 | "shared": false, 24 | "shared_agent": false, 25 | "last_login_at": null, 26 | "two_factor_auth_enabled": false, 27 | "signature": null, 28 | "details": null, 29 | "notes": null, 30 | "role_type": null, 31 | "custom_role_id": null, 32 | "moderator": false, 33 | "ticket_restriction": "requested", 34 | "only_private_comments": false, 35 | "restricted_agent": true, 36 | "suspended": false, 37 | "chat_only": false, 38 | "default_group_id": null, 39 | "report_csv": false, 40 | "user_fields": {} 41 | } 42 | } -------------------------------------------------------------------------------- /fixture/POST/webhooks.json: -------------------------------------------------------------------------------- 1 | { 2 | "webhook": { 3 | "authentication": { 4 | "add_position": "header", 5 | "type": "basic_auth" 6 | }, 7 | "created_at": "2020-10-20T08:16:28Z", 8 | "created_by": "1234567", 9 | "endpoint": "https://example.com/status/200", 10 | "http_method": "POST", 11 | "id": "01EJFTSCC78X5V07NPY2MHR00M", 12 | "name": "Example Webhook", 13 | "request_format": "json", 14 | "status": "active", 15 | "subscriptions": [ 16 | "conditional_ticket_events" 17 | ], 18 | "updated_at": "2020-10-20T08:16:28Z", 19 | "updated_by": "1234567" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /fixture/PUT/automations.json: -------------------------------------------------------------------------------- 1 | { 2 | "automation": { 3 | "url": "https://example.zendesk.com/api/v2/automations/360017421099.json", 4 | "id": 360017421099, 5 | "title": "Close ticket 4 days after status is set to solved", 6 | "active": true, 7 | "updated_at": "2019-09-17T21:22:20Z", 8 | "created_at": "2019-09-17T21:22:20Z", 9 | "actions": [ 10 | { 11 | "field": "status", 12 | "value": "closed" 13 | } 14 | ], 15 | "conditions": { 16 | "all": [ 17 | { 18 | "field": "status", 19 | "operator": "is", 20 | "value": "solved" 21 | }, 22 | { 23 | "field": "SOLVED", 24 | "operator": "greater_than", 25 | "value": "96" 26 | } 27 | ], 28 | "any": [] 29 | }, 30 | "position": 0, 31 | "raw_title": "Close ticket 4 days after status is set to solved" 32 | } 33 | } -------------------------------------------------------------------------------- /fixture/PUT/brands.json: -------------------------------------------------------------------------------- 1 | { 2 | "brand": 3 | { 4 | "url": "https://example.zendesk.com/api/v2/brands/360002143133.json", 5 | "id": 360002143133, 6 | "name": "brand2", 7 | "brand_url": "https://example-brand2.zendesk.com", 8 | "subdomain": "example-brand2", 9 | "has_help_center": false, 10 | "help_center_state": "disabled", 11 | "active": true, 12 | "default": false, 13 | "is_deleted": false, 14 | "logo": { 15 | "url": "https://example.zendesk.com/api/v2/attachments/360000142813.json", 16 | "id": 360000142813, 17 | "file_name": "zendesk_logo.jpeg", 18 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 19 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo.jpeg", 20 | "content_type": "image/jpeg", 21 | "size": 4060, 22 | "width": 80, 23 | "height": 80, 24 | "inline": false, 25 | "thumbnails": [ 26 | { 27 | "url": "https://example.zendesk.com/api/v2/attachments/360000142833.json", 28 | "id": 360000142833, 29 | "file_name": "zendesk_logo_thumb.jpeg", 30 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 31 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_thumb.jpeg", 32 | "content_type": "image/jpeg", 33 | "size": 2040, 34 | "width": 32, 35 | "height": 32, 36 | "inline": false 37 | }, 38 | { 39 | "url": "https://example.zendesk.com/api/v2/attachments/360000142853.json", 40 | "id": 360000142853, 41 | "file_name": "zendesk_logo_small.jpeg", 42 | "content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 43 | "mapped_content_url": "https://example.zendesk.com/system/brands/3600/0014/2813/zendesk_logo_small.jpeg", 44 | "content_type": "image/jpeg", 45 | "size": 1322, 46 | "width": 24, 47 | "height": 24, 48 | "inline": false 49 | } 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /fixture/PUT/groups.json: -------------------------------------------------------------------------------- 1 | { 2 | "group": { 3 | "url": "https://terraform-provider-zendesk.zendesk.com/api/v2/groups/360002440594.json", 4 | "id": 360002440594, 5 | "name": "Support", 6 | "deleted": false, 7 | "created_at": "2018-11-23T16:05:12Z", 8 | "updated_at": "2018-11-23T16:05:15Z" 9 | } 10 | } -------------------------------------------------------------------------------- /fixture/PUT/macro.json: -------------------------------------------------------------------------------- 1 | { 2 | "macro": { 3 | "actions": [ 4 | { 5 | "field": "status", 6 | "value": "solved" 7 | } 8 | ], 9 | "active": true, 10 | "description": "Sets the ticket status to `solved`", 11 | "id": 2, 12 | "position": 42, 13 | "restriction": {}, 14 | "title": "Close and Save" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /fixture/PUT/organization.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization": { 3 | "url": "https://example.zendesk.com/api/v2/organizations/361898904439.json", 4 | "id": 361898904439, 5 | "name": "Rebel Alliance", 6 | "shared_tickets": true, 7 | "shared_comments": true, 8 | "created_at": "2019-09-17T21:22:18Z", 9 | "updated_at": "2019-09-17T21:22:18Z", 10 | "domain_names": [ 11 | "hoth.com", 12 | "dantooine.com" 13 | ], 14 | "group_id": null, 15 | "tags": [ 16 | "test" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /fixture/PUT/organization_membership.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization_membership": { 3 | "created_at": "2009-05-13T00:07:08Z", 4 | "default": true, 5 | "id": 4, 6 | "organization_id": 361898904439, 7 | "updated_at": "2011-07-22T00:11:12Z", 8 | "user_id": 369531345753 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixture/PUT/redact_ticket_comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": { 3 | "attachments": [], 4 | "author_id": 123, 5 | "id": 123, 6 | "plain_body": "My ID number is ▇▇▇▇!", 7 | "public": true, 8 | "type": "Comment" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /fixture/PUT/redact_ticket_comment_attachment.json: -------------------------------------------------------------------------------- 1 | { 2 | "attachment": { 3 | "content_type": "application/binary", 4 | "content_url": "https://company.zendesk.com/attachments/myfile.dat", 5 | "file_name": "myfile.dat", 6 | "id": 498483, 7 | "size": 2532, 8 | "thumbnails": [], 9 | "url": "https://company.zendesk.com/api/v2/attachments/498483.json" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /fixture/PUT/sla_policies.json: -------------------------------------------------------------------------------- 1 | { 2 | "sla_policy": { 3 | "id": 360000068060, 4 | "title": "Incidents", 5 | "description": "For urgent incidents, we will respond to tickets in 10 minutes", 6 | "position": 3, 7 | "filter": { 8 | "all": [ 9 | { 10 | "field": "type", 11 | "operator": "is", 12 | "value": "incident" 13 | } 14 | ], 15 | "any": [] 16 | }, 17 | "policy_metrics": [ 18 | { 19 | "priority": "normal", 20 | "metric": "first_reply_time", 21 | "target": 30, 22 | "business_hours": false 23 | }, 24 | { 25 | "priority": "urgent", 26 | "metric": "first_reply_time", 27 | "target": 10, 28 | "business_hours": false 29 | }, 30 | { 31 | "priority": "low", 32 | "metric": "requester_wait_time", 33 | "target": 180, 34 | "business_hours": false 35 | }, 36 | { 37 | "priority": "normal", 38 | "metric": "requester_wait_time", 39 | "target": 160, 40 | "business_hours": false 41 | }, 42 | { 43 | "priority": "high", 44 | "metric": "requester_wait_time", 45 | "target": 140, 46 | "business_hours": false 47 | }, 48 | { 49 | "priority": "urgent", 50 | "metric": "requester_wait_time", 51 | "target": 120, 52 | "business_hours": false 53 | } 54 | ] 55 | } 56 | } -------------------------------------------------------------------------------- /fixture/PUT/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": [ 3 | "exchange", 4 | "important", 5 | "example" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /fixture/PUT/target.json: -------------------------------------------------------------------------------- 1 | { 2 | "target": { 3 | "url": "https://example.zendesk.com/api/v2/targets/360000217439.json", 4 | "id": 360000217439, 5 | "created_at": "2019-09-29T08:11:03Z", 6 | "type": "http_target", 7 | "title": "target :: http :: postbin", 8 | "active": true, 9 | "method": "post", 10 | "username": "", 11 | "password": null, 12 | "content_type": "application/json", 13 | "target_url": "https://postb.in/WERcssi2" 14 | } 15 | } -------------------------------------------------------------------------------- /fixture/PUT/ticket.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket": { 3 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/2.json", 4 | "id": 2, 5 | "external_id": null, 6 | "via": { 7 | "channel": "email", 8 | "source": { 9 | "from": { 10 | "address": "nukosuke@lavabit.com", 11 | "name": "Yosuke Tamura" 12 | }, 13 | "to": { 14 | "name": "Terraform Zendesk provider", 15 | "address": "support@d3v-terraform-provider.zendesk.com" 16 | }, 17 | "rel": null 18 | } 19 | }, 20 | "created_at": "2019-06-03T02:23:47Z", 21 | "updated_at": "2019-06-05T01:13:24Z", 22 | "type": null, 23 | "subject": "Mail to create fixture ticket for testing", 24 | "raw_subject": "Mail to create fixture ticket for testing", 25 | "description": "Mail to create fixture ticket for testing\n\nnukosuke (●ↀ ω ↀ●)", 26 | "priority": null, 27 | "status": "solved", 28 | "recipient": "support@d3v-terraform-provider.zendesk.com", 29 | "requester_id": 377922500012, 30 | "submitter_id": 377922500012, 31 | "assignee_id": 377922500012, 32 | "organization_id": 360363695492, 33 | "group_id": 360004077472, 34 | "collaborator_ids": [ 35 | 377922500012 36 | ], 37 | "follower_ids": [ 38 | 377922500012 39 | ], 40 | "email_cc_ids": [], 41 | "forum_topic_id": null, 42 | "problem_id": null, 43 | "has_incidents": false, 44 | "is_public": true, 45 | "due_at": null, 46 | "tags": [], 47 | "custom_fields": [], 48 | "satisfaction_rating": null, 49 | "sharing_agreement_ids": [], 50 | "fields": [], 51 | "followup_ids": [], 52 | "ticket_form_id": 360000389592, 53 | "brand_id": 360002256672, 54 | "satisfaction_probability": null, 55 | "allow_channelback": false, 56 | "allow_attachments": true 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /fixture/PUT/ticket_field.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_field": { 3 | "url": "https://example.zendesk.com/api/v2/ticket_fields/360011737434.json", 4 | "id": 360011737434, 5 | "type": "subject", 6 | "title": "Subject", 7 | "raw_title": "Subject", 8 | "description": "", 9 | "raw_description": "", 10 | "position": 0, 11 | "active": true, 12 | "required": false, 13 | "collapsed_for_agents": false, 14 | "regexp_for_validation": null, 15 | "title_in_portal": "Subject", 16 | "raw_title_in_portal": "Subject", 17 | "visible_in_portal": true, 18 | "editable_in_portal": true, 19 | "required_in_portal": true, 20 | "tag": null, 21 | "created_at": "2018-11-23T16:05:12Z", 22 | "updated_at": "2018-11-24T10:54:05Z", 23 | "removable": false, 24 | "agent_description": null 25 | } 26 | } -------------------------------------------------------------------------------- /fixture/PUT/ticket_form.json: -------------------------------------------------------------------------------- 1 | { 2 | "ticket_form": { 3 | "id": 47, 4 | "url": "https://company.zendesk.com/api/v2/ticket_forms/47.json", 5 | "name": "Snowboard Problem", 6 | "raw_name": "Snowboard Problem", 7 | "display_name": "Snowboard Damage", 8 | "raw_display_name": "{{dc.my_display_name}}", 9 | "end_user_visible": true, 10 | "position": 9999, 11 | "ticket_field_ids": [2, 4, 5, 10, 100, 101, 102, 200], 12 | "active": true, 13 | "default": true, 14 | "in_all_brands": false, 15 | "restricted_brand_ids": [47, 33, 22], 16 | "agent_conditions": [ 17 | { 18 | "parent_field_id": 100, 19 | "value": "matching_value", 20 | "child_fields": [ 21 | { "id": 101, "is_required": false }, 22 | { "id": 200, "is_required": true } 23 | ] 24 | }, 25 | { 26 | "parent_field_id": 101, 27 | "value": "matching_value_2", 28 | "child_fields": [{ "id": 102, "is_required": true }] 29 | } 30 | ], 31 | "end_user_conditions": [ 32 | { 33 | "parent_field_id": 100, 34 | "value": "matching_value", 35 | "child_fields": [{ "id": 101, "is_required": true }] 36 | }, 37 | { 38 | "parent_field_id": 200, 39 | "value": "matching_value", 40 | "child_fields": [{ "id": 202, "is_required": false }] 41 | } 42 | ], 43 | "created_at": "2012-04-02T22:55:29Z", 44 | "updated_at": "2012-04-02T22:55:29Z" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /fixture/PUT/triggers.json: -------------------------------------------------------------------------------- 1 | { 2 | "trigger": { 3 | "url": "https://example.zendesk.com/api/v2/triggers/360056295714.json", 4 | "id": 360056295714, 5 | "title": "Notify requester of received request", 6 | "active": true, 7 | "updated_at": "2018-11-23T16:05:14Z", 8 | "created_at": "2018-11-23T16:05:12Z", 9 | "actions": [ 10 | { 11 | "field": "notification_user", 12 | "value": [ 13 | "requester_id", 14 | "[Request received]", 15 | "Your request ({{ticket.id}}) has been received and is being reviewed by our support staff.\n\nTo add additional comments, reply to this email." 16 | ] 17 | } 18 | ], 19 | "conditions": { 20 | "all": [ 21 | { 22 | "field": "update_type", 23 | "operator": "is", 24 | "value": "Create" 25 | }, 26 | { 27 | "field": "status", 28 | "operator": "is_not", 29 | "value": "solved" 30 | }, 31 | { 32 | "field": "ticket_is_public", 33 | "operator": "is", 34 | "value": "public" 35 | } 36 | ], 37 | "any": [] 38 | }, 39 | "description": null, 40 | "position": 0, 41 | "raw_title": "Notify requester of received request" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /fixture/PUT/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": { 3 | "id": 369531345753, 4 | "url": "https://example.zendesk.com/api/v2/users/369531345753.json", 5 | "name": "Sample customer", 6 | "email": "customer@example.com", 7 | "created_at": "2018-11-23T16:05:13Z", 8 | "updated_at": "2018-11-23T16:05:14Z", 9 | "time_zone": "Osaka", 10 | "iana_time_zone": "Asia/Tokyo", 11 | "phone": null, 12 | "shared_phone_number": null, 13 | "photo": { 14 | "url": "https://example.zendesk.com/api/v2/attachments/360255188054.json", 15 | "id": 360255188054, 16 | "file_name": "profile_image_369531345753_9042965.jpg", 17 | "content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965.jpg", 18 | "mapped_content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965.jpg", 19 | "content_type": "image/jpeg", 20 | "size": 2587, 21 | "width": 40, 22 | "height": 40, 23 | "inline": false, 24 | "thumbnails": [ 25 | { 26 | "url": "https://example.zendesk.com/api/v2/attachments/360255188074.json", 27 | "id": 360255188074, 28 | "file_name": "profile_image_369531345753_9042965_thumb.jpg", 29 | "content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965_thumb.jpg", 30 | "mapped_content_url": "https://example.zendesk.com/system/photos/3602/5518/8054/profile_image_369531345753_9042965_thumb.jpg", 31 | "content_type": "image/jpeg", 32 | "size": 1973, 33 | "width": 32, 34 | "height": 32, 35 | "inline": false 36 | } 37 | ] 38 | }, 39 | "locale_id": 1, 40 | "locale": "en-US", 41 | "organization_id": null, 42 | "role": "end-user", 43 | "verified": false, 44 | "external_id": null, 45 | "tags": [], 46 | "alias": null, 47 | "active": true, 48 | "shared": false, 49 | "shared_agent": false, 50 | "last_login_at": null, 51 | "two_factor_auth_enabled": false, 52 | "signature": null, 53 | "details": null, 54 | "notes": null, 55 | "role_type": null, 56 | "custom_role_id": null, 57 | "moderator": false, 58 | "ticket_restriction": "requested", 59 | "only_private_comments": false, 60 | "restricted_agent": true, 61 | "suspended": false, 62 | "chat_only": false, 63 | "default_group_id": null, 64 | "report_csv": false, 65 | "user_fields": {} 66 | } 67 | } -------------------------------------------------------------------------------- /fixture/ticket_result.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "url": "https://d3v-terraform-provider.zendesk.com/api/v2/tickets/4.json", 4 | "id": 4, 5 | "external_id": null, 6 | "via": { 7 | "channel": "api", 8 | "source": { 9 | "from": {}, 10 | "to": {}, 11 | "rel": null 12 | } 13 | }, 14 | "created_at": "2019-06-06T10:02:04Z", 15 | "updated_at": "2019-06-06T10:02:04Z", 16 | "type": null, 17 | "subject": "nyanyanyanya", 18 | "raw_subject": "nyanyanyanya", 19 | "description": "(●ↀ ω ↀ )", 20 | "priority": "urgent", 21 | "status": "new", 22 | "recipient": null, 23 | "requester_id": 377922500012, 24 | "submitter_id": 377922500012, 25 | "assignee_id": null, 26 | "organization_id": 360363695492, 27 | "group_id": 360004077472, 28 | "collaborator_ids": [ 29 | 377922500012 30 | ], 31 | "follower_ids": [ 32 | 377922500012 33 | ], 34 | "email_cc_ids": [], 35 | "forum_topic_id": null, 36 | "problem_id": null, 37 | "has_incidents": false, 38 | "is_public": true, 39 | "due_at": null, 40 | "tags": [], 41 | "custom_fields": [], 42 | "satisfaction_rating": null, 43 | "sharing_agreement_ids": [], 44 | "fields": [], 45 | "followup_ids": [], 46 | "ticket_form_id": 360000389592, 47 | "brand_id": 360002256672, 48 | "satisfaction_probability": null, 49 | "allow_channelback": false, 50 | "allow_attachments": true, 51 | "result_type": "ticket" 52 | } 53 | ] -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nukosuke/go-zendesk 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/google/go-querystring v1.1.0 7 | github.com/stretchr/testify v1.9.0 8 | go.uber.org/mock v0.4.0 9 | ) 10 | 11 | require ( 12 | github.com/davecgh/go-spew v1.1.1 // indirect 13 | github.com/google/go-cmp v0.5.9 // indirect 14 | github.com/pmezard/go-difflib v1.0.0 // indirect 15 | gopkg.in/yaml.v3 v3.0.1 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 2 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 4 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= 5 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 6 | github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= 7 | github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= 8 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 9 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 10 | github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= 11 | github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 12 | go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= 13 | go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= 14 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 15 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 16 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 17 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 18 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 19 | -------------------------------------------------------------------------------- /script/create_locale_types.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # create_locale_types.rb 4 | # Create locale_types.go from public locale list from API 5 | # 6 | # (C) nukosuke 7 | 8 | require 'json' 9 | require 'uri' 10 | require 'net/http' 11 | require 'erb' 12 | 13 | uri = URI.parse('https://d3v-terraform-provider.zendesk.com/api/v2/locales/public.json') 14 | req = Net::HTTP::Get.new(uri) 15 | res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http| 16 | http.request(req) 17 | end 18 | 19 | if res.is_a? Net::HTTPSuccess 20 | data = JSON.parse(res.body) 21 | puts ERB.new(DATA.read).result(binding) 22 | else 23 | abort "failed to fetch from locale API: #{res.body.inspect}" 24 | end 25 | 26 | __END__ 27 | package zendesk 28 | 29 | // DO NOT EDIT 30 | // This file is generated by script/create_locale_types.rb 31 | // 32 | // <%= data['count'] %> locales are supported 33 | 34 | const (<% data['locales'].each_with_index do |locale, idx| %> 35 | // Locale<%= locale_key = locale['locale'].gsub('-', '').upcase %> <%= locale['presentation_name'] %> 36 | Locale<%= locale_key %> = <%= locale['id'] %><% end %> 37 | ) 38 | 39 | var localeTypeText = map[int]string {<% data['locales'].each do |locale| %> 40 | // Locale<%= locale_key = locale['locale'].gsub('-', '').upcase %> <%= locale['presentation_name'] %> 41 | Locale<%= locale_key %>: "<%= locale['locale'] %>",<% end %> 42 | } 43 | 44 | // LocaleTypeText returns locale type text 45 | func LocaleTypeText(loc int) string { 46 | return localeTypeText[loc] 47 | } 48 | -------------------------------------------------------------------------------- /zendesk/action_types.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // action field types which defined by system 4 | // https://developer.zendesk.com/rest_api/docs/core/triggers#actions-reference 5 | const ( 6 | // ActionFieldStatus status 7 | ActionFieldStatus = iota 8 | // ActionFieldType type 9 | ActionFieldType 10 | // ActionFieldPriority priority 11 | ActionFieldPriority 12 | // ActionFieldGroupID group_id 13 | ActionFieldGroupID 14 | // ActionFieldAssigneeID assignee_id 15 | ActionFieldAssigneeID 16 | // ActionFieldSetTags set_tags 17 | ActionFieldSetTags 18 | // ActionFieldCurrentTags current_tags 19 | ActionFieldCurrentTags 20 | // ActionFieldRemoveTags remove_tags 21 | ActionFieldRemoveTags 22 | // ActionFieldSatisfactionScore satisfaction_score 23 | ActionFieldSatisfactionScore 24 | // ActionFieldNotificationUser notification_user 25 | ActionFieldNotificationUser 26 | // ActionFieldNotificationGroup notification_group 27 | ActionFieldNotificationGroup 28 | // ActionFieldNotificationTarget notification_target 29 | ActionFieldNotificationTarget 30 | // ActionFieldTweetRequester tweet_requester 31 | ActionFieldTweetRequester 32 | // ActionFieldCC cc 33 | ActionFieldCC 34 | // ActionFieldLocaleID locale_id 35 | ActionFieldLocaleID 36 | // ActionFieldSubject subject 37 | ActionFieldSubject 38 | // ActionFieldCommentValue comment_value 39 | ActionFieldCommentValue 40 | // ActionFieldCommentValueHTML comment_value_html 41 | ActionFieldCommentValueHTML 42 | // ActionFieldCommentModeIsPublic comment_mode_is_public 43 | ActionFieldCommentModeIsPublic 44 | // ActionFieldTicketFormID ticket_form_id 45 | ActionFieldTicketFormID 46 | ) 47 | 48 | var actionFieldText = map[int]string{ 49 | ActionFieldStatus: "status", 50 | ActionFieldType: "type", 51 | ActionFieldPriority: "priority", 52 | ActionFieldGroupID: "group_id", 53 | ActionFieldAssigneeID: "assignee_id", 54 | ActionFieldSetTags: "set_tags", 55 | ActionFieldCurrentTags: "current_tags", 56 | ActionFieldRemoveTags: "remove_tags", 57 | ActionFieldSatisfactionScore: "satisfaction_score", 58 | ActionFieldNotificationUser: "notification_user", 59 | ActionFieldNotificationGroup: "notification_group", 60 | ActionFieldNotificationTarget: "notification_target", 61 | ActionFieldTweetRequester: "tweet_requester", 62 | ActionFieldCC: "cc", 63 | ActionFieldLocaleID: "locale_id", 64 | ActionFieldSubject: "subject", 65 | ActionFieldCommentValue: "comment_value", 66 | ActionFieldCommentValueHTML: "comment_value_html", 67 | ActionFieldCommentModeIsPublic: "comment_mode_is_public", 68 | ActionFieldTicketFormID: "ticket_form_id", 69 | } 70 | 71 | // ActionFieldText takes field type and returns field name string 72 | func ActionFieldText(fieldType int) string { 73 | return actionFieldText[fieldType] 74 | } 75 | -------------------------------------------------------------------------------- /zendesk/action_types_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestActionFieldText(t *testing.T) { 6 | if action := ActionFieldText(ActionFieldStatus); action != "status" { 7 | t.Fatal(`expected "status", but got ` + action) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /zendesk/all_ticket_audit_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetAllTicketAuditsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[TicketAudit] { 14 | return &Iterator[TicketAudit]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetAllTicketAuditsOBP, 23 | cbpFunc: z.GetAllTicketAuditsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetAllTicketAuditsOBP(ctx context.Context, opts *OBPOptions) ([]TicketAudit, Page, error) { 28 | var data struct { 29 | TicketAudits []TicketAudit `json:"audits"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/ticket_audits.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.TicketAudits, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetAllTicketAuditsCBP(ctx context.Context, opts *CBPOptions) ([]TicketAudit, CursorPaginationMeta, error) { 52 | var data struct { 53 | TicketAudits []TicketAudit `json:"audits"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/ticket_audits.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.TicketAudits, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/api.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | //nolint 4 | //go:generate mockgen -source=api.go -destination=mock/client.go -package=mock -mock_names=API=Client github.com/nukosuke/go-zendesk/zendesk API 5 | 6 | // API an interface containing all of the zendesk client methods 7 | type API interface { 8 | AppAPI 9 | AttachmentAPI 10 | AutomationAPI 11 | BaseAPI 12 | BrandAPI 13 | CustomRoleAPI 14 | DynamicContentAPI 15 | GroupAPI 16 | GroupMembershipAPI 17 | LocaleAPI 18 | MacroAPI 19 | OrganizationAPI 20 | OrganizationFieldAPI 21 | OrganizationMembershipAPI 22 | SearchAPI 23 | SLAPolicyAPI 24 | TagAPI 25 | TargetAPI 26 | TicketAuditAPI 27 | TicketAPI 28 | TicketCommentAPI 29 | TicketFieldAPI 30 | TicketFormAPI 31 | TriggerAPI 32 | UserAPI 33 | UserFieldAPI 34 | ViewAPI 35 | WebhookAPI 36 | CustomObjectAPI 37 | } 38 | 39 | var _ API = (*Client)(nil) 40 | -------------------------------------------------------------------------------- /zendesk/app.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | // AppInstallation is a struct representing an app that has been installed from the Zendesk Marketplace. 10 | // https://developer.zendesk.com/api-reference/ticketing/apps/apps/#example-responses-11 11 | type AppInstallation struct { 12 | ID int64 `json:"id"` 13 | AppID int64 `json:"app_id"` 14 | Product string `json:"product"` 15 | Settings struct { 16 | Name string `json:"name"` 17 | Title string `json:"title"` 18 | } `json:"settings"` 19 | SettingsObjects []struct { 20 | Name string `json:"name"` 21 | Value string `json:"value"` 22 | } `json:"settings_objects"` 23 | Enabled bool `json:"enabled"` 24 | Updated string `json:"updated"` 25 | UpdatedAt time.Time `json:"updated_at"` 26 | CreatedAt time.Time `json:"created_at"` 27 | RecurringPayment bool `json:"recurring_payment"` 28 | Collapsible bool `json:"collapsible"` 29 | Paid bool `json:"paid"` 30 | HasUnpaidSubscription bool `json:"has_unpaid_subscription"` 31 | HasIncompleteSubscription bool `json:"has_incomplete_subscription"` 32 | } 33 | 34 | // AppAPI is an interface containing all methods associated with zendesk apps 35 | type AppAPI interface { 36 | ListInstallations(ctx context.Context) ([]AppInstallation, error) 37 | } 38 | 39 | // ListInstallations shows all apps installed in the current account. 40 | // ref: https://developer.zendesk.com/api-reference/ticketing/apps/apps/#list-app-installations 41 | func (z *Client) ListInstallations(ctx context.Context) ([]AppInstallation, error) { 42 | var out struct { 43 | Installations []AppInstallation `json:"installations"` 44 | } 45 | 46 | body, err := z.get(ctx, "/apps/installations") 47 | if err != nil { 48 | return nil, err 49 | } 50 | 51 | err = json.Unmarshal(body, &out) 52 | return out.Installations, err 53 | } 54 | -------------------------------------------------------------------------------- /zendesk/app_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "reflect" 7 | "testing" 8 | "time" 9 | ) 10 | 11 | func TestListAppInstallations(t *testing.T) { 12 | mockAPI := newMockAPIWithStatus(http.MethodGet, "apps.json", http.StatusOK) 13 | client := newTestClient(mockAPI) 14 | defer mockAPI.Close() 15 | 16 | actual, err := client.ListInstallations(ctx) 17 | if err != nil { 18 | t.Fatalf("Failed to send request to list app installations: %s", err) 19 | } 20 | 21 | expected := []AppInstallation{ 22 | { 23 | ID: 42, 24 | AppID: 913, 25 | Product: "support", 26 | Settings: struct { 27 | Name string `json:"name"` 28 | Title string `json:"title"` 29 | }{ 30 | Name: "Mystery App", 31 | Title: "Mystery App", 32 | }, 33 | SettingsObjects: []struct { 34 | Name string `json:"name"` 35 | Value string `json:"value"` 36 | }{ 37 | { 38 | Name: "setting-one", 39 | Value: "value-one", 40 | }, 41 | { 42 | Name: "setting-two", 43 | Value: "value-two", 44 | }, 45 | }, 46 | Enabled: true, 47 | Paid: false, 48 | UpdatedAt: time.Date(2023, 1, 1, 1, 1, 1, 0, time.UTC), 49 | CreatedAt: time.Date(2023, 1, 1, 1, 1, 1, 0, time.UTC), 50 | }, 51 | { 52 | ID: 42, 53 | AppID: 917, 54 | Product: "support", 55 | Settings: struct { 56 | Name string `json:"name"` 57 | Title string `json:"title"` 58 | }{ 59 | Name: "Mystery App 2", 60 | Title: "Mystery App 2", 61 | }, 62 | SettingsObjects: []struct { 63 | Name string `json:"name"` 64 | Value string `json:"value"` 65 | }{ 66 | { 67 | Name: "foo", 68 | Value: "bar", 69 | }, 70 | }, 71 | Enabled: true, 72 | Paid: false, 73 | UpdatedAt: time.Date(2023, 2, 2, 2, 2, 2, 0, time.UTC), 74 | CreatedAt: time.Date(2023, 2, 2, 2, 2, 2, 0, time.UTC), 75 | }, 76 | } 77 | 78 | if len(actual) != 2 { 79 | t.Fatalf("expected 2 apps, got %d", len(actual)) 80 | } 81 | if !reflect.DeepEqual(expected, actual) { 82 | t.Fatalf("apps not equal") 83 | } 84 | } 85 | 86 | func TestListAppInstallationsCanceledContext(t *testing.T) { 87 | mockAPI := newMockAPIWithStatus(http.MethodPost, "apps.json", http.StatusOK) 88 | client := newTestClient(mockAPI) 89 | defer mockAPI.Close() 90 | 91 | canceled, cancel := context.WithCancel(ctx) 92 | cancel() 93 | 94 | _, err := client.ListInstallations(canceled) 95 | if err == nil { 96 | t.Fatalf("did not get expected error") 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /zendesk/automation_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetAutomationsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Automation] { 14 | return &Iterator[Automation]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetAutomationsOBP, 23 | cbpFunc: z.GetAutomationsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetAutomationsOBP(ctx context.Context, opts *OBPOptions) ([]Automation, Page, error) { 28 | var data struct { 29 | Automations []Automation `json:"automations"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/automation.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Automations, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetAutomationsCBP(ctx context.Context, opts *CBPOptions) ([]Automation, CursorPaginationMeta, error) { 52 | var data struct { 53 | Automations []Automation `json:"automations"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/automation.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Automations, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/brand_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func TestCreateBrand(t *testing.T) { 11 | mockAPI := newMockAPIWithStatus(http.MethodPost, "brands.json", http.StatusCreated) 12 | client := newTestClient(mockAPI) 13 | defer mockAPI.Close() 14 | 15 | _, err := client.CreateBrand(ctx, Brand{}) 16 | if err != nil { 17 | t.Fatalf("Failed to send request to create brand: %s", err) 18 | } 19 | } 20 | 21 | func TestCreateBrandCanceledContext(t *testing.T) { 22 | mockAPI := newMockAPIWithStatus(http.MethodPost, "brands.json", http.StatusCreated) 23 | client := newTestClient(mockAPI) 24 | defer mockAPI.Close() 25 | 26 | canceled, cancelFunc := context.WithCancel(ctx) 27 | cancelFunc() 28 | 29 | _, err := client.CreateBrand(canceled, Brand{}) 30 | if err == nil { 31 | t.Fatalf("did not get expected error") 32 | } 33 | } 34 | 35 | func TestGetBrand(t *testing.T) { 36 | mockAPI := newMockAPI(http.MethodGet, "brand.json") 37 | client := newTestClient(mockAPI) 38 | defer mockAPI.Close() 39 | 40 | brand, err := client.GetBrand(ctx, 123) 41 | if err != nil { 42 | t.Fatalf("Failed to get brand: %s", err) 43 | } 44 | 45 | expectedID := int64(360002143133) 46 | if brand.ID != expectedID { 47 | t.Fatalf("Returned brand does not have the expected ID %d. Brand ID is %d", expectedID, brand.ID) 48 | } 49 | } 50 | 51 | func TestUpdateBrand(t *testing.T) { 52 | mockAPI := newMockAPIWithStatus(http.MethodPut, "brands.json", http.StatusOK) 53 | client := newTestClient(mockAPI) 54 | defer mockAPI.Close() 55 | 56 | updatedBrand, err := client.UpdateBrand(ctx, int64(1234), Brand{}) 57 | if err != nil { 58 | t.Fatalf("Failed to send request to create brand: %s", err) 59 | } 60 | 61 | expectedID := int64(360002143133) 62 | if updatedBrand.ID != expectedID { 63 | t.Fatalf("Updated brand %v did not have expected id %d", updatedBrand, expectedID) 64 | } 65 | } 66 | 67 | func TestUpdateBrandCanceledContext(t *testing.T) { 68 | mockAPI := newMockAPIWithStatus(http.MethodPut, "brands.json", http.StatusOK) 69 | client := newTestClient(mockAPI) 70 | defer mockAPI.Close() 71 | 72 | canceled, cancelFunc := context.WithCancel(ctx) 73 | cancelFunc() 74 | _, err := client.UpdateBrand(canceled, int64(1234), Brand{}) 75 | if err == nil { 76 | t.Fatalf("did not get expected error") 77 | } 78 | } 79 | 80 | func TestDeleteBrand(t *testing.T) { 81 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 82 | w.WriteHeader(http.StatusNoContent) 83 | w.Write(nil) 84 | })) 85 | 86 | c := newTestClient(mockAPI) 87 | err := c.DeleteBrand(ctx, 1234) 88 | if err != nil { 89 | t.Fatalf("Failed to delete brand: %s", err) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /zendesk/collaborators.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "reflect" 7 | ) 8 | 9 | // Collaborator is user information for collaborator field value 10 | type Collaborator struct { 11 | Name string `json:"name,omitempty"` 12 | Email string `json:"email,omitempty"` 13 | } 14 | 15 | // Collaborators hold array of interface which can take Collaborator 16 | // 17 | // ref: https://developer.zendesk.com/rest_api/docs/support/tickets#setting-collaborators 18 | type Collaborators struct { 19 | collaborators []interface{} 20 | } 21 | 22 | // String return string formatted for 23 | func (c *Collaborators) String() string { 24 | return fmt.Sprintf("%v", c.collaborators) 25 | } 26 | 27 | // List return internal array in Collaborators 28 | func (c *Collaborators) List() []interface{} { 29 | return c.collaborators 30 | } 31 | 32 | // Append add any type of collaborator data payload to Collaborators. 33 | // The type can be string, int64, Collaborator or map[string]interface{} 34 | // which must include "name" and "email" field 35 | func (c *Collaborators) Append(i interface{}) error { 36 | switch e := i.(type) { 37 | case string: 38 | c.collaborators = append(c.collaborators, e) 39 | case Collaborator: 40 | c.collaborators = append(c.collaborators, e) 41 | case int64: 42 | c.collaborators = append(c.collaborators, e) 43 | case map[string]interface{}: 44 | collab := Collaborator{} 45 | name, ok := e["name"] 46 | if !ok { 47 | return fmt.Errorf("map %v did not contain a name value", e) 48 | } 49 | 50 | collab.Name, ok = name.(string) 51 | if !ok { 52 | return fmt.Errorf("type of name %v was not string", name) 53 | } 54 | 55 | email, ok := e["email"] 56 | if !ok { 57 | return fmt.Errorf("map %v did not contain an email value", e) 58 | } 59 | 60 | collab.Email, ok = email.(string) 61 | if !ok { 62 | return fmt.Errorf("type of email %v was not string", name) 63 | } 64 | c.collaborators = append(c.collaborators, collab) 65 | default: 66 | return fmt.Errorf("unsupported collaborator type %v", reflect.TypeOf(i)) 67 | } 68 | 69 | return nil 70 | } 71 | 72 | // MarshalJSON is marshaller for Collaborators 73 | func (c Collaborators) MarshalJSON() ([]byte, error) { 74 | return json.Marshal(c.collaborators) 75 | } 76 | 77 | // UnmarshalJSON is unmarshaller for Collaborators 78 | func (c *Collaborators) UnmarshalJSON(b []byte) error { 79 | var tmpCollaborators []interface{} 80 | newCollaborators := Collaborators{} 81 | err := json.Unmarshal(b, &tmpCollaborators) 82 | if err != nil { 83 | return err 84 | } 85 | 86 | for _, i := range tmpCollaborators { 87 | var err error 88 | switch e := i.(type) { 89 | case float64: 90 | err = newCollaborators.Append(int64(e)) 91 | default: 92 | err = newCollaborators.Append(i) 93 | } 94 | 95 | if err != nil { 96 | return err 97 | } 98 | } 99 | 100 | c.collaborators = newCollaborators.List() 101 | return nil 102 | } 103 | -------------------------------------------------------------------------------- /zendesk/collaborators_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "encoding/json" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | const collaboratorListJSON = `[562,"someone@example.com",{"name":"SomeoneElse","email":"else@example.com"}]` 10 | 11 | func TestCanBeUnmarshalled(t *testing.T) { 12 | c := &Collaborators{} 13 | err := c.UnmarshalJSON([]byte(collaboratorListJSON)) 14 | if err != nil { 15 | t.Fatalf("Unmarshal returned an error %v", err) 16 | } 17 | 18 | list := c.List() 19 | if len(list) != 3 { 20 | t.Fatalf("Collaborators %v did not have the correct length when unmarshaled", c) 21 | } 22 | 23 | for _, i := range list { 24 | switch i.(type) { 25 | case string: 26 | case int64: 27 | case Collaborator: 28 | //do nothing 29 | default: 30 | t.Fatalf("List contained an unexpected type %v", reflect.TypeOf(i)) 31 | } 32 | } 33 | } 34 | 35 | func TestCanBeMarshalled(t *testing.T) { 36 | c := &Collaborators{} 37 | err := c.UnmarshalJSON([]byte(collaboratorListJSON)) 38 | if err != nil { 39 | t.Fatalf("Unmarshal returned an error %v", err) 40 | } 41 | 42 | out, err := c.MarshalJSON() 43 | if err != nil { 44 | t.Fatalf("Marshal returned an error %v", err) 45 | } 46 | 47 | if string(out) != collaboratorListJSON { 48 | t.Fatalf("Json output %s did not match expected output %s", out, collaboratorListJSON) 49 | } 50 | } 51 | 52 | func TestCanBeRemarshalled(t *testing.T) { 53 | var src, dst Collaborators 54 | marshalled, err := json.Marshal(src) 55 | if err != nil { 56 | t.Fatalf("Marshalling returned an error %v", err) 57 | } 58 | err = json.Unmarshal(marshalled, &dst) 59 | if err != nil { 60 | t.Fatalf("Unmarshal returned an error %v", err) 61 | } 62 | 63 | if !reflect.DeepEqual(src, dst) { 64 | t.Fatalf("remarshalling is inconsistent") 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /zendesk/condition_types_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestConditionFieldText(t *testing.T) { 6 | if cond := ConditionFieldText(ConditionFieldGroupID); cond != "group_id" { 7 | t.Fatal(`expected "group_id", but got ` + cond) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /zendesk/credential.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // Credential is interface of API credential 4 | type Credential interface { 5 | Email() string 6 | Secret() string 7 | Bearer() bool 8 | } 9 | 10 | // BasicAuthCredential is type of credential for Basic authentication 11 | type BasicAuthCredential struct { 12 | email string 13 | password string 14 | } 15 | 16 | // NewBasicAuthCredential creates BasicAuthCredential and returns its pointer 17 | func NewBasicAuthCredential(email string, password string) *BasicAuthCredential { 18 | return &BasicAuthCredential{ 19 | email: email, 20 | password: password, 21 | } 22 | } 23 | 24 | // Email is accessor which returns email address 25 | func (c BasicAuthCredential) Email() string { 26 | return c.email 27 | } 28 | 29 | // Secret is accessor which returns password 30 | func (c BasicAuthCredential) Secret() string { 31 | return c.password 32 | } 33 | 34 | // Bearer is accessor which returns whether the credential is a bearer token 35 | func (c BasicAuthCredential) Bearer() bool { 36 | return false 37 | } 38 | 39 | // APITokenCredential is type of credential for API token authentication 40 | type APITokenCredential struct { 41 | email string 42 | apiToken string 43 | } 44 | 45 | // NewAPITokenCredential creates APITokenCredential and returns its pointer 46 | func NewAPITokenCredential(email string, apiToken string) *APITokenCredential { 47 | return &APITokenCredential{ 48 | email: email, 49 | apiToken: apiToken, 50 | } 51 | } 52 | 53 | // Email is accessor which returns email address 54 | func (c APITokenCredential) Email() string { 55 | return c.email + "/token" 56 | } 57 | 58 | // Secret is accessor which returns API token 59 | func (c APITokenCredential) Secret() string { 60 | return c.apiToken 61 | } 62 | 63 | // Bearer is accessor which returns whether the credential is a bearer token 64 | func (c APITokenCredential) Bearer() bool { 65 | return false 66 | } 67 | 68 | // BearerTokenCredential can be used to authenticate OAuth tokens issued by Zendesk. 69 | type BearerTokenCredential struct { 70 | token string 71 | } 72 | 73 | // NewBearerTokenCredential returns a pointer to a new BearerTokenCredential. Bearer 74 | // tokens are issued by Zendesk OAuth clients. 75 | func NewBearerTokenCredential(token string) *BearerTokenCredential { 76 | return &BearerTokenCredential{token: token} 77 | } 78 | 79 | // Email is accessor which returns email address 80 | func (c BearerTokenCredential) Email() string { 81 | return "" 82 | } 83 | 84 | // Secret is accessor which returns API token 85 | func (c BearerTokenCredential) Secret() string { 86 | return c.token 87 | } 88 | 89 | // Bearer is accessor which returns whether the credential is a bearer token 90 | func (c BearerTokenCredential) Bearer() bool { 91 | return true 92 | } 93 | -------------------------------------------------------------------------------- /zendesk/credential_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestNewBasicAuthCredential(t *testing.T) { 6 | cred := NewBasicAuthCredential("john.doe@example.com", "password") 7 | 8 | if cred.Email() != "john.doe@example.com" { 9 | t.Fatalf("BasicAuthCredential: email not match") 10 | } 11 | if cred.Secret() != "password" { 12 | t.Fatalf("BasicAuthCredential: secret not match") 13 | } 14 | if cred.Bearer() { 15 | t.Fatalf("BasicAuthCredential: not a bearer token") 16 | } 17 | } 18 | 19 | func TestNewAPITokenCredential(t *testing.T) { 20 | cred := NewAPITokenCredential("john.doe@example.com", "apitoken") 21 | 22 | if cred.Email() != "john.doe@example.com"+"/token" { 23 | t.Fatalf("APITokenCredential: email not match") 24 | } 25 | if cred.Secret() != "apitoken" { 26 | t.Fatalf("APITokenCredential: secret not match") 27 | } 28 | if cred.Bearer() { 29 | t.Fatalf("APITokenCredential: not a bearer token") 30 | } 31 | } 32 | 33 | func TestNewBearerTokenCredential(t *testing.T) { 34 | cred := NewBearerTokenCredential("apitoken") 35 | 36 | if cred.Email() != "" { 37 | t.Fatalf("BearerTokenCredential: email not match") 38 | } 39 | if cred.Secret() != "apitoken" { 40 | t.Fatalf("BearerTokenCredential: secret not match") 41 | } 42 | if !cred.Bearer() { 43 | t.Fatalf("BearerTokenCredential: is a bearer token") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /zendesk/cursor.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // DEPRECATED -- This file describes Zendesk API's "legacy" cursor pagination. 4 | // PLEASE USE CursorPagination IN zendesk.go INSTEAD! 5 | 6 | // Cursor is struct for cursor-based pagination 7 | type Cursor struct { 8 | AfterURL string `json:"after_url"` 9 | AfterCursor string `json:"after_cursor"` 10 | BeforeURL string `json:"before_url"` 11 | BeforeCursor string `json:"before_cursor"` 12 | } 13 | 14 | // CursorOption is options for list methods for cursor-based pagination resources 15 | // It's used to create query string. 16 | // 17 | // https://developer.zendesk.com/rest_api/docs/support/incremental_export#cursor-based-incremental-exports 18 | type CursorOption struct { 19 | StartTime int64 `url:"start_time,omitempty"` 20 | Cursor string `url:"cursor,omitempty"` 21 | } 22 | -------------------------------------------------------------------------------- /zendesk/custom_field_option.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // CustomFieldOption is struct for value of `custom_field_options` 4 | type CustomFieldOption struct { 5 | ID int64 `json:"id,omitempty"` 6 | Name string `json:"name"` 7 | Position int64 `json:"position,omitempty"` 8 | RawName string `json:"raw_name,omitempty"` 9 | URL string `json:"url,omitempty"` 10 | Value string `json:"value"` 11 | } 12 | 13 | type relationshipFilterObject struct { 14 | Field string `json:"field"` 15 | Operator string `json:"operator"` 16 | Value string `json:"value"` 17 | } 18 | 19 | // RelationshipFilter is struct for value of `relationship_filter` 20 | type RelationshipFilter struct { 21 | All []relationshipFilterObject `json:"all"` 22 | Any []relationshipFilterObject `json:"any"` 23 | } 24 | -------------------------------------------------------------------------------- /zendesk/custom_role.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | // Configuration is a dictionary of custom configuration fields 10 | type Configuration map[string]interface{} 11 | 12 | // CustomRole is zendesk CustomRole JSON payload format 13 | // https://developer.zendesk.com/api-reference/ticketing/account-configuration/custom_roles/ 14 | type CustomRole struct { 15 | Description string `json:"description,omitempty"` 16 | ID int64 `json:"id,omitempty"` 17 | TeamMemberCount int64 `json:"team_member_count"` 18 | Name string `json:"name"` 19 | Configuration Configuration `json:"configuration"` 20 | RoleType int64 `json:"role_type"` 21 | CreatedAt time.Time `json:"created_at,omitempty"` 22 | UpdatedAt time.Time `json:"updated_at,omitempty"` 23 | } 24 | 25 | // CustomRoleAPI an interface containing all CustomRole related methods 26 | type CustomRoleAPI interface { 27 | GetCustomRoles(ctx context.Context) ([]CustomRole, error) 28 | } 29 | 30 | // GetRoles fetch CustomRoles list 31 | func (z *Client) GetCustomRoles(ctx context.Context) ([]CustomRole, error) { 32 | var data struct { 33 | CustomRoles []CustomRole `json:"custom_roles"` 34 | Page 35 | } 36 | 37 | u := "/custom_roles.json" 38 | 39 | body, err := z.get(ctx, u) 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | err = json.Unmarshal(body, &data) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return data.CustomRoles, nil 49 | } 50 | -------------------------------------------------------------------------------- /zendesk/dynamic_content_generated.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "context" 4 | 5 | func (z *Client) GetDynamicContentItemsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[DynamicContentItem] { 6 | return &Iterator[DynamicContentItem]{ 7 | CommonOptions: opts.CommonOptions, 8 | pageSize: opts.PageSize, 9 | hasMore: true, 10 | isCBP: opts.IsCBP, 11 | pageAfter: "", 12 | pageIndex: 1, 13 | ctx: ctx, 14 | obpFunc: z.GetDynamicContentItemsOBP, 15 | cbpFunc: z.GetDynamicContentItemsCBP, 16 | } 17 | } 18 | 19 | func (z *Client) GetDynamicContentItemsOBP(ctx context.Context, opts *OBPOptions) ([]DynamicContentItem, Page, error) { 20 | var data struct { 21 | DynamicContentItems []DynamicContentItem `json:"items"` 22 | Page 23 | } 24 | 25 | tmp := opts 26 | if tmp == nil { 27 | tmp = &OBPOptions{} 28 | } 29 | 30 | u, err := addOptions("/dynamic_content/items.json", tmp) 31 | if err != nil { 32 | return nil, Page{}, err 33 | } 34 | 35 | err = getData(z, ctx, u, &data) 36 | if err != nil { 37 | return nil, Page{}, err 38 | } 39 | return data.DynamicContentItems, data.Page, nil 40 | } 41 | 42 | func (z *Client) GetDynamicContentItemsCBP(ctx context.Context, opts *CBPOptions) ([]DynamicContentItem, CursorPaginationMeta, error) { 43 | var data struct { 44 | DynamicContentItems []DynamicContentItem `json:"items"` 45 | Meta CursorPaginationMeta `json:"meta"` 46 | } 47 | 48 | tmp := opts 49 | if tmp == nil { 50 | tmp = &CBPOptions{} 51 | } 52 | 53 | u, err := addOptions("/dynamic_content/items.json", tmp) 54 | if err != nil { 55 | return nil, data.Meta, err 56 | } 57 | 58 | err = getData(z, ctx, u, &data) 59 | if err != nil { 60 | return nil, data.Meta, err 61 | } 62 | return data.DynamicContentItems, data.Meta, nil 63 | } 64 | 65 | -------------------------------------------------------------------------------- /zendesk/dynamic_content_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetDynamicContentItems(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "dynamic_content/items.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | items, page, err := client.GetDynamicContentItems(ctx) 14 | if err != nil { 15 | t.Fatalf("Failed to get dynamic content items: %s", err) 16 | } 17 | 18 | if len(items) != 2 { 19 | t.Fatalf("expected length of dynamic content items is 2, but got %d", len(items)) 20 | } 21 | 22 | if len(items[0].Variants) != 3 { 23 | t.Fatalf("expected length of items[0].Variants is 3, but got %d", len(items[0].Variants)) 24 | } 25 | 26 | if page.HasPrev() || page.HasNext() { 27 | t.Fatalf("page fields are wrong: %v", page) 28 | } 29 | } 30 | 31 | func TestCreateDynamicContentItem(t *testing.T) { 32 | mockAPI := newMockAPIWithStatus(http.MethodPost, "dynamic_content/items.json", http.StatusCreated) 33 | client := newTestClient(mockAPI) 34 | defer mockAPI.Close() 35 | 36 | item, err := client.CreateDynamicContentItem(ctx, DynamicContentItem{}) 37 | if err != nil { 38 | t.Fatalf("Failed to get valid response: %s", err) 39 | } 40 | if item.ID == 0 { 41 | t.Fatal("Failed to create dynamic content item") 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /zendesk/error.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "io/ioutil" 8 | "net/http" 9 | ) 10 | 11 | // Error an error type containing the http response from zendesk 12 | type Error struct { 13 | body []byte 14 | resp *http.Response 15 | } 16 | 17 | // NewError is a function to initialize the Error type. This function will be useful 18 | // for unit testing and mocking purposes in the client side 19 | // to test their behavior by the API response. 20 | func NewError(body []byte, resp *http.Response) Error { 21 | return Error{ 22 | body: body, 23 | resp: resp, 24 | } 25 | } 26 | 27 | // Error the error string for this error 28 | func (e Error) Error() string { 29 | msg := string(e.body) 30 | if msg == "" { 31 | msg = http.StatusText(e.Status()) 32 | } 33 | 34 | return fmt.Sprintf("%d: %s", e.resp.StatusCode, msg) 35 | } 36 | 37 | // Body is the Body of the HTTP response 38 | func (e Error) Body() io.ReadCloser { 39 | return ioutil.NopCloser(bytes.NewBuffer(e.body)) 40 | } 41 | 42 | // Headers the HTTP headers returned from zendesk 43 | func (e Error) Headers() http.Header { 44 | return e.resp.Header 45 | } 46 | 47 | // Status the HTTP status code returned from zendesk 48 | func (e Error) Status() int { 49 | return e.resp.StatusCode 50 | } 51 | 52 | // OptionsError is an error type for invalid option argument. 53 | type OptionsError struct { 54 | opts interface{} 55 | } 56 | 57 | func (e *OptionsError) Error() string { 58 | return fmt.Sprintf("invalid options: %v", e.opts) 59 | } 60 | -------------------------------------------------------------------------------- /zendesk/error_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "testing" 7 | ) 8 | 9 | func TestError_Error(t *testing.T) { 10 | status := http.StatusOK 11 | resp := &http.Response{ 12 | StatusCode: status, 13 | } 14 | body := []byte("foo") 15 | err := Error{ 16 | body: body, 17 | resp: resp, 18 | } 19 | 20 | expected := fmt.Sprintf("%d: %s", status, body) 21 | if v := err.Error(); v != expected { 22 | t.Fatalf("Error %s did not have expected value %s", v, expected) 23 | } 24 | } 25 | 26 | func TestError_ErrorEmptyBody(t *testing.T) { 27 | status := http.StatusOK 28 | resp := &http.Response{ 29 | StatusCode: status, 30 | } 31 | err := Error{ 32 | resp: resp, 33 | } 34 | 35 | expected := fmt.Sprintf("%d: %s", status, http.StatusText(status)) 36 | if v := err.Error(); v != expected { 37 | t.Fatalf("Error %s did not have expected value %s", v, expected) 38 | } 39 | } 40 | 41 | func TestError_Headers(t *testing.T) { 42 | retryAfter := "Retry-After" 43 | resp := &http.Response{ 44 | StatusCode: http.StatusTooManyRequests, 45 | Header: http.Header{ 46 | retryAfter: []string{"92"}, 47 | }, 48 | } 49 | 50 | err := Error{ 51 | resp: resp, 52 | } 53 | 54 | if _, ok := err.Headers()[retryAfter]; !ok { 55 | t.Fatal("Could not get header values from zendesk error") 56 | } 57 | } 58 | 59 | func TestError_Status(t *testing.T) { 60 | retryAfter := "Retry-After" 61 | resp := &http.Response{ 62 | StatusCode: http.StatusTooManyRequests, 63 | Header: http.Header{ 64 | retryAfter: []string{"92"}, 65 | }, 66 | } 67 | 68 | err := Error{ 69 | resp: resp, 70 | } 71 | 72 | if status := err.Status(); status != http.StatusTooManyRequests { 73 | t.Fatal("Status returned from error was not the correct status code") 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /zendesk/group_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetGroupsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Group] { 14 | return &Iterator[Group]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetGroupsOBP, 23 | cbpFunc: z.GetGroupsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetGroupsOBP(ctx context.Context, opts *OBPOptions) ([]Group, Page, error) { 28 | var data struct { 29 | Groups []Group `json:"groups"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/groups.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Groups, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetGroupsCBP(ctx context.Context, opts *CBPOptions) ([]Group, CursorPaginationMeta, error) { 52 | var data struct { 53 | Groups []Group `json:"groups"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/groups.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Groups, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/group_membership.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | type ( 10 | // GroupMembership is struct for group membership payload 11 | // https://developer.zendesk.com/api-reference/ticketing/groups/group_memberships/ 12 | GroupMembership struct { 13 | ID int64 `json:"id,omitempty"` 14 | URL string `json:"url,omitempty"` 15 | UserID int64 `json:"user_id"` 16 | GroupID int64 `json:"group_id"` 17 | Default bool `json:"default"` 18 | Name string `json:"name"` 19 | CreatedAt time.Time `json:"created_at,omitempty"` 20 | UpdatedAt time.Time `json:"updated_at,omitempty"` 21 | } 22 | 23 | // GroupMembershipListOptions is a struct for options for group membership list 24 | // ref: https://developer.zendesk.com/api-reference/ticketing/groups/group_memberships/ 25 | GroupMembershipListOptions struct { 26 | PageOptions 27 | GroupID int64 `json:"group_id,omitempty" url:"group_id,omitempty"` 28 | UserID int64 `json:"user_id,omitempty" url:"user_id,omitempty"` 29 | } 30 | 31 | // GroupMembershipAPI is an interface containing group membership related methods 32 | GroupMembershipAPI interface { 33 | GetGroupMemberships(context.Context, *GroupMembershipListOptions) ([]GroupMembership, Page, error) 34 | GetGroupMembershipsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[GroupMembership] 35 | GetGroupMembershipsOBP(ctx context.Context, opts *OBPOptions) ([]GroupMembership, Page, error) 36 | GetGroupMembershipsCBP(ctx context.Context, opts *CBPOptions) ([]GroupMembership, CursorPaginationMeta, error) 37 | } 38 | ) 39 | 40 | // GetGroupMemberships gets the memberships of the specified group 41 | // ref: https://developer.zendesk.com/api-reference/ticketing/groups/group_memberships/ 42 | func (z *Client) GetGroupMemberships(ctx context.Context, opts *GroupMembershipListOptions) ([]GroupMembership, Page, error) { 43 | var result struct { 44 | GroupMemberships []GroupMembership `json:"group_memberships"` 45 | Page 46 | } 47 | 48 | tmp := opts 49 | if tmp == nil { 50 | tmp = new(GroupMembershipListOptions) 51 | } 52 | 53 | u, err := addOptions("/group_memberships.json", tmp) 54 | if err != nil { 55 | return nil, Page{}, err 56 | } 57 | 58 | body, err := z.get(ctx, u) 59 | if err != nil { 60 | return nil, Page{}, err 61 | } 62 | 63 | if err := json.Unmarshal(body, &result); err != nil { 64 | return nil, Page{}, err 65 | } 66 | 67 | return result.GroupMemberships, result.Page, nil 68 | } 69 | -------------------------------------------------------------------------------- /zendesk/group_membership_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetGroupMembershipsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[GroupMembership] { 14 | return &Iterator[GroupMembership]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetGroupMembershipsOBP, 23 | cbpFunc: z.GetGroupMembershipsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetGroupMembershipsOBP(ctx context.Context, opts *OBPOptions) ([]GroupMembership, Page, error) { 28 | var data struct { 29 | GroupMemberships []GroupMembership `json:"group_memberships"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/group_memberships.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.GroupMemberships, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetGroupMembershipsCBP(ctx context.Context, opts *CBPOptions) ([]GroupMembership, CursorPaginationMeta, error) { 52 | var data struct { 53 | GroupMemberships []GroupMembership `json:"group_memberships"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/group_memberships.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.GroupMemberships, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/group_membership_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetGroupMemberships(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "group_memberships.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | groupMemberships, _, err := client.GetGroupMemberships(ctx, &GroupMembershipListOptions{GroupID: 123}) 14 | if err != nil { 15 | t.Fatalf("Failed to get group memberships: %s", err) 16 | } 17 | 18 | if len(groupMemberships) != 2 { 19 | t.Fatalf("expected length of group memberships is 2, but got %d", len(groupMemberships)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /zendesk/iterator_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "testing" 6 | 7 | "github.com/stretchr/testify/assert" 8 | ) 9 | 10 | // Test for NewPaginationOptions function 11 | func TestNewPaginationOptions(t *testing.T) { 12 | opts := NewPaginationOptions() 13 | 14 | assert.Equal(t, 100, opts.PageSize) 15 | assert.Equal(t, true, opts.IsCBP) 16 | } 17 | 18 | // Test for HasMore function 19 | func TestHasMore(t *testing.T) { 20 | iter := &Iterator[int]{ 21 | hasMore: true, 22 | } 23 | 24 | result := iter.HasMore() 25 | 26 | assert.Equal(t, true, result) 27 | } 28 | 29 | // Mock functions for GetNext testing 30 | func mockObpFunc(ctx context.Context, opts *OBPOptions) ([]int, Page, error) { 31 | nextPage := "2" 32 | return []int{1, 2, 3}, Page{NextPage: &nextPage, Count: 3}, nil 33 | } 34 | 35 | func mockCbpFunc(ctx context.Context, opts *CBPOptions) ([]int, CursorPaginationMeta, error) { 36 | return []int{1, 2, 3}, CursorPaginationMeta{HasMore: true, AfterCursor: "3"}, nil 37 | } 38 | 39 | // Test for GetNext function 40 | func TestGetNext(t *testing.T) { 41 | ctx := context.Background() 42 | 43 | iter := &Iterator[int]{ 44 | pageSize: 2, 45 | hasMore: true, 46 | isCBP: false, 47 | pageIndex: 1, 48 | ctx: ctx, 49 | obpFunc: mockObpFunc, 50 | cbpFunc: mockCbpFunc, 51 | } 52 | 53 | results, err := iter.GetNext() 54 | 55 | assert.NoError(t, err) 56 | assert.Equal(t, []int{1, 2, 3}, results) 57 | assert.Equal(t, true, iter.HasMore()) 58 | } 59 | -------------------------------------------------------------------------------- /zendesk/locale.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | // Locale is zendesk locale JSON payload format 10 | // https://developer.zendesk.com/rest_api/docs/support/locales 11 | type Locale struct { 12 | ID int64 `json:"id"` 13 | URL string `json:"url"` 14 | Locale string `json:"locale"` 15 | Name string `json:"name"` 16 | CreatedAt time.Time `json:"created_at"` 17 | UpdatedAt time.Time `json:"updated_at"` 18 | } 19 | 20 | // LocaleAPI an interface containing all of the local related zendesk methods 21 | type LocaleAPI interface { 22 | GetLocales(ctx context.Context) ([]Locale, error) 23 | } 24 | 25 | // GetLocales lists the translation locales available for the account. 26 | // https://developer.zendesk.com/rest_api/docs/support/locales#list-locales 27 | func (z *Client) GetLocales(ctx context.Context) ([]Locale, error) { 28 | var data struct { 29 | Locales []Locale `json:"locales"` 30 | } 31 | 32 | body, err := z.get(ctx, "/locales.json") 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | err = json.Unmarshal(body, &data) 38 | if err != nil { 39 | return nil, err 40 | } 41 | return data.Locales, nil 42 | } 43 | -------------------------------------------------------------------------------- /zendesk/locale_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetLocales(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "locales.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | locales, err := client.GetLocales(ctx) 14 | if err != nil { 15 | t.Fatalf("Failed to get locales: %s", err) 16 | } 17 | 18 | if len(locales) != 3 { 19 | t.Fatalf("expected length of groups is 3, but got %d", len(locales)) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /zendesk/locale_types_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestLocaleTypeText(t *testing.T) { 6 | if l := LocaleTypeText(LocaleENUS - 1); l != "" { 7 | t.Fatalf("expected empty string, but got %v", l) 8 | } 9 | if l := LocaleTypeText(LocaleENPH + 1); l != "" { 10 | t.Fatalf("expected empty string, but got %v", l) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /zendesk/macro_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetMacrosIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Macro] { 14 | return &Iterator[Macro]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetMacrosOBP, 23 | cbpFunc: z.GetMacrosCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetMacrosOBP(ctx context.Context, opts *OBPOptions) ([]Macro, Page, error) { 28 | var data struct { 29 | Macros []Macro `json:"macros"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/macros.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Macros, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetMacrosCBP(ctx context.Context, opts *CBPOptions) ([]Macro, CursorPaginationMeta, error) { 52 | var data struct { 53 | Macros []Macro `json:"macros"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/macros.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Macros, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/macro_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestGetMacros(t *testing.T) { 10 | mockAPI := newMockAPI(http.MethodGet, "macros.json") 11 | client := newTestClient(mockAPI) 12 | defer mockAPI.Close() 13 | 14 | macros, _, err := client.GetMacros(ctx, &MacroListOptions{ 15 | PageOptions: PageOptions{ 16 | Page: 1, 17 | PerPage: 10, 18 | }, 19 | SortBy: "id", 20 | SortOrder: "asc", 21 | }) 22 | if err != nil { 23 | t.Fatalf("Failed to get macros: %s", err) 24 | } 25 | 26 | expectedLength := 2 27 | if len(macros) != expectedLength { 28 | t.Fatalf("Returned macros does not have the expected length %d. Macros length is %d", expectedLength, len(macros)) 29 | } 30 | } 31 | 32 | func TestGetMacro(t *testing.T) { 33 | mockAPI := newMockAPI(http.MethodGet, "macro.json") 34 | client := newTestClient(mockAPI) 35 | defer mockAPI.Close() 36 | 37 | macro, err := client.GetMacro(ctx, 2) 38 | if err != nil { 39 | t.Fatalf("Failed to get macro: %s", err) 40 | } 41 | 42 | expectedID := int64(360111062754) 43 | if macro.ID != expectedID { 44 | t.Fatalf("Returned macro does not have the expected ID %d. Macro id is %d", expectedID, macro.ID) 45 | } 46 | 47 | } 48 | 49 | func TestCreateMacro(t *testing.T) { 50 | mockAPI := newMockAPIWithStatus(http.MethodPost, "macro.json", http.StatusCreated) 51 | client := newTestClient(mockAPI) 52 | defer mockAPI.Close() 53 | 54 | macro, err := client.CreateMacro(ctx, Macro{ 55 | Title: "nyanyanyanya", 56 | // Comment: MacroComment{ 57 | // Body: "(●ↀ ω ↀ )", 58 | // }, 59 | }) 60 | if err != nil { 61 | t.Fatalf("Failed to create macro: %s", err) 62 | } 63 | 64 | expectedID := int64(4) 65 | if macro.ID != expectedID { 66 | t.Fatalf("Returned macro does not have the expected ID %d. Macro id is %d", expectedID, macro.ID) 67 | } 68 | } 69 | 70 | func TestUpdateMacro(t *testing.T) { 71 | mockAPI := newMockAPIWithStatus(http.MethodPut, "macro.json", http.StatusOK) 72 | client := newTestClient(mockAPI) 73 | defer mockAPI.Close() 74 | 75 | macro, err := client.UpdateMacro(ctx, 2, Macro{}) 76 | if err != nil { 77 | t.Fatalf("Failed to update macro: %s", err) 78 | } 79 | 80 | expectedID := int64(2) 81 | if macro.ID != expectedID { 82 | t.Fatalf("Returned macro does not have the expected ID %d. Macro id is %d", expectedID, macro.ID) 83 | } 84 | } 85 | 86 | func TestUpdateMacroFailure(t *testing.T) { 87 | mockAPI := newMockAPIWithStatus(http.MethodPut, "macro.json", http.StatusInternalServerError) 88 | client := newTestClient(mockAPI) 89 | defer mockAPI.Close() 90 | 91 | _, err := client.UpdateMacro(ctx, 2, Macro{}) 92 | if err == nil { 93 | t.Fatal("Client did not return error when api failed") 94 | } 95 | } 96 | 97 | func TestDeleteMacro(t *testing.T) { 98 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 99 | w.WriteHeader(http.StatusNoContent) 100 | w.Write(nil) 101 | })) 102 | 103 | c := newTestClient(mockAPI) 104 | err := c.DeleteMacro(ctx, 437) 105 | if err != nil { 106 | t.Fatalf("Failed to delete macro field: %s", err) 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /zendesk/main_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "context" 4 | 5 | var ctx = context.Background() 6 | -------------------------------------------------------------------------------- /zendesk/mock/api.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import ( 4 | "github.com/nukosuke/go-zendesk/zendesk" 5 | ) 6 | 7 | var _ zendesk.API = (*Client)(nil) 8 | -------------------------------------------------------------------------------- /zendesk/organization_field.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | // OrganizationField represents the Organization Custom field structure 10 | type OrganizationField struct { 11 | ID int64 `json:"id,omitempty"` 12 | URL string `json:"url,omitempty"` 13 | Title string `json:"title"` 14 | Type string `json:"type"` 15 | RelationshipTargetType string `json:"relationship_target_type"` 16 | RelationshipFilter RelationshipFilter `json:"relationship_filter"` 17 | Active bool `json:"active,omitempty"` 18 | CustomFieldOptions []CustomFieldOption `json:"custom_field_options,omitempty"` 19 | Description string `json:"description,omitempty"` 20 | Key string `json:"key"` 21 | Position int64 `json:"position,omitempty"` 22 | RawDescription string `json:"raw_description,omitempty"` 23 | RawTitle string `json:"raw_title,omitempty"` 24 | RegexpForValidation string `json:"regexp_for_validation,omitempty"` 25 | System bool `json:"system,omitempty"` 26 | Tag string `json:"tag,omitempty"` 27 | CreatedAt *time.Time `json:"created_at,omitempty"` 28 | UpdatedAt *time.Time `json:"updated_at,omitempty"` 29 | } 30 | 31 | // OrganizationFieldAPI an interface containing all the organization field related zendesk methods 32 | type OrganizationFieldAPI interface { 33 | GetOrganizationFields(ctx context.Context) ([]OrganizationField, Page, error) 34 | CreateOrganizationField(ctx context.Context, organizationField OrganizationField) (OrganizationField, error) 35 | GetOrganizationFieldsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[OrganizationField] 36 | GetOrganizationFieldsOBP(ctx context.Context, opts *OBPOptions) ([]OrganizationField, Page, error) 37 | GetOrganizationFieldsCBP(ctx context.Context, opts *CBPOptions) ([]OrganizationField, CursorPaginationMeta, error) 38 | } 39 | 40 | // GetOrganizationFields fetches organization field list 41 | // ref: https://developer.zendesk.com/api-reference/ticketing/organizations/organization_fields/#list-organization-fields 42 | func (z *Client) GetOrganizationFields(ctx context.Context) ([]OrganizationField, Page, error) { 43 | var data struct { 44 | OrganizationFields []OrganizationField `json:"organization_fields"` 45 | Page 46 | } 47 | 48 | body, err := z.get(ctx, "/organization_fields.json") 49 | if err != nil { 50 | return []OrganizationField{}, Page{}, err 51 | } 52 | 53 | err = json.Unmarshal(body, &data) 54 | if err != nil { 55 | return []OrganizationField{}, Page{}, err 56 | } 57 | return data.OrganizationFields, data.Page, nil 58 | } 59 | 60 | // CreateOrganizationField creates new organization field 61 | // ref: https://developer.zendesk.com/api-reference/ticketing/organizations/organization_fields/#create-organization-field 62 | func (z *Client) CreateOrganizationField(ctx context.Context, organizationField OrganizationField) (OrganizationField, error) { 63 | var data, result struct { 64 | OrganizationField OrganizationField `json:"organization_field"` 65 | } 66 | data.OrganizationField = organizationField 67 | 68 | body, err := z.post(ctx, "/organization_fields.json", data) 69 | if err != nil { 70 | return OrganizationField{}, err 71 | } 72 | 73 | err = json.Unmarshal(body, &result) 74 | if err != nil { 75 | return OrganizationField{}, err 76 | } 77 | return result.OrganizationField, nil 78 | } 79 | -------------------------------------------------------------------------------- /zendesk/organization_field_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetOrganizationFieldsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[OrganizationField] { 14 | return &Iterator[OrganizationField]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetOrganizationFieldsOBP, 23 | cbpFunc: z.GetOrganizationFieldsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetOrganizationFieldsOBP(ctx context.Context, opts *OBPOptions) ([]OrganizationField, Page, error) { 28 | var data struct { 29 | OrganizationFields []OrganizationField `json:"organization_fields"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/organization_fields.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.OrganizationFields, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetOrganizationFieldsCBP(ctx context.Context, opts *CBPOptions) ([]OrganizationField, CursorPaginationMeta, error) { 52 | var data struct { 53 | OrganizationFields []OrganizationField `json:"organization_fields"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/organization_fields.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.OrganizationFields, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/organization_field_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetOrganizationFields(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "organization_fields.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | ticketFields, _, err := client.GetOrganizationFields(ctx) 14 | if err != nil { 15 | t.Fatalf("Failed to get organization fields: %s", err) 16 | } 17 | 18 | if len(ticketFields) != 2 { 19 | t.Fatalf("expected length of organization fields is , but got %d", len(ticketFields)) 20 | } 21 | } 22 | 23 | func TestOrganizationField(t *testing.T) { 24 | mockAPI := newMockAPIWithStatus(http.MethodPost, "organization_fields.json", http.StatusCreated) 25 | client := newTestClient(mockAPI) 26 | defer mockAPI.Close() 27 | 28 | _, err := client.CreateOrganizationField(ctx, OrganizationField{}) 29 | if err != nil { 30 | t.Fatalf("Failed to send request to create organization field: %s", err) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /zendesk/organization_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetOrganizationsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Organization] { 14 | return &Iterator[Organization]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetOrganizationsOBP, 23 | cbpFunc: z.GetOrganizationsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetOrganizationsOBP(ctx context.Context, opts *OBPOptions) ([]Organization, Page, error) { 28 | var data struct { 29 | Organizations []Organization `json:"organizations"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/organizations.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Organizations, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetOrganizationsCBP(ctx context.Context, opts *CBPOptions) ([]Organization, CursorPaginationMeta, error) { 52 | var data struct { 53 | Organizations []Organization `json:"organizations"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/organizations.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Organizations, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/organization_membership_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetOrganizationMembershipsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[OrganizationMembership] { 14 | return &Iterator[OrganizationMembership]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetOrganizationMembershipsOBP, 23 | cbpFunc: z.GetOrganizationMembershipsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetOrganizationMembershipsOBP(ctx context.Context, opts *OBPOptions) ([]OrganizationMembership, Page, error) { 28 | var data struct { 29 | OrganizationMemberships []OrganizationMembership `json:"organization_memberships"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/organization_memberships.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.OrganizationMemberships, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetOrganizationMembershipsCBP(ctx context.Context, opts *CBPOptions) ([]OrganizationMembership, CursorPaginationMeta, error) { 52 | var data struct { 53 | OrganizationMemberships []OrganizationMembership `json:"organization_memberships"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/organization_memberships.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.OrganizationMemberships, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/organization_membership_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetOrganizationMemberships(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "organization_memberships.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | orgMemberships, _, err := client.GetOrganizationMemberships(ctx, &OrganizationMembershipListOptions{}) 14 | if err != nil { 15 | t.Fatalf("Failed to get organization memberships: %s", err) 16 | } 17 | 18 | expectedOrgMemberships := 2 19 | 20 | if len(orgMemberships) != expectedOrgMemberships { 21 | t.Fatalf("expected length of organization memberships is %d, but got %d", expectedOrgMemberships, len(orgMemberships)) 22 | } 23 | } 24 | 25 | func TestCreateOrganizationMembership(t *testing.T) { 26 | mockAPI := newMockAPIWithStatus(http.MethodPost, "organization_membership.json", http.StatusCreated) 27 | client := newTestClient(mockAPI) 28 | defer mockAPI.Close() 29 | 30 | _, err := client.CreateOrganizationMembership(ctx, OrganizationMembershipOptions{}) 31 | if err != nil { 32 | t.Fatalf("Failed to send request to create organization membership: %s", err) 33 | } 34 | } 35 | 36 | func TestSetDefaultOrganization(t *testing.T) { 37 | mockAPI := newMockAPIWithStatus(http.MethodPut, "organization_membership.json", http.StatusOK) 38 | client := newTestClient(mockAPI) 39 | defer mockAPI.Close() 40 | 41 | orgMembership, err := client.SetDefaultOrganization(ctx, OrganizationMembershipOptions{}) 42 | if err != nil { 43 | t.Fatalf("Failed to set the default organization for user: %s", err) 44 | } 45 | 46 | expectedDefault := true 47 | if orgMembership.Default != expectedDefault { 48 | t.Fatalf("Returned org membership does not have the expected default status %v. It is %v", expectedDefault, orgMembership.Default) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /zendesk/organization_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestCreateOrganization(t *testing.T) { 10 | mockAPI := newMockAPIWithStatus(http.MethodPost, "organization.json", http.StatusCreated) 11 | client := newTestClient(mockAPI) 12 | defer mockAPI.Close() 13 | 14 | _, err := client.CreateOrganization(ctx, Organization{}) 15 | if err != nil { 16 | t.Fatalf("Failed to send request to create organization: %s", err) 17 | } 18 | } 19 | 20 | func TestGetOrganization(t *testing.T) { 21 | mockAPI := newMockAPI(http.MethodGet, "organization.json") 22 | client := newTestClient(mockAPI) 23 | defer mockAPI.Close() 24 | 25 | org, err := client.GetOrganization(ctx, 123) 26 | if err != nil { 27 | t.Fatalf("Failed to get organization: %s", err) 28 | } 29 | 30 | expectedID := int64(361898904439) 31 | if org.ID != expectedID { 32 | t.Fatalf("Returned organization does not have the expected ID %d. Organization ID is %d", expectedID, org.ID) 33 | } 34 | } 35 | 36 | func TestGetOrganizations(t *testing.T) { 37 | mockAPI := newMockAPI(http.MethodGet, "organizations.json") 38 | client := newTestClient(mockAPI) 39 | defer mockAPI.Close() 40 | 41 | orgs, _, err := client.GetOrganizations(ctx, &OrganizationListOptions{}) 42 | if err != nil { 43 | t.Fatalf("Failed to get organizations: %s", err) 44 | } 45 | 46 | if len(orgs) != 2 { 47 | t.Fatalf("expected length of organizations is , but got %d", len(orgs)) 48 | } 49 | } 50 | 51 | func TestUpdateOrganization(t *testing.T) { 52 | mockAPI := newMockAPIWithStatus(http.MethodPut, "organization.json", http.StatusOK) 53 | client := newTestClient(mockAPI) 54 | defer mockAPI.Close() 55 | 56 | updatedOrg, err := client.UpdateOrganization(ctx, int64(1234), Organization{}) 57 | if err != nil { 58 | t.Fatalf("Failed to send request to create organization: %s", err) 59 | } 60 | 61 | expectedID := int64(361898904439) 62 | if updatedOrg.ID != expectedID { 63 | t.Fatalf("Updated organization %v did not have expected id %d", updatedOrg, expectedID) 64 | } 65 | } 66 | 67 | func TestDeleteOrganization(t *testing.T) { 68 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 69 | w.WriteHeader(http.StatusNoContent) 70 | w.Write(nil) 71 | })) 72 | 73 | c := newTestClient(mockAPI) 74 | err := c.DeleteOrganization(ctx, 1234) 75 | if err != nil { 76 | t.Fatalf("Failed to delete organization: %s", err) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /zendesk/organization_tickets_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import ( 12 | "context" 13 | "fmt" 14 | ) 15 | 16 | func (z *Client) GetOrganizationTicketsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Ticket] { 17 | return &Iterator[Ticket]{ 18 | CommonOptions: opts.CommonOptions, 19 | pageSize: opts.PageSize, 20 | hasMore: true, 21 | isCBP: opts.IsCBP, 22 | pageAfter: "", 23 | pageIndex: 1, 24 | ctx: ctx, 25 | obpFunc: z.GetOrganizationTicketsOBP, 26 | cbpFunc: z.GetOrganizationTicketsCBP, 27 | } 28 | } 29 | 30 | func (z *Client) GetOrganizationTicketsOBP(ctx context.Context, opts *OBPOptions) ([]Ticket, Page, error) { 31 | var data struct { 32 | Tickets []Ticket `json:"tickets"` 33 | Page 34 | } 35 | 36 | tmp := opts 37 | if tmp == nil { 38 | tmp = &OBPOptions{} 39 | } 40 | 41 | path := fmt.Sprintf("/organizations/%d/tickets.json", tmp.Id) 42 | u, err := addOptions(path, tmp) 43 | 44 | if err != nil { 45 | return nil, Page{}, err 46 | } 47 | 48 | err = getData(z, ctx, u, &data) 49 | if err != nil { 50 | return nil, Page{}, err 51 | } 52 | return data.Tickets, data.Page, nil 53 | } 54 | 55 | func (z *Client) GetOrganizationTicketsCBP(ctx context.Context, opts *CBPOptions) ([]Ticket, CursorPaginationMeta, error) { 56 | var data struct { 57 | Tickets []Ticket `json:"tickets"` 58 | Meta CursorPaginationMeta `json:"meta"` 59 | } 60 | 61 | tmp := opts 62 | if tmp == nil { 63 | tmp = &CBPOptions{} 64 | } 65 | 66 | path := fmt.Sprintf("/organizations/%d/tickets.json", tmp.Id) 67 | u, err := addOptions(path, tmp) 68 | 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | 73 | err = getData(z, ctx, u, &data) 74 | if err != nil { 75 | return nil, data.Meta, err 76 | } 77 | return data.Tickets, data.Meta, nil 78 | } 79 | 80 | -------------------------------------------------------------------------------- /zendesk/organization_users_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import ( 12 | "context" 13 | "fmt" 14 | ) 15 | 16 | func (z *Client) GetOrganizationUsersIterator(ctx context.Context, opts *PaginationOptions) *Iterator[User] { 17 | return &Iterator[User]{ 18 | CommonOptions: opts.CommonOptions, 19 | pageSize: opts.PageSize, 20 | hasMore: true, 21 | isCBP: opts.IsCBP, 22 | pageAfter: "", 23 | pageIndex: 1, 24 | ctx: ctx, 25 | obpFunc: z.GetOrganizationUsersOBP, 26 | cbpFunc: z.GetOrganizationUsersCBP, 27 | } 28 | } 29 | 30 | func (z *Client) GetOrganizationUsersOBP(ctx context.Context, opts *OBPOptions) ([]User, Page, error) { 31 | var data struct { 32 | Users []User `json:"users"` 33 | Page 34 | } 35 | 36 | tmp := opts 37 | if tmp == nil { 38 | tmp = &OBPOptions{} 39 | } 40 | 41 | path := fmt.Sprintf("/organizations/%d/users.json", tmp.Id) 42 | u, err := addOptions(path, tmp) 43 | 44 | if err != nil { 45 | return nil, Page{}, err 46 | } 47 | 48 | err = getData(z, ctx, u, &data) 49 | if err != nil { 50 | return nil, Page{}, err 51 | } 52 | return data.Users, data.Page, nil 53 | } 54 | 55 | func (z *Client) GetOrganizationUsersCBP(ctx context.Context, opts *CBPOptions) ([]User, CursorPaginationMeta, error) { 56 | var data struct { 57 | Users []User `json:"users"` 58 | Meta CursorPaginationMeta `json:"meta"` 59 | } 60 | 61 | tmp := opts 62 | if tmp == nil { 63 | tmp = &CBPOptions{} 64 | } 65 | 66 | path := fmt.Sprintf("/organizations/%d/users.json", tmp.Id) 67 | u, err := addOptions(path, tmp) 68 | 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | 73 | err = getData(z, ctx, u, &data) 74 | if err != nil { 75 | return nil, data.Meta, err 76 | } 77 | return data.Users, data.Meta, nil 78 | } 79 | 80 | -------------------------------------------------------------------------------- /zendesk/page.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // Page is base struct for resource pagination 4 | type Page struct { 5 | PreviousPage *string `json:"previous_page"` 6 | NextPage *string `json:"next_page"` 7 | Count int64 `json:"count"` 8 | } 9 | 10 | // PageOptions is options for list method of paginatable resources. 11 | // It's used to create query string. 12 | // 13 | // ref: https://developer.zendesk.com/rest_api/docs/support/introduction#pagination 14 | type PageOptions struct { 15 | PerPage int `url:"per_page,omitempty"` 16 | Page int `url:"page,omitempty"` 17 | } 18 | 19 | // HasPrev checks if the Page has previous page 20 | func (p Page) HasPrev() bool { 21 | return (p.PreviousPage != nil) 22 | } 23 | 24 | // HasNext checks if the Page has next page 25 | func (p Page) HasNext() bool { 26 | return (p.NextPage != nil) 27 | } 28 | -------------------------------------------------------------------------------- /zendesk/page_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestHasNext(t *testing.T) { 6 | pageURL := "https://example.com/pages/2" 7 | 8 | if (Page{NextPage: &pageURL}).HasNext() != true { 9 | t.Fatalf("expext true, but got false") 10 | } 11 | if (Page{NextPage: nil}).HasNext() != false { 12 | t.Fatalf("expect false, but got true") 13 | } 14 | } 15 | 16 | func TestHasPrev(t *testing.T) { 17 | pageURL := "https://example.com/pages/1" 18 | 19 | if (Page{PreviousPage: &pageURL}).HasPrev() != true { 20 | t.Fatalf("expect true, but got false") 21 | } 22 | if (Page{PreviousPage: nil}).HasPrev() != false { 23 | t.Fatalf("expect false, but got true") 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /zendesk/search_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetSearchIterator(ctx context.Context, opts *PaginationOptions) *Iterator[SearchResults] { 14 | return &Iterator[SearchResults]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetSearchOBP, 23 | cbpFunc: z.GetSearchCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetSearchOBP(ctx context.Context, opts *OBPOptions) ([]SearchResults, Page, error) { 28 | var data struct { 29 | SearchResultss []SearchResults `json:"results"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/search.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.SearchResultss, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetSearchCBP(ctx context.Context, opts *CBPOptions) ([]SearchResults, CursorPaginationMeta, error) { 52 | var data struct { 53 | SearchResultss []SearchResults `json:"results"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/search.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.SearchResultss, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/sla_policy_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetSLAPoliciesIterator(ctx context.Context, opts *PaginationOptions) *Iterator[SLAPolicy] { 14 | return &Iterator[SLAPolicy]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetSLAPoliciesOBP, 23 | cbpFunc: z.GetSLAPoliciesCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetSLAPoliciesOBP(ctx context.Context, opts *OBPOptions) ([]SLAPolicy, Page, error) { 28 | var data struct { 29 | SLAPolicys []SLAPolicy `json:"sla_policies"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/slas/policies.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.SLAPolicys, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetSLAPoliciesCBP(ctx context.Context, opts *CBPOptions) ([]SLAPolicy, CursorPaginationMeta, error) { 52 | var data struct { 53 | SLAPolicys []SLAPolicy `json:"sla_policies"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/slas/policies.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.SLAPolicys, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/target_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestGetTargets(t *testing.T) { 10 | mockAPI := newMockAPI(http.MethodGet, "targets.json") 11 | client := newTestClient(mockAPI) 12 | defer mockAPI.Close() 13 | 14 | targets, _, err := client.GetTargets(ctx) 15 | if err != nil { 16 | t.Fatalf("Failed to get targets: %s", err) 17 | } 18 | 19 | if len(targets) != 2 { 20 | t.Fatalf("expected length of targets is , but got %d", len(targets)) 21 | } 22 | } 23 | 24 | func TestGetTarget(t *testing.T) { 25 | mockAPI := newMockAPI(http.MethodGet, "target.json") 26 | client := newTestClient(mockAPI) 27 | defer mockAPI.Close() 28 | 29 | target, err := client.GetTarget(ctx, 123) 30 | if err != nil { 31 | t.Fatalf("Failed to get targets: %s", err) 32 | } 33 | 34 | expectedID := int64(360000217439) 35 | if target.ID != expectedID { 36 | t.Fatalf("Returned target does not have the expected ID %d. Ticket id is %d", expectedID, target.ID) 37 | } 38 | } 39 | 40 | func TestCreateTarget(t *testing.T) { 41 | mockAPI := newMockAPIWithStatus(http.MethodPost, "target.json", http.StatusCreated) 42 | client := newTestClient(mockAPI) 43 | defer mockAPI.Close() 44 | 45 | _, err := client.CreateTarget(ctx, Target{}) 46 | if err != nil { 47 | t.Fatalf("Failed to send request to create target: %s", err) 48 | } 49 | } 50 | 51 | func TestUpdateTarget(t *testing.T) { 52 | mockAPI := newMockAPIWithStatus(http.MethodPut, "target.json", http.StatusOK) 53 | client := newTestClient(mockAPI) 54 | defer mockAPI.Close() 55 | 56 | updatedField, err := client.UpdateTarget(ctx, int64(1234), Target{}) 57 | if err != nil { 58 | t.Fatalf("Failed to send request to create target: %s", err) 59 | } 60 | 61 | expectedID := int64(360000217439) 62 | if updatedField.ID != expectedID { 63 | t.Fatalf("Updated field %v did not have expected id %d", updatedField, expectedID) 64 | } 65 | } 66 | 67 | func TestDeleteTarget(t *testing.T) { 68 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 69 | w.WriteHeader(http.StatusNoContent) 70 | w.Write(nil) 71 | })) 72 | 73 | c := newTestClient(mockAPI) 74 | err := c.DeleteTarget(ctx, 1234) 75 | if err != nil { 76 | t.Fatalf("Failed to delete target: %s", err) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /zendesk/ticket_audit_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import ( 12 | "context" 13 | "fmt" 14 | ) 15 | 16 | func (z *Client) GetTicketAuditsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[TicketAudit] { 17 | return &Iterator[TicketAudit]{ 18 | CommonOptions: opts.CommonOptions, 19 | pageSize: opts.PageSize, 20 | hasMore: true, 21 | isCBP: opts.IsCBP, 22 | pageAfter: "", 23 | pageIndex: 1, 24 | ctx: ctx, 25 | obpFunc: z.GetTicketAuditsOBP, 26 | cbpFunc: z.GetTicketAuditsCBP, 27 | } 28 | } 29 | 30 | func (z *Client) GetTicketAuditsOBP(ctx context.Context, opts *OBPOptions) ([]TicketAudit, Page, error) { 31 | var data struct { 32 | TicketAudits []TicketAudit `json:"audits"` 33 | Page 34 | } 35 | 36 | tmp := opts 37 | if tmp == nil { 38 | tmp = &OBPOptions{} 39 | } 40 | 41 | path := fmt.Sprintf("/tickets/%d/audits.json", tmp.Id) 42 | u, err := addOptions(path, tmp) 43 | 44 | if err != nil { 45 | return nil, Page{}, err 46 | } 47 | 48 | err = getData(z, ctx, u, &data) 49 | if err != nil { 50 | return nil, Page{}, err 51 | } 52 | return data.TicketAudits, data.Page, nil 53 | } 54 | 55 | func (z *Client) GetTicketAuditsCBP(ctx context.Context, opts *CBPOptions) ([]TicketAudit, CursorPaginationMeta, error) { 56 | var data struct { 57 | TicketAudits []TicketAudit `json:"audits"` 58 | Meta CursorPaginationMeta `json:"meta"` 59 | } 60 | 61 | tmp := opts 62 | if tmp == nil { 63 | tmp = &CBPOptions{} 64 | } 65 | 66 | path := fmt.Sprintf("/tickets/%d/audits.json", tmp.Id) 67 | u, err := addOptions(path, tmp) 68 | 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | 73 | err = getData(z, ctx, u, &data) 74 | if err != nil { 75 | return nil, data.Meta, err 76 | } 77 | return data.TicketAudits, data.Meta, nil 78 | } 79 | 80 | -------------------------------------------------------------------------------- /zendesk/ticket_audit_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetAllTicketAudits(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "ticket_audits.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | ticketAudits, _, err := client.GetAllTicketAudits(ctx, CursorOption{}) 14 | if err != nil { 15 | t.Fatalf("Failed to get ticket audits: %s", err) 16 | } 17 | 18 | if len(ticketAudits) != 1 { 19 | t.Fatalf("expected length of ticket audit is %d, but got %d", 1, len(ticketAudits)) 20 | } 21 | } 22 | 23 | func TestGetTicketAudits(t *testing.T) { 24 | mockAPI := newMockAPI(http.MethodGet, "ticket_audits.json") 25 | client := newTestClient(mockAPI) 26 | defer mockAPI.Close() 27 | 28 | ticketAudits, _, err := client.GetTicketAudits(ctx, 666, PageOptions{}) 29 | if err != nil { 30 | t.Fatalf("Failed to get ticket audits: %s", err) 31 | } 32 | 33 | if len(ticketAudits) != 1 { 34 | t.Fatalf("expected length of ticket audit is %d, but got %d", 1, len(ticketAudits)) 35 | } 36 | } 37 | 38 | func TestGetTicketAudit(t *testing.T) { 39 | mockAPI := newMockAPI(http.MethodGet, "ticket_audit.json") 40 | client := newTestClient(mockAPI) 41 | defer mockAPI.Close() 42 | 43 | ticketAudit, err := client.GetTicketAudit(ctx, 666, 2127301143) 44 | if err != nil { 45 | t.Fatalf("Failed to get ticket audit: %s", err) 46 | } 47 | 48 | expectedID := int64(2127301143) 49 | if ticketAudit.ID != expectedID { 50 | t.Fatalf("Returned ticket audit does not have the expected ID %d. Ticket audit id is %d", expectedID, ticketAudit.ID) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /zendesk/ticket_comment_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import ( 12 | "context" 13 | "fmt" 14 | ) 15 | 16 | func (z *Client) GetTicketCommentsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[TicketComment] { 17 | return &Iterator[TicketComment]{ 18 | CommonOptions: opts.CommonOptions, 19 | pageSize: opts.PageSize, 20 | hasMore: true, 21 | isCBP: opts.IsCBP, 22 | pageAfter: "", 23 | pageIndex: 1, 24 | ctx: ctx, 25 | obpFunc: z.GetTicketCommentsOBP, 26 | cbpFunc: z.GetTicketCommentsCBP, 27 | } 28 | } 29 | 30 | func (z *Client) GetTicketCommentsOBP(ctx context.Context, opts *OBPOptions) ([]TicketComment, Page, error) { 31 | var data struct { 32 | TicketComments []TicketComment `json:"comments"` 33 | Page 34 | } 35 | 36 | tmp := opts 37 | if tmp == nil { 38 | tmp = &OBPOptions{} 39 | } 40 | 41 | path := fmt.Sprintf("/tickets/%d/comments.json", tmp.Id) 42 | u, err := addOptions(path, tmp) 43 | 44 | if err != nil { 45 | return nil, Page{}, err 46 | } 47 | 48 | err = getData(z, ctx, u, &data) 49 | if err != nil { 50 | return nil, Page{}, err 51 | } 52 | return data.TicketComments, data.Page, nil 53 | } 54 | 55 | func (z *Client) GetTicketCommentsCBP(ctx context.Context, opts *CBPOptions) ([]TicketComment, CursorPaginationMeta, error) { 56 | var data struct { 57 | TicketComments []TicketComment `json:"comments"` 58 | Meta CursorPaginationMeta `json:"meta"` 59 | } 60 | 61 | tmp := opts 62 | if tmp == nil { 63 | tmp = &CBPOptions{} 64 | } 65 | 66 | path := fmt.Sprintf("/tickets/%d/comments.json", tmp.Id) 67 | u, err := addOptions(path, tmp) 68 | 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | 73 | err = getData(z, ctx, u, &data) 74 | if err != nil { 75 | return nil, data.Meta, err 76 | } 77 | return data.TicketComments, data.Meta, nil 78 | } 79 | 80 | -------------------------------------------------------------------------------- /zendesk/ticket_field_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetTicketFieldsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[TicketField] { 14 | return &Iterator[TicketField]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetTicketFieldsOBP, 23 | cbpFunc: z.GetTicketFieldsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetTicketFieldsOBP(ctx context.Context, opts *OBPOptions) ([]TicketField, Page, error) { 28 | var data struct { 29 | TicketFields []TicketField `json:"ticket_fields"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/ticket_fields.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.TicketFields, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetTicketFieldsCBP(ctx context.Context, opts *CBPOptions) ([]TicketField, CursorPaginationMeta, error) { 52 | var data struct { 53 | TicketFields []TicketField `json:"ticket_fields"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/ticket_fields.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.TicketFields, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/ticket_field_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestGetTicketFields(t *testing.T) { 10 | mockAPI := newMockAPI(http.MethodGet, "ticket_fields.json") 11 | client := newTestClient(mockAPI) 12 | defer mockAPI.Close() 13 | 14 | ticketFields, _, err := client.GetTicketFields(ctx) 15 | if err != nil { 16 | t.Fatalf("Failed to get ticket fields: %s", err) 17 | } 18 | 19 | if len(ticketFields) != 15 { 20 | t.Fatalf("expected length of ticket fields is , but got %d", len(ticketFields)) 21 | } 22 | } 23 | 24 | func TestGetTicketField(t *testing.T) { 25 | mockAPI := newMockAPI(http.MethodGet, "ticket_field.json") 26 | client := newTestClient(mockAPI) 27 | defer mockAPI.Close() 28 | 29 | ticketField, err := client.GetTicketField(ctx, 123) 30 | if err != nil { 31 | t.Fatalf("Failed to get ticket fields: %s", err) 32 | } 33 | 34 | expectedID := int64(360011737434) 35 | if ticketField.ID != expectedID { 36 | t.Fatalf("Returned ticket field does not have the expected ID %d. Ticket id is %d", expectedID, ticketField.ID) 37 | } 38 | } 39 | 40 | func TestCreateTicketField(t *testing.T) { 41 | mockAPI := newMockAPIWithStatus(http.MethodPost, "ticket_fields.json", http.StatusCreated) 42 | client := newTestClient(mockAPI) 43 | defer mockAPI.Close() 44 | 45 | _, err := client.CreateTicketField(ctx, TicketField{}) 46 | if err != nil { 47 | t.Fatalf("Failed to send request to create ticket field: %s", err) 48 | } 49 | } 50 | 51 | func TestUpdateTicketField(t *testing.T) { 52 | mockAPI := newMockAPIWithStatus(http.MethodPut, "ticket_field.json", http.StatusOK) 53 | client := newTestClient(mockAPI) 54 | defer mockAPI.Close() 55 | 56 | updatedField, err := client.UpdateTicketField(ctx, int64(1234), TicketField{}) 57 | if err != nil { 58 | t.Fatalf("Failed to send request to create ticket field: %s", err) 59 | } 60 | 61 | expectedID := int64(360011737434) 62 | if updatedField.ID != expectedID { 63 | t.Fatalf("Updated field %v did not have expected id %d", updatedField, expectedID) 64 | } 65 | } 66 | 67 | func TestDeleteTicketField(t *testing.T) { 68 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 69 | w.WriteHeader(http.StatusNoContent) 70 | w.Write(nil) 71 | })) 72 | 73 | c := newTestClient(mockAPI) 74 | err := c.DeleteTicketField(ctx, 1234) 75 | if err != nil { 76 | t.Fatalf("Failed to delete ticket field: %s", err) 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /zendesk/ticket_form_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetTicketFormsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[TicketForm] { 14 | return &Iterator[TicketForm]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetTicketFormsOBP, 23 | cbpFunc: z.GetTicketFormsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetTicketFormsOBP(ctx context.Context, opts *OBPOptions) ([]TicketForm, Page, error) { 28 | var data struct { 29 | TicketForms []TicketForm `json:"ticket_forms"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/ticket_forms.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.TicketForms, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetTicketFormsCBP(ctx context.Context, opts *CBPOptions) ([]TicketForm, CursorPaginationMeta, error) { 52 | var data struct { 53 | TicketForms []TicketForm `json:"ticket_forms"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/ticket_forms.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.TicketForms, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/ticket_form_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | "testing" 7 | ) 8 | 9 | func TestGetTicketForms(t *testing.T) { 10 | mockAPI := newMockAPI(http.MethodGet, "ticket_forms.json") 11 | client := newTestClient(mockAPI) 12 | defer mockAPI.Close() 13 | 14 | ticketForms, _, err := client.GetTicketForms(ctx, nil) 15 | if err != nil { 16 | t.Fatalf("Failed to get ticket forms: %s", err) 17 | } 18 | 19 | if len(ticketForms) != 1 { 20 | t.Fatalf("expected length of ticket forms is , but got %d", len(ticketForms)) 21 | } 22 | } 23 | 24 | func TestCreateTicketForm(t *testing.T) { 25 | mockAPI := newMockAPIWithStatus(http.MethodPost, "ticket_form.json", http.StatusCreated) 26 | client := newTestClient(mockAPI) 27 | defer mockAPI.Close() 28 | 29 | _, err := client.CreateTicketForm(ctx, TicketForm{}) 30 | if err != nil { 31 | t.Fatalf("Failed to send request to create ticket form: %s", err) 32 | } 33 | } 34 | 35 | func TestDeleteTicketForm(t *testing.T) { 36 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 37 | w.WriteHeader(http.StatusNoContent) 38 | w.Write(nil) 39 | })) 40 | 41 | c := newTestClient(mockAPI) 42 | err := c.DeleteTicketForm(ctx, 1234) 43 | if err != nil { 44 | t.Fatalf("Failed to delete ticket field: %s", err) 45 | } 46 | } 47 | 48 | func TestDeleteTicketFormFailure(t *testing.T) { 49 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 50 | w.WriteHeader(http.StatusInternalServerError) 51 | w.Write(nil) 52 | })) 53 | 54 | c := newTestClient(mockAPI) 55 | err := c.DeleteTicketForm(ctx, 1234) 56 | if err == nil { 57 | t.Fatal("Client did not return error when api failed") 58 | } 59 | } 60 | 61 | func TestGetTicketForm(t *testing.T) { 62 | mockAPI := newMockAPI(http.MethodGet, "ticket_form.json") 63 | client := newTestClient(mockAPI) 64 | defer mockAPI.Close() 65 | 66 | f, err := client.GetTicketForm(ctx, 123) 67 | if err != nil { 68 | t.Fatalf("Failed to get ticket fields: %s", err) 69 | } 70 | 71 | expectedID := int64(47) 72 | if f.ID != expectedID { 73 | t.Fatalf("Returned ticket form does not have the expected ID %d. Ticket id is %d", expectedID, f.ID) 74 | } 75 | } 76 | 77 | func TestGetTicketFormFailure(t *testing.T) { 78 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 79 | w.WriteHeader(http.StatusInternalServerError) 80 | w.Write(nil) 81 | })) 82 | 83 | c := newTestClient(mockAPI) 84 | _, err := c.GetTicketForm(ctx, 1234) 85 | if err == nil { 86 | t.Fatal("Client did not return error when api failed") 87 | } 88 | } 89 | 90 | func TestUpdateTicketForm(t *testing.T) { 91 | mockAPI := newMockAPIWithStatus(http.MethodPut, "ticket_form.json", http.StatusOK) 92 | client := newTestClient(mockAPI) 93 | defer mockAPI.Close() 94 | 95 | f, err := client.UpdateTicketForm(ctx, 123, TicketForm{}) 96 | if err != nil { 97 | t.Fatalf("Failed to get ticket fields: %s", err) 98 | } 99 | 100 | expectedID := int64(47) 101 | if f.ID != expectedID { 102 | t.Fatalf("Returned ticket form does not have the expected ID %d. Ticket id is %d", expectedID, f.ID) 103 | } 104 | } 105 | 106 | func TestUpdateTicketFormFailure(t *testing.T) { 107 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 108 | w.WriteHeader(http.StatusInternalServerError) 109 | w.Write(nil) 110 | })) 111 | 112 | c := newTestClient(mockAPI) 113 | _, err := c.UpdateTicketForm(ctx, 1234, TicketForm{}) 114 | if err == nil { 115 | t.Fatal("Client did not return error when api failed") 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /zendesk/ticket_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetTicketsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Ticket] { 14 | return &Iterator[Ticket]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetTicketsOBP, 23 | cbpFunc: z.GetTicketsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetTicketsOBP(ctx context.Context, opts *OBPOptions) ([]Ticket, Page, error) { 28 | var data struct { 29 | Tickets []Ticket `json:"tickets"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/tickets.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Tickets, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetTicketsCBP(ctx context.Context, opts *CBPOptions) ([]Ticket, CursorPaginationMeta, error) { 52 | var data struct { 53 | Tickets []Ticket `json:"tickets"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/tickets.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Tickets, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/tickets_from_view_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import ( 12 | "context" 13 | "fmt" 14 | ) 15 | 16 | func (z *Client) GetTicketsFromViewIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Ticket] { 17 | return &Iterator[Ticket]{ 18 | CommonOptions: opts.CommonOptions, 19 | pageSize: opts.PageSize, 20 | hasMore: true, 21 | isCBP: opts.IsCBP, 22 | pageAfter: "", 23 | pageIndex: 1, 24 | ctx: ctx, 25 | obpFunc: z.GetTicketsFromViewOBP, 26 | cbpFunc: z.GetTicketsFromViewCBP, 27 | } 28 | } 29 | 30 | func (z *Client) GetTicketsFromViewOBP(ctx context.Context, opts *OBPOptions) ([]Ticket, Page, error) { 31 | var data struct { 32 | Tickets []Ticket `json:"tickets"` 33 | Page 34 | } 35 | 36 | tmp := opts 37 | if tmp == nil { 38 | tmp = &OBPOptions{} 39 | } 40 | 41 | path := fmt.Sprintf("/views/%d/tickets.json", tmp.Id) 42 | u, err := addOptions(path, tmp) 43 | 44 | if err != nil { 45 | return nil, Page{}, err 46 | } 47 | 48 | err = getData(z, ctx, u, &data) 49 | if err != nil { 50 | return nil, Page{}, err 51 | } 52 | return data.Tickets, data.Page, nil 53 | } 54 | 55 | func (z *Client) GetTicketsFromViewCBP(ctx context.Context, opts *CBPOptions) ([]Ticket, CursorPaginationMeta, error) { 56 | var data struct { 57 | Tickets []Ticket `json:"tickets"` 58 | Meta CursorPaginationMeta `json:"meta"` 59 | } 60 | 61 | tmp := opts 62 | if tmp == nil { 63 | tmp = &CBPOptions{} 64 | } 65 | 66 | path := fmt.Sprintf("/views/%d/tickets.json", tmp.Id) 67 | u, err := addOptions(path, tmp) 68 | 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | 73 | err = getData(z, ctx, u, &data) 74 | if err != nil { 75 | return nil, data.Meta, err 76 | } 77 | return data.Tickets, data.Meta, nil 78 | } 79 | 80 | -------------------------------------------------------------------------------- /zendesk/topics.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "time" 4 | 5 | type Topic struct { 6 | ID int64 `json:"id"` 7 | URL string `json:"url"` 8 | HTMLURL string `json:"html_url"` 9 | Name string `json:"name"` 10 | Description string `json:"description"` 11 | Position int `json:"position"` 12 | FollowerCount int `json:"follower_count"` 13 | ManageableBy string `json:"manageable_by"` 14 | UserSegmentID int64 `json:"user_segment_id"` 15 | CreatedAt time.Time `json:"created_at"` 16 | UpdatedAt time.Time `json:"updated_at"` 17 | } 18 | -------------------------------------------------------------------------------- /zendesk/trigger_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetTriggersIterator(ctx context.Context, opts *PaginationOptions) *Iterator[Trigger] { 14 | return &Iterator[Trigger]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetTriggersOBP, 23 | cbpFunc: z.GetTriggersCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetTriggersOBP(ctx context.Context, opts *OBPOptions) ([]Trigger, Page, error) { 28 | var data struct { 29 | Triggers []Trigger `json:"triggers"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/triggers.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Triggers, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetTriggersCBP(ctx context.Context, opts *CBPOptions) ([]Trigger, CursorPaginationMeta, error) { 52 | var data struct { 53 | Triggers []Trigger `json:"triggers"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/triggers.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Triggers, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/user_field.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "time" 7 | ) 8 | 9 | // UserField is struct for user_field payload 10 | type UserField struct { 11 | ID int64 `json:"id,omitempty"` 12 | URL string `json:"url,omitempty"` 13 | Key string `json:"key,omitempty"` 14 | Type string `json:"type"` 15 | Title string `json:"title"` 16 | RawTitle string `json:"raw_title,omitempty"` 17 | Description string `json:"description,omitempty"` 18 | RawDescription string `json:"raw_description,omitempty"` 19 | Position int64 `json:"position,omitempty"` 20 | Active bool `json:"active,omitempty"` 21 | System bool `json:"system,omitempty"` 22 | RegexpForValidation string `json:"regexp_for_validation,omitempty"` 23 | Tag string `json:"tag,omitempty"` 24 | CustomFieldOptions []CustomFieldOption `json:"custom_field_options"` 25 | CreatedAt time.Time `json:"created_at,omitempty"` 26 | UpdatedAt time.Time `json:"updated_at,omitempty"` 27 | } 28 | 29 | type UserFieldListOptions struct { 30 | PageOptions 31 | } 32 | 33 | type UserFieldAPI interface { 34 | GetUserFields(ctx context.Context, opts *UserFieldListOptions) ([]UserField, Page, error) 35 | CreateUserField(ctx context.Context, userField UserField) (UserField, error) 36 | GetUserFieldsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[UserField] 37 | GetUserFieldsOBP(ctx context.Context, opts *OBPOptions) ([]UserField, Page, error) 38 | GetUserFieldsCBP(ctx context.Context, opts *CBPOptions) ([]UserField, CursorPaginationMeta, error) 39 | } 40 | 41 | // GetUserFields fetch trigger list 42 | // 43 | // https://developer.zendesk.com/rest_api/docs/support/user_fields#list-user-fields 44 | func (z *Client) GetUserFields(ctx context.Context, opts *UserFieldListOptions) ([]UserField, Page, error) { 45 | var data struct { 46 | UserFields []UserField `json:"user_fields"` 47 | Page 48 | } 49 | 50 | tmp := opts 51 | if tmp == nil { 52 | tmp = &UserFieldListOptions{} 53 | } 54 | 55 | u, err := addOptions("/user_fields.json", tmp) 56 | if err != nil { 57 | return nil, Page{}, err 58 | } 59 | 60 | body, err := z.get(ctx, u) 61 | if err != nil { 62 | return nil, Page{}, err 63 | } 64 | 65 | err = json.Unmarshal(body, &data) 66 | if err != nil { 67 | return nil, Page{}, err 68 | } 69 | return data.UserFields, data.Page, nil 70 | } 71 | 72 | // CreateUserField creates new user field 73 | // ref: https://developer.zendesk.com/api-reference/ticketing/users/user_fields/#create-user-field 74 | func (z *Client) CreateUserField(ctx context.Context, userField UserField) (UserField, error) { 75 | var data, result struct { 76 | UserField UserField `json:"user_field"` 77 | } 78 | data.UserField = userField 79 | 80 | body, err := z.post(ctx, "/user_fields.json", data) 81 | if err != nil { 82 | return UserField{}, err 83 | } 84 | 85 | err = json.Unmarshal(body, &result) 86 | if err != nil { 87 | return UserField{}, err 88 | } 89 | return result.UserField, nil 90 | } 91 | -------------------------------------------------------------------------------- /zendesk/user_field_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetUserFieldsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[UserField] { 14 | return &Iterator[UserField]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetUserFieldsOBP, 23 | cbpFunc: z.GetUserFieldsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetUserFieldsOBP(ctx context.Context, opts *OBPOptions) ([]UserField, Page, error) { 28 | var data struct { 29 | UserFields []UserField `json:"user_fields"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/user_fields.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.UserFields, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetUserFieldsCBP(ctx context.Context, opts *CBPOptions) ([]UserField, CursorPaginationMeta, error) { 52 | var data struct { 53 | UserFields []UserField `json:"user_fields"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/user_fields.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.UserFields, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/user_field_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "net/http/httptest" 7 | "path/filepath" 8 | "testing" 9 | ) 10 | 11 | func TestGetUserFields(t *testing.T) { 12 | mockAPI := newMockAPI(http.MethodGet, "user_fields.json") 13 | client := newTestClient(mockAPI) 14 | defer mockAPI.Close() 15 | 16 | fields, page, err := client.GetUserFields(ctx, nil) 17 | if err != nil { 18 | t.Fatalf("Received error calling API: %v", err) 19 | } 20 | 21 | if page.Count != 1 { 22 | t.Fatalf("Did not receive the correct count in the page field. Was %d expected 1", page.Count) 23 | } 24 | 25 | n := len(fields) 26 | if n != 1 { 27 | t.Fatalf("Expected 1 entry in fields list. Got %d", n) 28 | } 29 | 30 | id := fields[0].ID 31 | if id != 7 { 32 | t.Fatalf("Field did not have the expected id. Was %d", id) 33 | } 34 | } 35 | 36 | func TestUserFieldQueryParamsSet(t *testing.T) { 37 | opts := UserFieldListOptions{ 38 | PageOptions{ 39 | Page: 2, 40 | }, 41 | } 42 | expected := fmt.Sprintf("page=%d", opts.Page) 43 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 44 | queryString := r.URL.Query().Encode() 45 | if queryString != expected { 46 | t.Fatalf(`Did not get the expect query string: "%s". Was: "%s"`, expected, queryString) 47 | } 48 | w.Write(readFixture(filepath.Join(http.MethodGet, "user_fields.json"))) 49 | })) 50 | 51 | defer mockAPI.Close() 52 | client := newTestClient(mockAPI) 53 | _, _, err := client.GetUserFields(ctx, &opts) 54 | if err != nil { 55 | t.Fatalf("Received error calling API: %v", err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /zendesk/user_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetUsersIterator(ctx context.Context, opts *PaginationOptions) *Iterator[User] { 14 | return &Iterator[User]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetUsersOBP, 23 | cbpFunc: z.GetUsersCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetUsersOBP(ctx context.Context, opts *OBPOptions) ([]User, Page, error) { 28 | var data struct { 29 | Users []User `json:"users"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/users.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Users, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetUsersCBP(ctx context.Context, opts *CBPOptions) ([]User, CursorPaginationMeta, error) { 52 | var data struct { 53 | Users []User `json:"users"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/users.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Users, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/via_types.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | // https://developer.zendesk.com/rest_api/docs/support/triggers#via-types 4 | const ( 5 | // ViaWebForm : Web form 6 | ViaWebForm = 0 7 | // ViaMail : Email 8 | ViaMail = 4 9 | // ViaChat : Chat 10 | ViaChat = 29 11 | // ViaTwitter : Twitter 12 | ViaTwitter = 30 13 | // ViaTwitterDM : Twitter DM 14 | ViaTwitterDM = 26 15 | // TwitterFavorite : Twitter like 16 | ViaTwitterFavorite = 23 17 | // ViaVoicemail : Voicemail 18 | ViaVoicemail = 33 19 | // ViaPhoneCallInbound : Phone call (incoming) 20 | ViaPhoneCallInbound = 34 21 | // ViaPhoneCallOutbound : Phone call (outbound) 22 | ViaPhoneCallOutbound = 35 23 | // ViaAPIVoicemail : CTI voicemail 24 | ViaAPIVoicemail = 44 25 | // ViaAPIPhoneCallInbound : CTI phone call (inbound) 26 | ViaAPIPhoneCallInbound = 45 27 | // ViaAPIPhoneCallOutbound : CTI phone call (outbound) 28 | ViaAPIPhoneCallOutbound = 46 29 | // ViaSMS : SMS 30 | ViaSMS = 57 31 | // ViaGetSatisfaction : Get Satisfaction 32 | ViaGetSatisfaction = 16 33 | // ViaWebWidget : Web Widget 34 | ViaWebWidget = 48 35 | // ViaMobileSDK : Mobile SDK 36 | ViaMobileSDK = 49 37 | // ViaMobile : Mobile 38 | ViaMobile = 56 39 | // ViaHelpCenter : Help Center post 40 | ViaHelpCenter = 50 41 | // ViaWebService : Web service (API) 42 | ViaWebService = 5 43 | // ViaRule : Trigger, automation 44 | ViaRule = 8 45 | // ViaClosedTicket : Closed ticket 46 | ViaClosedTicket = 27 47 | // ViaTicketSharing : Ticket Sharing 48 | ViaTicketSharing = 31 49 | // ViaFacebookPost : Facebook post 50 | ViaFacebookPost = 38 51 | // ViaFacebookMessage : Facebook private message 52 | ViaFacebookMessage = 41 53 | // ViaSatisfactionPrediction : Satisfaction prediction 54 | ViaSatisfactionPrediction = 54 55 | // ViaAnyChannel : Channel framework 56 | ViaAnyChannel = 55 57 | ) 58 | 59 | var viaTypeText = map[int]string{ 60 | ViaWebForm: "web_form", 61 | ViaMail: "mail", 62 | ViaChat: "chat", 63 | ViaTwitter: "twitter", 64 | ViaTwitterDM: "twitter_dm", 65 | ViaTwitterFavorite: "twitter_favorite", 66 | ViaVoicemail: "voicemail", 67 | ViaPhoneCallInbound: "phone_call_inbound", 68 | ViaPhoneCallOutbound: "phone_call_outbound", 69 | ViaAPIVoicemail: "api_voicemail", 70 | ViaAPIPhoneCallInbound: "api_phone_call_inbound", 71 | ViaAPIPhoneCallOutbound: "api_phone_call_outbound", 72 | ViaSMS: "sms", 73 | ViaGetSatisfaction: "get_satisfaction", 74 | ViaWebWidget: "web_widget", 75 | ViaMobileSDK: "mobile_sdk", 76 | ViaMobile: "mobile", 77 | ViaHelpCenter: "helpcenter", 78 | ViaWebService: "web_service", 79 | ViaRule: "rule", 80 | ViaClosedTicket: "closed_ticket", 81 | ViaTicketSharing: "ticket_sharing", 82 | ViaFacebookPost: "facebook_post", 83 | ViaFacebookMessage: "facebook_message", 84 | ViaSatisfactionPrediction: "satisfaction_prediction", 85 | ViaAnyChannel: "any_channel", 86 | } 87 | 88 | // ViaTypeText takes via_id and returns via_type 89 | func ViaTypeText(viaID int) string { 90 | return viaTypeText[viaID] 91 | } 92 | -------------------------------------------------------------------------------- /zendesk/via_types_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import "testing" 4 | 5 | func TestViaTypeText(t *testing.T) { 6 | if viaType := ViaTypeText(ViaWebForm); viaType != "web_form" { 7 | t.Fatal(`expect "web_form", but got "` + viaType + `"`) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /zendesk/view_generated.go: -------------------------------------------------------------------------------- 1 | 2 | // Code generated by Script. DO NOT EDIT. 3 | // Source: script/codegen/main.go 4 | // 5 | // Generated by this command: 6 | // 7 | // go run script/codegen/main.go 8 | 9 | package zendesk 10 | 11 | import "context" 12 | 13 | func (z *Client) GetViewsIterator(ctx context.Context, opts *PaginationOptions) *Iterator[View] { 14 | return &Iterator[View]{ 15 | CommonOptions: opts.CommonOptions, 16 | pageSize: opts.PageSize, 17 | hasMore: true, 18 | isCBP: opts.IsCBP, 19 | pageAfter: "", 20 | pageIndex: 1, 21 | ctx: ctx, 22 | obpFunc: z.GetViewsOBP, 23 | cbpFunc: z.GetViewsCBP, 24 | } 25 | } 26 | 27 | func (z *Client) GetViewsOBP(ctx context.Context, opts *OBPOptions) ([]View, Page, error) { 28 | var data struct { 29 | Views []View `json:"views"` 30 | Page 31 | } 32 | 33 | tmp := opts 34 | if tmp == nil { 35 | tmp = &OBPOptions{} 36 | } 37 | 38 | u, err := addOptions("/views.json", tmp) 39 | 40 | if err != nil { 41 | return nil, Page{}, err 42 | } 43 | 44 | err = getData(z, ctx, u, &data) 45 | if err != nil { 46 | return nil, Page{}, err 47 | } 48 | return data.Views, data.Page, nil 49 | } 50 | 51 | func (z *Client) GetViewsCBP(ctx context.Context, opts *CBPOptions) ([]View, CursorPaginationMeta, error) { 52 | var data struct { 53 | Views []View `json:"views"` 54 | Meta CursorPaginationMeta `json:"meta"` 55 | } 56 | 57 | tmp := opts 58 | if tmp == nil { 59 | tmp = &CBPOptions{} 60 | } 61 | 62 | u, err := addOptions("/views.json", tmp) 63 | 64 | if err != nil { 65 | return nil, data.Meta, err 66 | } 67 | 68 | err = getData(z, ctx, u, &data) 69 | if err != nil { 70 | return nil, data.Meta, err 71 | } 72 | return data.Views, data.Meta, nil 73 | } 74 | 75 | -------------------------------------------------------------------------------- /zendesk/view_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | ) 7 | 8 | func TestGetView(t *testing.T) { 9 | mockAPI := newMockAPI(http.MethodGet, "view.json") 10 | client := newTestClient(mockAPI) 11 | defer mockAPI.Close() 12 | 13 | view, err := client.GetView(ctx, 123) 14 | if err != nil { 15 | t.Fatalf("Failed to get view: %s", err) 16 | } 17 | 18 | expectedID := int64(360002440594) 19 | if view.ID != expectedID { 20 | t.Fatalf("Returned view does not have the expected ID %d. View ID is %d", expectedID, view.ID) 21 | } 22 | } 23 | 24 | func TestGetViews(t *testing.T) { 25 | mockAPI := newMockAPI(http.MethodGet, "views.json") 26 | client := newTestClient(mockAPI) 27 | defer mockAPI.Close() 28 | 29 | views, _, err := client.GetViews(ctx) 30 | if err != nil { 31 | t.Fatalf("Failed to get views: %s", err) 32 | } 33 | 34 | if len(views) != 2 { 35 | t.Fatalf("expected length of views is 2, but got %d", len(views)) 36 | } 37 | } 38 | 39 | func TestGetCountTicketsInViewsTestGetViews(t *testing.T) { 40 | mockAPI := newMockAPI(http.MethodGet, "views_ticket_count.json") 41 | client := newTestClient(mockAPI) 42 | defer mockAPI.Close() 43 | ids := []string{"25", "78"} 44 | viewsCount, err := client.GetCountTicketsInViews(ctx, ids) 45 | if err != nil { 46 | t.Fatalf("Failed to get views tickets count: %s", err) 47 | } 48 | 49 | if len(viewsCount) != 2 { 50 | t.Fatalf("expected length of views ticket counts is 2, but got %d", len(viewsCount)) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /zendesk/webhook_test.go: -------------------------------------------------------------------------------- 1 | package zendesk 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | "net/http/httptest" 7 | "testing" 8 | ) 9 | 10 | func TestCreateWebhook(t *testing.T) { 11 | mockAPI := newMockAPI(http.MethodPost, "webhooks.json") 12 | client := newTestClient(mockAPI) 13 | defer mockAPI.Close() 14 | 15 | hook, err := client.CreateWebhook(context.Background(), &Webhook{ 16 | Authentication: &WebhookAuthentication{ 17 | AddPosition: "header", 18 | Data: map[string]string{ 19 | "password": "hello_123", 20 | "username": "john_smith", 21 | }, 22 | Type: "basic_auth", 23 | }, 24 | Endpoint: "https://example.com/status/200", 25 | HTTPMethod: http.MethodGet, 26 | Name: "Example Webhook", 27 | RequestFormat: "json", 28 | Status: "active", 29 | Subscriptions: []string{"conditional_ticket_events"}, 30 | }) 31 | if err != nil { 32 | t.Fatalf("Failed to create webhook: %v", err) 33 | } 34 | 35 | if len(hook.Subscriptions) != 1 || hook.Authentication.AddPosition != "header" { 36 | t.Fatalf("Invalid response of webhook: %v", hook) 37 | } 38 | } 39 | 40 | func TestGetWebhook(t *testing.T) { 41 | mockAPI := newMockAPI(http.MethodGet, "webhook.json") 42 | client := newTestClient(mockAPI) 43 | defer mockAPI.Close() 44 | 45 | hook, err := client.GetWebhook(ctx, "01EJFTSCC78X5V07NPY2MHR00M") 46 | if err != nil { 47 | t.Fatalf("Failed to get webhook: %s", err) 48 | } 49 | 50 | expectedID := "01EJFTSCC78X5V07NPY2MHR00M" 51 | if hook.ID != expectedID { 52 | t.Fatalf("Returned webhook does not have the expected ID %s. Webhook ID is %s", expectedID, hook.ID) 53 | } 54 | } 55 | 56 | func TestUpdateWebhook(t *testing.T) { 57 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 58 | w.WriteHeader(http.StatusNoContent) 59 | w.Write(nil) 60 | })) 61 | client := newTestClient(mockAPI) 62 | defer mockAPI.Close() 63 | 64 | err := client.UpdateWebhook(ctx, "01EJFTSCC78X5V07NPY2MHR00M", &Webhook{}) 65 | if err != nil { 66 | t.Fatalf("Failed to send request to create webhook: %s", err) 67 | } 68 | } 69 | 70 | func TestDeleteWebhook(t *testing.T) { 71 | mockAPI := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 72 | w.WriteHeader(http.StatusNoContent) 73 | w.Write(nil) 74 | })) 75 | client := newTestClient(mockAPI) 76 | defer mockAPI.Close() 77 | 78 | err := client.DeleteWebhook(ctx, "01EJFTSCC78X5V07NPY2MHR00M") 79 | if err != nil { 80 | t.Fatalf("Failed to delete webhook: %s", err) 81 | } 82 | } 83 | --------------------------------------------------------------------------------