Для разработчиков

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, InviterID: *int32, 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.Oauth.GetTokenInfo()GETИнформация о токене
client.Chats.CreateChat()POSTНовый чат
client.Chats.RequestExport()POSTЭкспорт сообщений
client.Chats.ListChats()GETСписок чатов
client.Chats.DownloadExport()GETСкачать архив экспорта
client.Chats.GetChat()GETИнформация о чате
client.Chats.UpdateChat()PUTРедактирование чата
client.Chats.ArchiveChat()PUTАрхивация чата
client.Chats.UnarchiveChat()PUTРазархивация чата
client.Profile.GetProfile()GETСвой профиль
client.Profile.GetStatus()GETСвой статус
client.Profile.UpdateProfileAvatar()PUTЗагрузка своего аватара
client.Profile.UpdateStatus()PUTНовый свой статус
client.Profile.DeleteProfileAvatar()DELETEУдаление своего аватара
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.UpdateUserAvatar()PUTЗагрузка аватара сотрудника
client.Users.UpdateUserStatus()PUTНовый статус сотрудника
client.Users.DeleteUser()DELETEУдаление сотрудника
client.Users.DeleteUserAvatar()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.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.CreateStandaloneThread()POSTНовый самостоятельный тред
client.Threads.ListThreads()GETСписок тредов
client.Threads.GetThread()GETИнформация о треде
client.Messages.CreateMessage()POSTНовое сообщение
client.Messages.Unfurl()POSTUnfurl (разворачивание ссылок)
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.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.SelfRecreateBotToken()POSTРотация собственного токена бота
client.Bots.CreateBot()POSTНовый бот
client.Bots.RecreateBotToken()POSTРотация токена бота
client.Bots.ListBots()GETСписок ботов
client.Bots.GetBot()GETИнформация о боте
client.Bots.GetWebhookEvents()GETИстория событий
client.Bots.SelfUpdateBotWebhook()PUTСаморегистрация вебхука бота
client.Bots.UpdateBot()PUTРедактирование бота
client.Bots.DeleteBot()DELETEУдаление бота
client.Bots.DeleteWebhookEvent()DELETEУдаление события
client.Security.GetAuditEvents()GETЖурнал аудита событий
client.CustomProperties.ListProperties()GETСписок дополнительных полей
client.Files.UploadFile()POSTЗагрузка файла
client.Files.GetUploadParams()POSTПолучение подписи, ключа и других параметров

Запросы

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

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

import pachca "github.com/pachca/openapi/sdk/go/generated" // Список чатовparams := &ListChatsParams{	Sort: Ptr(ChatSortFieldID),	Order: Ptr(SortOrderDesc),	Availability: Ptr(ChatAvailabilityIsMember),	Archived: Ptr(true),	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, Archived: 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, Archived: bool, Personal: bool, Public: bool, LastMessageAt: string, MeetRoomURL: string}

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

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

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

Пагинация

SDK работает с двумя группами методов, возвращающих списки, у которых разная структура Meta — это важно учитывать при ручной пагинации:

  • Списочные методы (client.Users.ListUsers(), client.Chats.ListChats(), client.Messages.ListChatMessages() и т.д.) — Meta.Paginate с полями NextPage, PrevPage, HasNext, HasPrev. Признак конца — HasNext == false. Курсор PrevPage нужен для polling новых записей «сверху» списка.
  • Методы поиска (client.Search.SearchUsers(), client.Search.SearchChats(), client.Search.SearchMessages()) — Meta с полями Total и Paginate.NextPage (без PrevPage/HasNext/HasPrev). Признак конца — пустой Data или совпадение числа полученных записей с Total.

Курсоры — непрозрачные токены, никогда не бывают пустыми. Подробное описание полей и примеры — на странице Пагинация.

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

var cursor *stringhasNext := truefor hasNext {    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)    }    nextPage := response.Meta.Paginate.NextPage    cursor = &nextPage    hasNext = response.Meta.Paginate.HasNext}

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

Для каждого метода с пагинацией есть *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 и ошибок сервера 5xx (500, 502, 503, 504):

  • До 3 повторов на каждый запрос
  • 429: если сервер вернул заголовок Retry-After — ждёт указанное время, иначе — экспоненциальный backoff: 1 сек, 2 сек, 4 сек
  • 5xx: экспоненциальный backoff с jitter: ~10 сек, ~20 сек, ~40 сек
  • Тело запроса пересоздаётся через req.GetBody() при каждой попытке
  • Ошибки клиента (4xx, кроме 429) возвращаются сразу без повторов

Типы

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

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)),			DurationMs: Ptr(int32(5400)),			Waveform: Ptr("4,8,12,20,16,10,6,3"),		}},		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}, VoiceContent: *VoiceContent{DurationMs: int32, Waveform: string, Transcript: *string}, Buttons: *[][]Button{Text: string, URL: *string, Data: *string}, Thread: *MessageThread{ID: int64, ChatID: int64}, 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}}