Skip to content

Commit f63730b

Browse files
authored
Merge pull request #48 from vansisto/IG-46
IG-46 to dev
2 parents 09e5693 + cf1d0fd commit f63730b

13 files changed

+206
-30
lines changed

pom.xml

-15
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,11 @@
5858
<artifactId>jackson-databind</artifactId>
5959
<version>${jackson.version}</version>
6060
</dependency>
61-
<!-- <dependency>-->
62-
<!-- <groupId>com.fasterxml.jackson.core</groupId>-->
63-
<!-- <artifactId>jackson-core</artifactId>-->
64-
<!-- <version>${jackson.version}</version>-->
65-
<!-- </dependency>-->
66-
<!-- <dependency>-->
67-
<!-- <groupId>com.fasterxml.jackson.core</groupId>-->
68-
<!-- <artifactId>jackson-annotations</artifactId>-->
69-
<!-- <version>${jackson.version}</version>-->
70-
<!-- </dependency>-->
7161
<dependency>
7262
<groupId>com.github.pengrad</groupId>
7363
<artifactId>java-telegram-bot-api</artifactId>
7464
<version>6.6.0</version>
7565
</dependency>
76-
<!-- <dependency>-->
77-
<!-- <groupId>org.apache.httpcomponents.client5</groupId>-->
78-
<!-- <artifactId>httpclient5</artifactId>-->
79-
<!-- <version>5.2.1</version>-->
80-
<!-- </dependency>-->
8166
<dependency>
8267
<groupId>com.squareup.okhttp3</groupId>
8368
<artifactId>okhttp</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.vansisto.aiimagebot.exceptions;
2+
3+
public class JsonContentResponseException extends RuntimeException {
4+
public JsonContentResponseException() {
5+
super("An error occurred during parsing response json");
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.vansisto.aiimagebot.exceptions;
2+
3+
public class JsonRequestFormingException extends RuntimeException {
4+
public JsonRequestFormingException() {
5+
super("An error occurred during forming json for image generating");
6+
}
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.vansisto.aiimagebot.exceptions;
2+
3+
public class TranslationRequestException extends RuntimeException {
4+
public TranslationRequestException() {
5+
super("An error occurred during translation request");
6+
}
7+
}

src/main/java/com/vansisto/aiimagebot/services/bot/MyBot.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
import com.vansisto.aiimagebot.services.bot.handler.UpdateHandler;
88
import com.vansisto.aiimagebot.services.bot.handler.UpdateHandlerFactory;
99
import lombok.RequiredArgsConstructor;
10+
import lombok.extern.slf4j.Slf4j;
1011
import org.springframework.stereotype.Service;
1112

13+
@Slf4j
1214
@Service
1315
@RequiredArgsConstructor
1416
public class MyBot {
@@ -19,9 +21,13 @@ public class MyBot {
1921
public void run() {
2022
telegramBot.setUpdatesListener(updates -> {
2123
for (Update update : updates) {
22-
updateCache.setUpdate(update);
23-
UpdateHandler updateHandler = updateHandlerFactory.getFromUpdate(update);
24-
updateHandler.handle(update);
24+
try {
25+
updateCache.setUpdate(update);
26+
UpdateHandler updateHandler = updateHandlerFactory.getFromUpdate(update);
27+
updateHandler.handle(update);
28+
} catch (Exception e) {
29+
log.error(e.getMessage());
30+
}
2531
}
2632
return UpdatesListener.CONFIRMED_UPDATES_ALL;
2733
});

src/main/java/com/vansisto/aiimagebot/services/bot/handler/handlers/MessageHandler.java

+26-2
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22

33
import com.pengrad.telegrambot.model.Update;
44
import com.pengrad.telegrambot.request.SendMessage;
5+
import com.vansisto.aiimagebot.exceptions.JsonContentResponseException;
56
import com.vansisto.aiimagebot.services.bot.handler.AbstractHandler;
67
import com.vansisto.aiimagebot.services.bot.handler.UpdateHandler;
78
import com.vansisto.aiimagebot.services.openai.RequestsExecutor;
89
import com.vansisto.aiimagebot.services.settings.UserSetting;
910
import lombok.RequiredArgsConstructor;
11+
import lombok.extern.slf4j.Slf4j;
12+
import org.springframework.boot.configurationprocessor.json.JSONArray;
13+
import org.springframework.boot.configurationprocessor.json.JSONException;
14+
import org.springframework.boot.configurationprocessor.json.JSONObject;
1015
import org.springframework.stereotype.Service;
1116

1217
import java.util.Objects;
@@ -16,6 +21,7 @@
1621

1722
@Service
1823
@RequiredArgsConstructor
24+
@Slf4j
1925
public class MessageHandler extends AbstractHandler implements UpdateHandler {
2026
@Override
2127
public void handle(Update update) {
@@ -33,7 +39,25 @@ public boolean canHandle(Update update) {
3339
}
3440

3541
private void proceed(String messageText, long chatId, UserSetting setting) {
36-
String response = RequestsExecutor.generateImage(messageText, setting);
37-
bot.execute(new SendMessage(chatId, response));
42+
if (setting.getLocale().getLanguage().equals("uk")) {
43+
bot.execute(new SendMessage(chatId, "Translating..."));
44+
String json = RequestsExecutor.translate(messageText, setting);
45+
messageText = extractContentFromJson(json);
46+
}
47+
bot.execute(new SendMessage(chatId, "Image generating request..."));
48+
messageText = RequestsExecutor.generateImage(messageText, setting);
49+
bot.execute(new SendMessage(chatId, messageText));
50+
}
51+
52+
private String extractContentFromJson(String jsonString) {
53+
try {
54+
JSONObject jsonObject = new JSONObject(jsonString);
55+
JSONArray choices = jsonObject.getJSONArray("choices");
56+
JSONObject choice = choices.getJSONObject(0);
57+
JSONObject message = choice.getJSONObject("message");
58+
return message.getString("content");
59+
} catch (JSONException e) {
60+
throw new JsonContentResponseException();
61+
}
3862
}
3963
}

src/main/java/com/vansisto/aiimagebot/services/bot/handler/handlers/VoiceHandler.java

+13-2
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,20 @@ public void handle(Update update) {
3535
long chatId = getChatId(update);
3636

3737
try {
38+
log(chatId, "Audio downloading...");
3839
File sourceOggFile = telegramFileDownloader.downloadVoiceFile(voice);
3940
File targetMp3File = new java.io.File(update.updateId() + ".mp3");
41+
log(chatId, "Audio conversion...");
4042
CompletableFuture<File> conversionFuture = AudioConverter.convertOggToMp3(sourceOggFile, targetMp3File);
4143
String token = settingsService.getOpenAiApiKey();
4244

4345
conversionFuture.thenAccept(convertedFile -> {
44-
String response = RequestsExecutor.sendTranscriptionRequest(token, convertedFile);
45-
bot.execute(new SendMessage(chatId, response));
46+
log(chatId, "Audio transcription...");
47+
String transcript = RequestsExecutor.sendTranscriptionRequest(token, convertedFile);
48+
log(chatId, "Transcript: " + transcript);
49+
log(chatId, "Image generating request...");
50+
String response = RequestsExecutor.generateImage(transcript, settingsService.getOrInitSetting(update));
51+
log(chatId, response);
4652

4753
try {
4854
Files.delete(sourceOggFile.toPath());
@@ -64,6 +70,11 @@ public void handle(Update update) {
6470
}
6571
}
6672

73+
private void log(long chatId, String logMessage) {
74+
log.info(logMessage);
75+
bot.execute(new SendMessage(chatId, logMessage));
76+
}
77+
6778
@Override
6879
public boolean canHandle(Update update) {
6980
return Objects.nonNull(update.message()) && Objects.nonNull(getVoice(update));

src/main/java/com/vansisto/aiimagebot/services/converter/AudioConverter.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ private static void logProcessOutput(Process process) throws IOException {
6262
try (BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
6363
String line;
6464
while ((line = stdoutReader.readLine()) != null) {
65-
log.info("STDOUT: " + line);
65+
log.debug("STDOUT: " + line);
6666
}
6767
}
6868

6969
try (BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
7070
String line;
7171
while ((line = stderrReader.readLine()) != null) {
72-
log.error("STDERR: " + line);
72+
log.debug("STDERR: " + line);
7373
}
7474
}
7575
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.vansisto.aiimagebot.services.openai;
2+
3+
public class Message {
4+
private String role;
5+
private String content;
6+
7+
public Message(String role, String content) {
8+
this.role = role;
9+
this.content = content;
10+
}
11+
12+
public String getRole() {
13+
return role;
14+
}
15+
16+
public void setRole(String role) {
17+
this.role = role;
18+
}
19+
20+
public String getContent() {
21+
return content;
22+
}
23+
24+
public void setContent(String content) {
25+
this.content = content;
26+
}
27+
}

src/main/java/com/vansisto/aiimagebot/services/openai/RequestsExecutor.java

+28-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package com.vansisto.aiimagebot.services.openai;
22

33
import com.vansisto.aiimagebot.exceptions.ImageGenerationRequestException;
4+
import com.vansisto.aiimagebot.exceptions.JsonRequestFormingException;
45
import com.vansisto.aiimagebot.exceptions.TranscriptionRequestException;
6+
import com.vansisto.aiimagebot.exceptions.TranslationRequestException;
57
import com.vansisto.aiimagebot.services.openai.requests.ImageGenerationRequestUtil;
68
import com.vansisto.aiimagebot.services.openai.requests.TranscriptionRequestUtil;
9+
import com.vansisto.aiimagebot.services.openai.requests.TranslationRequestUtil;
710
import com.vansisto.aiimagebot.services.settings.UserSetting;
811
import lombok.extern.slf4j.Slf4j;
912
import okhttp3.OkHttpClient;
1013
import okhttp3.Request;
1114
import okhttp3.Response;
15+
import org.springframework.boot.configurationprocessor.json.JSONException;
16+
import org.springframework.boot.configurationprocessor.json.JSONObject;
1217

1318
import java.io.File;
1419
import java.io.IOException;
@@ -27,21 +32,40 @@ private RequestsExecutor(){}
2732

2833
public static String sendTranscriptionRequest(String token, File file) {
2934
Request request = TranscriptionRequestUtil.createRequest(token, file);
30-
log.info("TranscriptionRequestUtil request sent...");
35+
log.info("Transcription request sent...");
3136
try(Response response = client.newCall(request).execute()) {
32-
return response.isSuccessful() ? response.body().string() : "Fail: " + response.message();
37+
return getResponseResult(response);
3338
} catch (IOException e) {
3439
throw new TranscriptionRequestException();
3540
}
3641
}
3742

3843
public static String generateImage(String messageText, UserSetting setting) {
3944
Request request = ImageGenerationRequestUtil.createRequest(setting.getOpenAiApiKey(), messageText, setting.getNumberOfPictures(), setting.getSize());
40-
log.info("Image generating request sent...");
4145
try(Response response = client.newCall(request).execute()) {
42-
return response.isSuccessful() ? response.body().string() : "Fail: " + response.message();
46+
String responseJson = getResponseResult(response);
47+
JSONObject jsonResponse = new JSONObject(responseJson);
48+
return jsonResponse.getJSONArray("data").toString().replace("\\/", "/");
4349
} catch (IOException e) {
4450
throw new ImageGenerationRequestException();
51+
} catch (JSONException e) {
52+
throw new JsonRequestFormingException();
4553
}
4654
}
55+
56+
public static String translate(String messageText, UserSetting setting) {
57+
Request request = TranslationRequestUtil.createRequest(setting.getOpenAiApiKey(), messageText);
58+
log.info("Translation request sent...");
59+
try(Response response = client.newCall(request).execute()) {
60+
return getResponseResult(response);
61+
} catch (IOException e) {
62+
throw new TranslationRequestException();
63+
}
64+
}
65+
66+
private static String getResponseResult(Response response) throws IOException {
67+
return response.isSuccessful()
68+
? response.body().string().trim()
69+
: "Fail (" + response.code() + "): " + response.message();
70+
}
4771
}

src/main/java/com/vansisto/aiimagebot/services/openai/requests/ImageGenerationRequestUtil.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import okhttp3.RequestBody;
66

77
public class ImageGenerationRequestUtil {
8+
9+
private ImageGenerationRequestUtil() {}
10+
811
public static Request createRequest(String token, String prompt, int numberOfImages, String size) {
9-
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
12+
MediaType json = MediaType.parse("application/json; charset=utf-8");
1013
String jsonBody = String.format("{\"prompt\": \"%s\", \"n\": %d, \"size\": \"%s\"}", prompt, numberOfImages, size);
11-
RequestBody requestBody = RequestBody.create(JSON, jsonBody);
14+
RequestBody requestBody = RequestBody.create(json, jsonBody);
1215

1316
return new Request.Builder()
1417
.url("https://api.openai.com/v1/images/generations")

src/main/java/com/vansisto/aiimagebot/services/openai/requests/TranscriptionRequestUtil.java

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
import java.io.File;
99

1010
public class TranscriptionRequestUtil {
11+
12+
private TranscriptionRequestUtil() {}
13+
1114
private static final MediaType MEDIA_TYPE_MP3 = MediaType.parse("audio/mp3");
1215

1316
public static Request createRequest(String token, File file) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.vansisto.aiimagebot.services.openai.requests;
2+
3+
import com.vansisto.aiimagebot.exceptions.JsonRequestFormingException;
4+
import com.vansisto.aiimagebot.services.openai.Message;
5+
import okhttp3.MediaType;
6+
import okhttp3.Request;
7+
import okhttp3.RequestBody;
8+
import org.jetbrains.annotations.NotNull;
9+
import org.springframework.boot.configurationprocessor.json.JSONArray;
10+
import org.springframework.boot.configurationprocessor.json.JSONException;
11+
import org.springframework.boot.configurationprocessor.json.JSONObject;
12+
13+
import java.util.ArrayList;
14+
import java.util.List;
15+
16+
public class TranslationRequestUtil {
17+
18+
private TranslationRequestUtil() {}
19+
20+
public static Request createRequest(String token, String textToTranslate) {
21+
MediaType json = MediaType.parse("application/json; charset=utf-8");
22+
23+
List<Message> messages = createPromptMessages(textToTranslate);
24+
JSONObject jsonBody = makeJsonFromPrompts(messages);
25+
RequestBody requestBody = RequestBody.create(json, jsonBody.toString());
26+
27+
return new Request.Builder()
28+
.url("https://api.openai.com/v1/chat/completions")
29+
.post(requestBody)
30+
.header("Authorization", "Bearer " + token)
31+
.header("Content-Type", "application/json")
32+
.build();
33+
}
34+
35+
private static JSONObject makeJsonFromPrompts(List<Message> messages) {
36+
JSONObject jsonBody = new JSONObject();
37+
JSONArray jsonArray = new JSONArray();
38+
for (Message message : messages) {
39+
try {
40+
JSONObject jsonObject = new JSONObject();
41+
42+
jsonObject.put("role", message.getRole());
43+
jsonObject.put("content", message.getContent());
44+
45+
jsonArray.put(jsonObject);
46+
47+
} catch (JSONException e) {
48+
throw new JsonRequestFormingException();
49+
}
50+
}
51+
try {
52+
jsonBody.put("model", "gpt-3.5-turbo");
53+
jsonBody.put("messages", jsonArray);
54+
} catch (JSONException e) {
55+
throw new JsonRequestFormingException();
56+
}
57+
58+
return jsonBody;
59+
}
60+
61+
@NotNull
62+
private static List<Message> createPromptMessages(String textToTranslate) {
63+
List<Message> messages = new ArrayList<>();
64+
messages.add(new Message("system", "You are a translator from Ukrainian to English"));
65+
messages.add(new Message("user", "Тарас Шевченко! Досить було однієї людини, щоб урятувати цілу націю"));
66+
messages.add(new Message("assistant", "Taras Shevchenko. One man was enough to save an entire nation"));
67+
messages.add(new Message("user", "Поганий той школяр який учителя не переважить"));
68+
messages.add(new Message("assistant", "A bad student is a student who cannot surpass his teacher"));
69+
messages.add(new Message("user", textToTranslate));
70+
return messages;
71+
}
72+
}

0 commit comments

Comments
 (0)