Go

Типизированный клиент для Pachca API на Go. Синхронный, с контекстами (context.Context), автопагинацией и обработкой retry. Требуется Go 1.24+.

Быстрый старт

Установка

go get github.com/pachca/openapi/sdk/go/generated

Создание клиента

Получите API-токен в интерфейсе Пачки: Настройки → Автоматизации → API (подробнее — Авторизация).

import pachca "github.com/pachca/openapi/sdk/go/generated" client := pachca.NewPachcaClient("YOUR_TOKEN")

Первый запрос

import pachca "github.com/pachca/openapi/sdk/go/generated" // Получение профиляresponse, err := client.Profile.GetProfile(ctx)// → User{ID: int32, FirstName: string, LastName: string, Nickname: string, Email: string, PhoneNumber: string, Department: string, Title: string, Role: UserRole, Suspended: bool, InviteStatus: InviteStatus, ListTags: []string, CustomProperties: []CustomProperty{ID: int32, Name: string, DataType: CustomPropertyDataType, Value: string}, UserStatus: *UserStatus{Emoji: string, Title: string, ExpiresAt: *string, IsAway: bool, AwayMessage: *UserStatusAwayMessage{Text: string}}, Bot: bool, Sso: bool, CreatedAt: string, LastActivityAt: string, TimeZone: string, ImageURL: *string}

Инициализация

import pachca "github.com/pachca/openapi/sdk/go/generated" // Стандартное подключениеclient := pachca.NewPachcaClient("YOUR_TOKEN") // С кастомным базовым URLclient := pachca.NewPachcaClient("YOUR_TOKEN", "https://custom-api.example.com/api/shared/v1")
ПараметрТипПо умолчаниюОписание
tokenstringBearer-токен для авторизации
baseURL...stringhttps://api.pachca.com/api/shared/v1Базовый URL API (необязательный)

Все методы принимают context.Context первым аргументом — используйте его для таймаутов и отмены:

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel() user, err := client.Profile.GetProfile(ctx)

Все методы

МетодМетод API
client.Common.RequestExport()POSTЭкспорт сообщений
client.Common.UploadFile()POSTЗагрузка файла
client.Common.GetUploadParams()POSTПолучение подписи, ключа и других параметров
client.Common.DownloadExport()GETСкачать архив экспорта
client.Common.ListProperties()GETСписок дополнительных полей
client.Profile.GetTokenInfo()GETИнформация о токене
client.Profile.GetProfile()GETИнформация о профиле
client.Profile.GetStatus()GETТекущий статус
client.Profile.UpdateStatus()PUTНовый статус
client.Profile.DeleteStatus()DELETEУдаление статуса
client.Users.CreateUser()POSTСоздать сотрудника
client.Users.ListUsers()GETСписок сотрудников
client.Users.GetUser()GETИнформация о сотруднике
client.Users.GetUserStatus()GETСтатус сотрудника
client.Users.UpdateUser()PUTРедактирование сотрудника
client.Users.UpdateUserStatus()PUTНовый статус сотрудника
client.Users.DeleteUser()DELETEУдаление сотрудника
client.Users.DeleteUserStatus()DELETEУдаление статуса сотрудника
client.GroupTags.CreateTag()POSTНовый тег
client.GroupTags.ListTags()GETСписок тегов сотрудников
client.GroupTags.GetTag()GETИнформация о теге
client.GroupTags.GetTagUsers()GETСписок сотрудников тега
client.GroupTags.UpdateTag()PUTРедактирование тега
client.GroupTags.DeleteTag()DELETEУдаление тега
client.Chats.CreateChat()POSTНовый чат
client.Chats.ListChats()GETСписок чатов
client.Chats.GetChat()GETИнформация о чате
client.Chats.UpdateChat()PUTОбновление чата
client.Chats.ArchiveChat()PUTАрхивация чата
client.Chats.UnarchiveChat()PUTРазархивация чата
client.Members.AddTags()POSTДобавление тегов
client.Members.AddMembers()POSTДобавление пользователей
client.Members.ListMembers()GETСписок участников чата
client.Members.UpdateMemberRole()PUTРедактирование роли
client.Members.RemoveTag()DELETEИсключение тега
client.Members.LeaveChat()DELETEВыход из беседы или канала
client.Members.RemoveMember()DELETEИсключение пользователя
client.Threads.CreateThread()POSTНовый тред
client.Threads.GetThread()GETИнформация о треде
client.Messages.CreateMessage()POSTНовое сообщение
client.Messages.PinMessage()POSTЗакрепление сообщения
client.Messages.ListChatMessages()GETСписок сообщений чата
client.Messages.GetMessage()GETИнформация о сообщении
client.Messages.UpdateMessage()PUTРедактирование сообщения
client.Messages.DeleteMessage()DELETEУдаление сообщения
client.Messages.UnpinMessage()DELETEОткрепление сообщения
client.ReadMembers.ListReadMembers()GETСписок прочитавших сообщение
client.Reactions.AddReaction()POSTДобавление реакции
client.Reactions.ListReactions()GETСписок реакций
client.Reactions.RemoveReaction()DELETEУдаление реакции
client.LinkPreviews.CreateLinkPreviews()POSTUnfurl (разворачивание ссылок)
client.Search.SearchChats()GETПоиск чатов
client.Search.SearchMessages()GETПоиск сообщений
client.Search.SearchUsers()GETПоиск сотрудников
client.Tasks.CreateTask()POSTНовое напоминание
client.Tasks.ListTasks()GETСписок напоминаний
client.Tasks.GetTask()GETИнформация о напоминании
client.Tasks.UpdateTask()PUTРедактирование напоминания
client.Tasks.DeleteTask()DELETEУдаление напоминания
client.Views.OpenView()POSTОткрытие представления
client.Bots.GetWebhookEvents()GETИстория событий
client.Bots.UpdateBot()PUTРедактирование бота
client.Bots.DeleteWebhookEvent()DELETEУдаление события
client.Security.GetAuditEvents()GETЖурнал аудита событий

Запросы

Все методы — синхронные и возвращают (*T, error).

GET с параметрами:

import pachca "github.com/pachca/openapi/sdk/go/generated" // Список чатовparams := &ListChatsParams{	SortID: Ptr(SortOrderDesc),	Availability: Ptr(ChatAvailabilityIsMember),	LastMessageAtAfter: Ptr("2025-01-01T00:00:00.000Z"),	LastMessageAtBefore: Ptr("2025-02-01T00:00:00.000Z"),	Personal: Ptr(false),	Limit: Ptr(int32(1)),	Cursor: Ptr("eyJpZCI6MTAsImRpciI6ImFzYyJ9"),}response, err := client.Chats.ListChats(ctx, params)// → ListChatsResponse{Data: []Chat, Meta: *PaginationMeta}

POST с телом запроса:

import pachca "github.com/pachca/openapi/sdk/go/generated" // Создание чатаrequest := ChatCreateRequest{	Chat: ChatCreateRequestChat{		Name: "🤿 aqua",		MemberIDs: []int32{int32(123)},		GroupTagIDs: []int32{int32(123)},		Channel: Ptr(true),		Public: Ptr(false),	},}response, err := client.Chats.CreateChat(ctx, request)// → Chat{ID: int32, Name: string, CreatedAt: string, OwnerID: int32, MemberIDs: []int32, GroupTagIDs: []int32, Channel: bool, Personal: bool, Public: bool, LastMessageAt: string, MeetRoomURL: string}

Простой вызов по ID:

import pachca "github.com/pachca/openapi/sdk/go/generated" // Получение чатаresponse, err := client.Chats.GetChat(ctx, int32(334))// → Chat{ID: int32, Name: string, CreatedAt: string, OwnerID: int32, MemberIDs: []int32, GroupTagIDs: []int32, Channel: bool, Personal: bool, Public: bool, LastMessageAt: string, MeetRoomURL: string}

Указатели для необязательных полей

Для необязательных полей используйте функцию Ptr():

request := pachca.ChatUpdateRequest{    Chat: pachca.ChatUpdateRequestChat{        Name:   pachca.Ptr("Новое название"),        Public: pachca.Ptr(true),    },}

Пагинация

Методы, возвращающие списки, используют cursor-based пагинацию. Ответ содержит Meta.Paginate.NextPage — курсор для следующей страницы.

Ручная пагинация

var cursor *stringfor {    params := &pachca.ListUsersParams{Limit: pachca.Ptr(int32(50)), Cursor: cursor}    response, err := client.Users.ListUsers(ctx, params)    if err != nil {        log.Fatal(err)    }    for _, user := range response.Data {        fmt.Println(user.FirstName, user.LastName)    }    if response.Meta == nil || response.Meta.Paginate == nil || response.Meta.Paginate.NextPage == nil {        break    }    cursor = response.Meta.Paginate.NextPage}

Автопагинация

Для каждого метода с пагинацией есть *All() вариант:

// Все пользователи одним слайсомusers, err := client.Users.ListUsersAll(ctx, nil)if err != nil {    log.Fatal(err)}fmt.Printf("Всего: %d\n", len(users))

Доступные методы автопагинации:

МетодВозвращает
Security.GetAuditEventsAll()[]AuditEvent
Bots.GetWebhookEventsAll()[]WebhookEvent
Chats.ListChatsAll()[]Chat
GroupTags.ListTagsAll()[]GroupTag
GroupTags.GetTagUsersAll()[]User
Members.ListMembersAll()[]User
Messages.ListChatMessagesAll()[]Message
Reactions.ListReactionsAll()[]Reaction
Search.SearchChatsAll()[]Chat
Search.SearchMessagesAll()[]Message
Search.SearchUsersAll()[]User
Tasks.ListTasksAll()[]Task
Users.ListUsersAll()[]User

Обработка ошибок

SDK возвращает два типа ошибок (реализуют интерфейс error):

ApiError

Возникает при ошибках 400, 403, 404, 409, 410, 422:

chat, err := client.Chats.CreateChat(ctx, request)if err != nil {    var apiErr *pachca.ApiError    if errors.As(err, &apiErr) {        for _, e := range apiErr.Errors {            fmt.Println(e.Key, e.Message)   // "name", "не может быть пустым"            fmt.Println(e.Code)             // ValidationErrorCodeBlank        }    }}

Поля ApiErrorItem:

ПолеТипОписание
KeystringПоле, вызвавшее ошибку
Value*stringПереданное значение
MessagestringТекст ошибки
CodeValidationErrorCodeКод валидации
Payload*stringДополнительные данные

OAuthError

Возникает при ошибке авторизации (401):

user, err := client.Profile.GetProfile(ctx)if err != nil {    var oauthErr *pachca.OAuthError    if errors.As(err, &oauthErr) {        fmt.Println(oauthErr.Err)              // "Token not found"        fmt.Println(oauthErr.ErrorDescription)  // описание ошибки    }}

Повторные запросы

SDK автоматически повторяет запрос при получении 429 Too Many Requests:

  • До 3 повторов на каждый запрос
  • Если сервер вернул заголовок Retry-After — ждёт указанное время
  • Иначе — экспоненциальный backoff: 1 сек, 2 сек, 4 сек
  • Тело запроса пересоздаётся через req.GetBody() при каждой попытке

Типы

Все типы экспортируются из пакета:

import pachca "github.com/pachca/openapi/sdk/go/generated" // Моделиvar chat pachca.Chatvar msg  pachca.Messagevar user pachca.User // Запросыvar req pachca.ChatCreateRequest // Перечисленияkey := pachca.AuditEventKeyUserLoginavailability := pachca.ChatAvailabilityIsOpenrole := pachca.ChatMemberRoleAdminstatus := pachca.TaskStatusDone // Ошибкиvar apiErr *pachca.ApiErrorvar oauthErr *pachca.OAuthError

Доступные перечисления: AuditEventKey, ChatAvailability, ChatMemberRole, ChatMemberRoleFilter, ChatSubtype, CustomPropertyDataType, FileType, InviteStatus, MemberEventType, MessageEntityType, OAuthScope, ReactionEventType, SearchEntityType, SearchSortOrder, SortOrder, TaskKind, TaskStatus, UserEventType, UserRole, ValidationErrorCode, WebhookEventType.

Примеры

import pachca "github.com/pachca/openapi/sdk/go/generated" client := pachca.NewPachcaClient("YOUR_TOKEN") // Отправка сообщенияrequest := MessageCreateRequest{	Message: MessageCreateRequestMessage{		EntityType: Ptr(MessageEntityTypeDiscussion),		EntityID: int32(334),		Content: "Вчера мы продали 756 футболок (что на 10% больше, чем в прошлое воскресенье)",		Files: []MessageCreateRequestFile{MessageCreateRequestFile{			Key: "attaches/files/93746/e354fd79-4f3e-4b5a-9c8d-1a2b3c4d5e6f/logo.png",			Name: "logo.png",			FileType: FileTypeImage,			Size: int32(12345),			Width: Ptr(int32(800)),			Height: Ptr(int32(600)),		}},		Buttons: [][]Button{[]Button{Button{			Text: "Подробнее",			URL: Ptr("https://example.com/details"),			Data: Ptr("awesome"),		}}},		ParentMessageID: Ptr(int32(194270)),		DisplayAvatarURL: Ptr("https://example.com/avatar.png"),		DisplayName: Ptr("Бот Поддержки"),		SkipInviteMentions: Ptr(false),		LinkPreview: Ptr(false),	},}response, err := client.Messages.CreateMessage(ctx, request)// → Message{ID: int32, EntityType: MessageEntityType, EntityID: int32, ChatID: int32, RootChatID: int32, Content: string, UserID: int32, CreatedAt: string, URL: string, Files: []File{ID: int32, Key: string, Name: string, FileType: FileType, URL: string, Width: *int32, Height: *int32}, Buttons: *[][]Button{Text: string, URL: *string, Data: *string}, Thread: *Thread{ID: int64, ChatID: int64, MessageID: int64, MessageChatID: int64, UpdatedAt: string}, Forwarding: *Forwarding{OriginalMessageID: int32, OriginalChatID: int32, AuthorID: int32, OriginalCreatedAt: string, OriginalThreadID: *int32, OriginalThreadMessageID: *int32, OriginalThreadParentChatID: *int32}, ParentMessageID: *int32, DisplayAvatarURL: *string, DisplayName: *string, ChangedAt: *string, DeletedAt: *string} // Список сотрудниковparams := &ListUsersParams{	Query: Ptr("Олег"),	Limit: Ptr(int32(1)),	Cursor: Ptr("eyJpZCI6MTAsImRpciI6ImFzYyJ9"),}response, err := client.Users.ListUsers(ctx, params)// → ListUsersResponse{Data: []User, Meta: *PaginationMeta} // Создание задачиrequest := TaskCreateRequest{	Task: TaskCreateRequestTask{		Kind: TaskKindReminder,		Content: Ptr("Забрать со склада 21 заказ"),		DueAt: Ptr("2020-06-05T12:00:00.000+03:00"),		Priority: Ptr(int32(2)),		PerformerIDs: []int32{int32(123)},		ChatID: Ptr(int32(456)),		AllDay: Ptr(false),		CustomProperties: []TaskCreateRequestCustomProperty{TaskCreateRequestCustomProperty{			ID: int32(78),			Value: "Синий склад",		}},	},}response, err := client.Tasks.CreateTask(ctx, request)// → Task{ID: int32, Kind: TaskKind, Content: string, DueAt: *string, Priority: int32, UserID: int32, ChatID: *int32, Status: TaskStatus, CreatedAt: string, PerformerIDs: []int32, AllDay: bool, CustomProperties: []CustomProperty{ID: int32, Name: string, DataType: CustomPropertyDataType, Value: string}}