Подключение к GigaChat API на Java: пошаговое руководство

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всем привет! В этой статье я расскажу о том, как подключиться к API GigaChat в IntelliJ IDEA на Java и настроить безопасное соединение с использованием SSL-сертификатов, чтобы получать ответы от GigaChat в своем приложении.

1. Что такое GigaChat и зачем он нужен?

GigaChat API — это интерфейс для интеграции AI-системы, разработанной для проведения диалогов и помощи с генерацией текста. Он может применяться для создания интерактивных приложений, таких как чат-боты, системы поддержки и более сложных аналитических инструментов, требующих обработки языка.

Сам GigaChat имеет подробную документацию по интеграции по API -> Установка | Документация для разработчиков , однако, я решил, что пошаговый личный пример, может быть интересен сообществу и возможно кому-то сэкономит немного времени при настройке.

2. Настройка окружения

Для работы с GigaChat API вам потребуется Java, а также клиент для HTTP-запросов, например, OkHttp. Ниже приведён список зависимостей и некоторые базовые настройки.

Зависимости

Добавим в проект OkHttp для отправки HTTP-запросов. Если используете Gradle, добавьте в build.gradle:

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.9.3'
}

3. Получение SSL-сертификатов

Поскольку GigaChat API требует защищённого соединения, необходимо настроить сертификаты SSL. Получите корневой и подчинённый сертификаты (CA Certificates) согласно документации и сохраните их в папке проекта. У себя я их разместил в src/main/resources/certs.

4. Класс для подключения к API

Ниже привожу код, который создаёт запрос к GigaChat API, используя OkHttpClient с настройками SSL-сертификата.

Код для GigaChatDialog

import okhttp3.*;
import javax.net.ssl.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

public class GigaChatDialog {

    private static final String API_URL = "https://gigachat.devices.sberbank.ru/api/v1/chat/completions";
    private static final String CERT_PATH = "src/main/resources/certs/russian_trusted_sub_ca.cer";
    private static final String ACCESS_TOKEN = "токен_доступа";

    private OkHttpClient client;

    public GigaChatDialog() {
        try {
            this.client = createClient();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private OkHttpClient createClient() throws Exception {
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStream certInput = new FileInputStream(CERT_PATH);
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(certInput);

        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);

        return new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0])
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .build();
    }

    public String getResponse(String message) {
        String jsonPayload = "{ \"model\": \"GigaChat\", \"messages\": [{ \"role\": \"user\", \"content\": \"" + message + "\" }], \"stream\": false }";
        RequestBody body = RequestBody.create(jsonPayload, MediaType.get("application/json; charset=utf-8"));

        Request request = new Request.Builder()
                .url(API_URL)
                .post(body)
                .addHeader("Authorization", "Bearer " + ACCESS_TOKEN)
                .addHeader("Content-Type", "application/json")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                throw new IOException("Unexpected code " + response);
            }
            return new String(response.body().bytes(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}

Что делает этот код?

  1. Загружает сертификат: Использует TrustManagerFactory, чтобы загружать корневой сертификат.

  2. Настраивает SSLContext: Настраивает клиент OkHttp для работы с сертификатом и SSLContext.

  3. Формирует запрос: Создаёт JSON-пayload с текстом запроса и отправляет его на сервер.

  4. Обрабатывает ответ: Получает ответ и возвращает его как строку в UTF-8, чтобы избежать проблем с кодировкой.

5. Что за зверь AccessToken и где его взять

В доке GigaChat API указано, что для взаимодействия необходим AccessToken, срок жизни его 30 минут. Достать его можно несколькими способами:

пробросить curl, как написано в официальной документации или есть небольшой метод на Phyton, однако curl у меня не сработал, поэтому я пошел своим путем и написал небольшой метод на java, который получает токен, привожу ключевые моменты

            // Кодирование client_id и client_secret в формате Base64
            String authKey = Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8));
          
            // Создание тела запроса для POST
            RequestBody formBody = new FormBody.Builder()
                    .add("scope", "GIGACHAT_API_PERS")
                    .build();

            // Создание запроса
            Request request = new Request.Builder()
                    .url(url)
                    .post(formBody)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .addHeader("Accept", "application/json")
                    .addHeader("RqUID", "хххххххх-хххх-хххх-хххх-хххххххххххх")  // Замените на уникальный идентификатор запроса
                    .addHeader("Authorization", "Basic " + authKey)
                    .build();

            // Создание OkHttpClient с SSL-сертификатом
            OkHttpClient client = new OkHttpClient.Builder()
                    .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) tmf.getTrustManagers()[0])
                    .build();

            // Выполнение запроса
            try (Response response = client.newCall(request).execute()) {

                // Обработка ответа
                if (response.isSuccessful() && response.body() != null) {
                    System.out.println("Access Token: " + response.body().string());
                } else {
                    System.out.println("Response body: " + (response.body() != null ? response.body().string() : "No response body"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

Тут отмечу, что RqUID - обязательное поле, без него у меня сыпалась ошибка неверного формата запроса.

6. Пример использования

Теперь давайте используем наш класс GigaChatDialog, чтобы получить ответ от GigaChat API.

    public static void main(String[] args) {
        GigaChatDialog chatDialog = new GigaChatDialog();
        String response = chatDialog.getResponse("Привет, GigaChat! Как дела?");
        System.out.println("GigaChat: " + response);
    }

Ответ получим в следующем формате:

7. Проблемы с которыми я столкнулся при подключении

  • RqUID - обязательный в хедерах запроса

  • 401 Unauthorized: Проверьте, правильно ли указан токен доступа.

  • SSLHandshakeException: Убедитесь, что сертификаты загружены правильно и пути к ним указаны верно.

Вместо заключения

Теперь вы знаете, как подключить Java-приложение к GigaChat API и как настроить клиент для работы с SSL-сертификатами. Надеюсь, статья была полезной и поможет вам использовать AI в своих проектах! Делитесь своими мыслями и вопросами в комментариях — будет интересно обсудить!

Источник: https://habr.com/ru/articles/854820/


Интересные статьи

Интересные статьи

Как можно получать элементы инфоблоков в 1С-Битрикс в ядре d7?У \CIBlockElement::getList(), на первый взгляд, есть свои преимущества, она задокументирована, о ней много статей на форумах. Её дебагинг ...
В этом руководстве я покажу, как протестировать использование внешнего API с помощью Python моков.Интеграция со сторонними приложениями — отличный способ расширить функциональность любого продукта. Од...
Во второй части статьи про bitrix кластер мы будет рассматривать настройку percona xtradb cluster mysql 5.7, настройка арбитра, настройка удобного dashboard.Если вы пропустили предыдущие части: Первая...