forked from Sanders/TelegaBot
feat: Add OpenRouter AI integration with config, service, and tests
This commit is contained in:
+1
-1
@@ -54,7 +54,7 @@ dependencies {
|
||||
runtimeOnly group: 'org.flywaydb', name: 'flyway-database-postgresql', version: '11.3.1'
|
||||
// https://mvnrepository.com/artifact/org.postgresql/postgresql
|
||||
implementation group: 'org.postgresql', name: 'postgresql', version: '42.7.5'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package ru.cathub.telegabot.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "openrouter.api")
|
||||
@Getter
|
||||
@Setter
|
||||
public class OpenRouterConfig {
|
||||
private String key;
|
||||
private String url;
|
||||
private String model;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ru.cathub.telegabot.exception;
|
||||
|
||||
public class OpenRouterException extends Exception {
|
||||
public OpenRouterException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public OpenRouterException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package ru.cathub.telegabot.service;
|
||||
|
||||
import ru.cathub.telegabot.exception.OpenRouterException;
|
||||
|
||||
public interface OpenRouterService {
|
||||
String getChatResponse(String message) throws OpenRouterException;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package ru.cathub.telegabot.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import ru.cathub.telegabot.config.OpenRouterConfig;
|
||||
import ru.cathub.telegabot.exception.OpenRouterException;
|
||||
import ru.cathub.telegabot.service.OpenRouterService;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class OpenRouterServiceImpl implements OpenRouterService {
|
||||
|
||||
private final OpenRouterConfig config;
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
@Override
|
||||
public String getChatResponse(String message) throws OpenRouterException {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(config.getKey());
|
||||
headers.add("HTTP-Referer", "https://github.com/your-username/telegabot");
|
||||
headers.add("X-Title", "TelegaBot");
|
||||
|
||||
Map<String, Object> request = new HashMap<>();
|
||||
request.put("model", config.getModel());
|
||||
request.put("messages", List.of(Map.of(
|
||||
"role", "user",
|
||||
"content", message
|
||||
)));
|
||||
|
||||
try {
|
||||
ResponseEntity<Map> response = restTemplate.postForEntity(
|
||||
config.getUrl() + "/chat/completions",
|
||||
new HttpEntity<>(request, headers),
|
||||
Map.class
|
||||
);
|
||||
|
||||
return extractResponse(response.getBody());
|
||||
} catch (RestClientException e) {
|
||||
log.error("OpenRouter API error: {}", e.getMessage());
|
||||
throw new OpenRouterException("API request failed: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String extractResponse(Map<String, Object> response) {
|
||||
try {
|
||||
List<Map<String, Object>> choices = (List<Map<String, Object>>) response.get("choices");
|
||||
Map<String, Object> firstChoice = choices.get(0);
|
||||
Map<String, String> message = (Map<String, String>) firstChoice.get("message");
|
||||
return message.get("content");
|
||||
} catch (Exception e) {
|
||||
throw new OpenRouterException("Error parsing API response");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,3 +37,9 @@ logging.level.io.hypersistence.utils.hibernate.query=DEBUG
|
||||
|
||||
# ??????????? ????
|
||||
logging.level.org.springframework.cache=INFO
|
||||
|
||||
# OpenRouter AI
|
||||
openrouter.api.url=https://openrouter.ai/api/v1
|
||||
openrouter.api.model=gryphe/mythomax-l2-13b
|
||||
# Для безопасности лучше установить через переменную окружения:
|
||||
openrouter.api.key=${OPENROUTER_API_KEY}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package ru.cathub.telegabot.service;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestClientException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import ru.cathub.telegabot.exception.OpenRouterException;
|
||||
import ru.cathub.telegabot.service.impl.OpenRouterServiceImpl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class OpenRouterServiceTest {
|
||||
|
||||
@Mock
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@InjectMocks
|
||||
private OpenRouterServiceImpl openRouterService;
|
||||
|
||||
@Test
|
||||
void shouldReturnValidResponse() throws OpenRouterException {
|
||||
// Mock response
|
||||
Map<String, Object> mockResponse = Map.of(
|
||||
"choices", List.of(Map.of(
|
||||
"message", Map.of("content", "Test response")
|
||||
))
|
||||
);
|
||||
|
||||
when(restTemplate.postForEntity(anyString(), any(), eq(Map.class)))
|
||||
.thenReturn(new ResponseEntity<>(mockResponse, HttpStatus.OK));
|
||||
|
||||
String response = openRouterService.getChatResponse("Test message");
|
||||
assertEquals("Test response", response);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowExceptionOnApiError() {
|
||||
when(restTemplate.postForEntity(anyString(), any(), eq(Map.class)))
|
||||
.thenThrow(new RestClientException("API error"));
|
||||
|
||||
assertThrows(OpenRouterException.class,
|
||||
() -> openRouterService.getChatResponse("Test message"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user