Replace ChatGPT with Google Gemini
This commit is contained in:
@@ -3,7 +3,8 @@
|
||||
"allow": [
|
||||
"Bash(tree:*)",
|
||||
"Bash(mvn clean compile:*)",
|
||||
"WebFetch(domain:github.com)"
|
||||
"WebFetch(domain:github.com)",
|
||||
"Bash(rm:*)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
# OpenAI API Configuration
|
||||
OPENAI_API_KEY=your_openai_api_key_here
|
||||
# Google Gemini API Configuration
|
||||
# Get your free API key from: https://aistudio.google.com/app/apikey
|
||||
GEMINI_API_KEY=your_gemini_api_key_here
|
||||
|
||||
# Twitter API Configuration (OAuth 2.0)
|
||||
# Twitter API Configuration (OAuth 1.0a)
|
||||
# Get your credentials from Twitter Developer Portal: https://developer.twitter.com/
|
||||
TWITTER_API_KEY=your_twitter_api_key_here
|
||||
TWITTER_API_SECRET=your_twitter_api_secret_here
|
||||
TWITTER_ACCESS_TOKEN=your_twitter_access_token_here
|
||||
TWITTER_ACCESS_TOKEN_SECRET=your_twitter_access_token_secret_here
|
||||
TWITTER_BEARER_TOKEN=your_twitter_bearer_token_here
|
||||
|
||||
# Tweet Generation Configuration
|
||||
TWEET_PROMPT=Write a short, engaging tweet about technology trends
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,9 @@
|
||||
# Environment variables (IMPORTANT: Never commit API keys!)
|
||||
.env
|
||||
|
||||
# OAuth 2.0 tokens (IMPORTANT: Never commit access tokens!)
|
||||
.twitter_tokens.json
|
||||
|
||||
# Maven
|
||||
target/
|
||||
pom.xml.tag
|
||||
|
||||
46
README.md
46
README.md
@@ -1,10 +1,10 @@
|
||||
# TweetBot - AI-Powered Twitter Bot
|
||||
|
||||
An automated Twitter bot that generates and posts tweets using OpenAI's ChatGPT API. This Java application allows you to create engaging social media content with custom prompts.
|
||||
An automated Twitter bot that generates and posts tweets using Google Gemini's free API. This Java application allows you to create engaging social media content with custom prompts.
|
||||
|
||||
## Features
|
||||
|
||||
- Generate tweet content using ChatGPT (GPT-3.5-turbo)
|
||||
- Generate tweet content using Google Gemini (gemini-2.0-flash-exp) - **Free Tier**
|
||||
- **Three operation modes:**
|
||||
- Interactive mode with manual approval
|
||||
- Auto-post mode for one-time tweets
|
||||
@@ -22,17 +22,24 @@ An automated Twitter bot that generates and posts tweets using OpenAI's ChatGPT
|
||||
|
||||
- Java 17 or higher
|
||||
- Maven 3.6 or higher
|
||||
- OpenAI API key
|
||||
- Google Gemini API key (free tier available)
|
||||
- Twitter Developer Account with API credentials
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. Get OpenAI API Key
|
||||
### 1. Get Google Gemini API Key (Free)
|
||||
|
||||
1. Go to [OpenAI Platform](https://platform.openai.com/)
|
||||
2. Sign up or log in to your account
|
||||
3. Navigate to API keys section
|
||||
4. Create a new API key and save it securely
|
||||
1. Go to [Google AI Studio](https://aistudio.google.com/app/apikey)
|
||||
2. Sign in with your Google account
|
||||
3. Click "Create API Key"
|
||||
4. Select or create a Google Cloud project
|
||||
5. Copy the API key and save it securely
|
||||
|
||||
**Note:** The free tier of Google Gemini includes:
|
||||
- 15 requests per minute
|
||||
- 1 million tokens per minute
|
||||
- 1,500 requests per day
|
||||
- More than enough for a tweet bot!
|
||||
|
||||
### 2. Get Twitter API Credentials
|
||||
|
||||
@@ -44,7 +51,6 @@ An automated Twitter bot that generates and posts tweets using OpenAI's ChatGPT
|
||||
- API Secret (Consumer Secret)
|
||||
- Access Token
|
||||
- Access Token Secret
|
||||
- Bearer Token
|
||||
|
||||
**Important:** Ensure your Twitter app has **Read and Write** permissions:
|
||||
- Go to your app settings
|
||||
@@ -60,12 +66,11 @@ An automated Twitter bot that generates and posts tweets using OpenAI's ChatGPT
|
||||
|
||||
2. Edit `.env` and add your API credentials:
|
||||
```
|
||||
OPENAI_API_KEY=sk-your-openai-api-key-here
|
||||
GEMINI_API_KEY=your-gemini-api-key-here
|
||||
TWITTER_API_KEY=your-twitter-api-key
|
||||
TWITTER_API_SECRET=your-twitter-api-secret
|
||||
TWITTER_ACCESS_TOKEN=your-twitter-access-token
|
||||
TWITTER_ACCESS_TOKEN_SECRET=your-twitter-access-token-secret
|
||||
TWITTER_BEARER_TOKEN=your-twitter-bearer-token
|
||||
TWEET_PROMPT=Write a short, engaging tweet about technology trends
|
||||
IMAGE_PATH=/path/to/your/image.jpg
|
||||
```
|
||||
@@ -80,7 +85,7 @@ An automated Twitter bot that generates and posts tweets using OpenAI's ChatGPT
|
||||
- Supported formats: JPEG, PNG, GIF
|
||||
- Maximum file size: 5MB (Twitter limit)
|
||||
|
||||
### 5. Build the Project
|
||||
### 4. Build the Project
|
||||
|
||||
```bash
|
||||
mvn clean package
|
||||
@@ -216,7 +221,7 @@ tweetbot/
|
||||
│ ├── config/
|
||||
│ │ └── Config.java # Configuration loader
|
||||
│ └── service/
|
||||
│ ├── OpenAIService.java # ChatGPT integration
|
||||
│ ├── GeminiService.java # Google Gemini integration
|
||||
│ └── TwitterService.java # Twitter API integration
|
||||
└── resources/
|
||||
└── logback.xml # Logging configuration
|
||||
@@ -228,12 +233,11 @@ tweetbot/
|
||||
|
||||
| Variable | Required | Description |
|
||||
|----------|----------|-------------|
|
||||
| `OPENAI_API_KEY` | Yes | Your OpenAI API key |
|
||||
| `GEMINI_API_KEY` | Yes | Your Google Gemini API key (free tier available) |
|
||||
| `TWITTER_API_KEY` | Yes | Twitter API Key (Consumer Key) |
|
||||
| `TWITTER_API_SECRET` | Yes | Twitter API Secret (Consumer Secret) |
|
||||
| `TWITTER_ACCESS_TOKEN` | Yes | Twitter Access Token |
|
||||
| `TWITTER_ACCESS_TOKEN_SECRET` | Yes | Twitter Access Token Secret |
|
||||
| `TWITTER_BEARER_TOKEN` | Yes | Twitter Bearer Token |
|
||||
| `TWEET_PROMPT` | No | Default prompt for tweet generation |
|
||||
| `IMAGE_PATH` | No | Path to image file to attach to every tweet (jpg, png, gif) |
|
||||
|
||||
@@ -371,9 +375,10 @@ Ensure your `.env` file exists and contains all required variables.
|
||||
|
||||
### "Failed to generate tweet"
|
||||
|
||||
1. Verify your OpenAI API key is valid
|
||||
2. Check that you have sufficient API credits
|
||||
1. Verify your Gemini API key is valid
|
||||
2. Check that you're within the free tier rate limits (15 RPM, 1500 RPD)
|
||||
3. Review the error message in logs
|
||||
4. Ensure your Google Cloud project is properly configured
|
||||
|
||||
### Twitter API Rate Limits
|
||||
|
||||
@@ -385,9 +390,7 @@ Twitter API has rate limits:
|
||||
|
||||
## Dependencies
|
||||
|
||||
- **Twitter API Java SDK** (2.0.3) - Twitter API client
|
||||
- **OpenAI GPT-3 Java** (0.18.2) - OpenAI API client
|
||||
- **OkHttp** (4.12.0) - HTTP client
|
||||
- **OkHttp** (4.12.0) - HTTP client for API requests
|
||||
- **Jackson** (2.16.1) - JSON processing
|
||||
- **SLF4J & Logback** (2.0.9) - Logging
|
||||
- **Dotenv** (3.0.0) - Environment variable management
|
||||
@@ -406,7 +409,6 @@ private static final int SCHEDULE_INTERVAL_MINUTES = 30; // Change this value
|
||||
|
||||
### Other Enhancement Ideas
|
||||
|
||||
- Add support for images and media attachments
|
||||
- Implement tweet threading for longer content
|
||||
- Add sentiment analysis before posting
|
||||
- Create multiple prompt templates with rotation
|
||||
@@ -429,4 +431,4 @@ For issues or questions:
|
||||
1. Check the troubleshooting section
|
||||
2. Review application logs in `tweetbot.log`
|
||||
3. Verify API credentials and permissions
|
||||
4. Check Twitter and OpenAI API status pages
|
||||
4. Check Twitter and Google AI Studio status pages
|
||||
|
||||
9
pom.xml
9
pom.xml
@@ -11,7 +11,7 @@
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>TweetBot</name>
|
||||
<description>Auto-posting tweets with ChatGPT generated content</description>
|
||||
<description>Auto-posting tweets with Google Gemini generated content</description>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
@@ -20,13 +20,6 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- OpenAI Java Client -->
|
||||
<dependency>
|
||||
<groupId>com.theokanning.openai-gpt3-java</groupId>
|
||||
<artifactId>service</artifactId>
|
||||
<version>0.18.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- OkHttp for HTTP requests -->
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.voidcode.tweetbot;
|
||||
|
||||
import com.voidcode.tweetbot.config.Config;
|
||||
import com.voidcode.tweetbot.service.OpenAIService;
|
||||
import com.voidcode.tweetbot.service.GeminiService;
|
||||
import com.voidcode.tweetbot.service.TwitterService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class TweetBot {
|
||||
private static final Logger logger = LoggerFactory.getLogger(TweetBot.class);
|
||||
private static final int SCHEDULE_INTERVAL_MINUTES = 30;
|
||||
private static OpenAIService openAIService;
|
||||
private static GeminiService geminiService;
|
||||
private static TwitterService twitterService;
|
||||
private static String tweetPrompt;
|
||||
private static String imagePath;
|
||||
@@ -48,7 +48,7 @@ public class TweetBot {
|
||||
|
||||
// Load configuration
|
||||
logger.info("Loading configuration...");
|
||||
String openAIApiKey = Config.getOpenAIApiKey();
|
||||
String geminiApiKey = Config.getGeminiApiKey();
|
||||
String twitterApiKey = Config.getTwitterApiKey();
|
||||
String twitterApiSecret = Config.getTwitterApiSecret();
|
||||
String twitterAccessToken = Config.getTwitterAccessToken();
|
||||
@@ -66,7 +66,7 @@ public class TweetBot {
|
||||
|
||||
// Initialize services
|
||||
logger.info("Initializing services...");
|
||||
openAIService = new OpenAIService(openAIApiKey);
|
||||
geminiService = new GeminiService(geminiApiKey);
|
||||
twitterService = new TwitterService(
|
||||
twitterApiKey,
|
||||
twitterApiSecret,
|
||||
@@ -114,8 +114,8 @@ public class TweetBot {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
logger.info("Shutdown signal received, stopping TweetBot...");
|
||||
isRunning = false;
|
||||
if (openAIService != null) {
|
||||
openAIService.shutdown();
|
||||
if (geminiService != null) {
|
||||
geminiService.shutdown();
|
||||
}
|
||||
logger.info("TweetBot stopped gracefully");
|
||||
}));
|
||||
@@ -157,7 +157,7 @@ public class TweetBot {
|
||||
try {
|
||||
// Generate tweet content
|
||||
logger.info("Generating tweet content...");
|
||||
String tweetContent = openAIService.generateTweet(tweetPrompt);
|
||||
String tweetContent = geminiService.generateTweet(tweetPrompt);
|
||||
|
||||
// Display generated content
|
||||
System.out.println("\n" + "=".repeat(60));
|
||||
@@ -196,8 +196,8 @@ public class TweetBot {
|
||||
|
||||
} finally {
|
||||
// Cleanup
|
||||
if (openAIService != null) {
|
||||
openAIService.shutdown();
|
||||
if (geminiService != null) {
|
||||
geminiService.shutdown();
|
||||
}
|
||||
logger.info("TweetBot finished");
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public class TweetBot {
|
||||
logger.info("[{}] Starting scheduled tweet posting...", timestamp);
|
||||
|
||||
// Generate tweet content
|
||||
String tweetContent = openAIService.generateTweet(tweetPrompt);
|
||||
String tweetContent = geminiService.generateTweet(tweetPrompt);
|
||||
logger.info("Generated tweet: {}", tweetContent);
|
||||
|
||||
// Post tweet
|
||||
@@ -233,7 +233,7 @@ public class TweetBot {
|
||||
}
|
||||
|
||||
private static void printUsage() {
|
||||
System.out.println("TweetBot - Automated Twitter posting with ChatGPT");
|
||||
System.out.println("TweetBot - Automated Twitter posting with Google Gemini");
|
||||
System.out.println("\nUsage:");
|
||||
System.out.println(" java -jar tweetbot.jar [OPTIONS] [CUSTOM_PROMPT]");
|
||||
System.out.println("\nOptions:");
|
||||
|
||||
@@ -8,12 +8,12 @@ public class Config {
|
||||
.ignoreIfMissing()
|
||||
.load();
|
||||
|
||||
// OpenAI Configuration
|
||||
public static String getOpenAIApiKey() {
|
||||
return getEnvOrThrow("OPENAI_API_KEY");
|
||||
// Google Gemini Configuration
|
||||
public static String getGeminiApiKey() {
|
||||
return getEnvOrThrow("GEMINI_API_KEY");
|
||||
}
|
||||
|
||||
// Twitter Configuration
|
||||
// Twitter Configuration (OAuth 1.0a)
|
||||
public static String getTwitterApiKey() {
|
||||
return getEnvOrThrow("TWITTER_API_KEY");
|
||||
}
|
||||
@@ -30,10 +30,6 @@ public class Config {
|
||||
return getEnvOrThrow("TWITTER_ACCESS_TOKEN_SECRET");
|
||||
}
|
||||
|
||||
public static String getTwitterBearerToken() {
|
||||
return getEnvOrThrow("TWITTER_BEARER_TOKEN");
|
||||
}
|
||||
|
||||
// Tweet Generation Configuration
|
||||
public static String getTweetPrompt() {
|
||||
return dotenv.get("TWEET_PROMPT", "Write a short, engaging tweet about technology");
|
||||
|
||||
132
src/main/java/com/voidcode/tweetbot/service/GeminiService.java
Normal file
132
src/main/java/com/voidcode/tweetbot/service/GeminiService.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package com.voidcode.tweetbot.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import okhttp3.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class GeminiService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(GeminiService.class);
|
||||
private static final int MAX_TWEET_LENGTH = 280;
|
||||
private static final String GEMINI_API_URL = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent";
|
||||
private static final MediaType JSON = MediaType.get("application/json; charset=utf-8");
|
||||
|
||||
private final String apiKey;
|
||||
private final OkHttpClient httpClient;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
public GeminiService(String apiKey) {
|
||||
this.apiKey = apiKey;
|
||||
this.httpClient = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.build();
|
||||
this.objectMapper = new ObjectMapper();
|
||||
logger.info("Gemini service initialized with model: gemini-2.0-flash-exp");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tweet content using Google Gemini
|
||||
* @param prompt The prompt to generate the tweet
|
||||
* @return Generated tweet text
|
||||
*/
|
||||
public String generateTweet(String prompt) {
|
||||
try {
|
||||
logger.info("Generating tweet with prompt: {}", prompt);
|
||||
|
||||
// Build the request body
|
||||
String systemInstruction = "You are a creative social media content creator. Generate engaging tweets that are concise, " +
|
||||
"interesting, and within Twitter's character limit. Do not include hashtags unless specifically " +
|
||||
"requested. Keep it under 280 characters.";
|
||||
|
||||
String userPrompt = prompt + " Keep it under " + MAX_TWEET_LENGTH + " characters.";
|
||||
|
||||
String jsonBody = String.format(
|
||||
"{\"contents\":[{\"parts\":[{\"text\":\"%s\\n\\n%s\"}]}],\"generationConfig\":{\"temperature\":0.8,\"maxOutputTokens\":100}}",
|
||||
escapeJson(systemInstruction),
|
||||
escapeJson(userPrompt)
|
||||
);
|
||||
|
||||
// Build the request
|
||||
Request request = new Request.Builder()
|
||||
.url(GEMINI_API_URL + "?key=" + apiKey)
|
||||
.post(RequestBody.create(jsonBody, JSON))
|
||||
.build();
|
||||
|
||||
// Execute the request
|
||||
try (Response response = httpClient.newCall(request).execute()) {
|
||||
if (!response.isSuccessful()) {
|
||||
String errorBody = response.body() != null ? response.body().string() : "No error body";
|
||||
logger.error("Gemini API request failed: {} - {}", response.code(), errorBody);
|
||||
throw new IOException("Gemini API request failed: " + response.code() + " - " + errorBody);
|
||||
}
|
||||
|
||||
String responseBody = response.body().string();
|
||||
logger.debug("Gemini API response: {}", responseBody);
|
||||
|
||||
// Parse the response
|
||||
JsonNode rootNode = objectMapper.readTree(responseBody);
|
||||
JsonNode candidates = rootNode.get("candidates");
|
||||
|
||||
if (candidates == null || candidates.isEmpty()) {
|
||||
throw new RuntimeException("No candidates in Gemini response");
|
||||
}
|
||||
|
||||
JsonNode content = candidates.get(0).get("content");
|
||||
if (content == null) {
|
||||
throw new RuntimeException("No content in Gemini response");
|
||||
}
|
||||
|
||||
JsonNode parts = content.get("parts");
|
||||
if (parts == null || parts.isEmpty()) {
|
||||
throw new RuntimeException("No parts in Gemini response");
|
||||
}
|
||||
|
||||
String generatedText = parts.get(0).get("text").asText().trim();
|
||||
|
||||
// Remove quotes if the AI wrapped the tweet in quotes
|
||||
generatedText = generatedText.replaceAll("^[\"']|[\"']$", "");
|
||||
|
||||
// Ensure it's within Twitter's character limit
|
||||
if (generatedText.length() > MAX_TWEET_LENGTH) {
|
||||
logger.warn("Generated tweet exceeds {} characters, truncating", MAX_TWEET_LENGTH);
|
||||
generatedText = generatedText.substring(0, MAX_TWEET_LENGTH - 3) + "...";
|
||||
}
|
||||
|
||||
logger.info("Generated tweet: {}", generatedText);
|
||||
return generatedText;
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Error generating tweet", e);
|
||||
throw new RuntimeException("Failed to generate tweet: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape special characters for JSON
|
||||
*/
|
||||
private String escapeJson(String text) {
|
||||
return text.replace("\\", "\\\\")
|
||||
.replace("\"", "\\\"")
|
||||
.replace("\n", "\\n")
|
||||
.replace("\r", "\\r")
|
||||
.replace("\t", "\\t");
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the Gemini service
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (httpClient != null) {
|
||||
httpClient.dispatcher().executorService().shutdown();
|
||||
httpClient.connectionPool().evictAll();
|
||||
logger.info("Gemini service shut down");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package com.voidcode.tweetbot.service;
|
||||
|
||||
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
|
||||
import com.theokanning.openai.completion.chat.ChatCompletionResult;
|
||||
import com.theokanning.openai.completion.chat.ChatMessage;
|
||||
import com.theokanning.openai.completion.chat.ChatMessageRole;
|
||||
import com.theokanning.openai.service.OpenAiService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class OpenAIService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(OpenAIService.class);
|
||||
private final OpenAiService openAiService;
|
||||
private static final int MAX_TWEET_LENGTH = 280;
|
||||
|
||||
public OpenAIService(String apiKey) {
|
||||
this.openAiService = new OpenAiService(apiKey, Duration.ofSeconds(60));
|
||||
logger.info("OpenAI service initialized");
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tweet content using ChatGPT
|
||||
* @param prompt The prompt to generate the tweet
|
||||
* @return Generated tweet text
|
||||
*/
|
||||
public String generateTweet(String prompt) {
|
||||
try {
|
||||
logger.info("Generating tweet with prompt: {}", prompt);
|
||||
|
||||
// Create the system message to set context
|
||||
ChatMessage systemMessage = new ChatMessage(
|
||||
ChatMessageRole.SYSTEM.value(),
|
||||
"You are a creative social media content creator. Generate engaging tweets that are concise, " +
|
||||
"interesting, and within Twitter's character limit. Do not include hashtags unless specifically " +
|
||||
"requested. Keep it under 280 characters."
|
||||
);
|
||||
|
||||
// Create the user message with the prompt
|
||||
ChatMessage userMessage = new ChatMessage(
|
||||
ChatMessageRole.USER.value(),
|
||||
prompt + " Keep it under " + MAX_TWEET_LENGTH + " characters."
|
||||
);
|
||||
|
||||
List<ChatMessage> messages = new ArrayList<>();
|
||||
messages.add(systemMessage);
|
||||
messages.add(userMessage);
|
||||
|
||||
// Create the chat completion request
|
||||
ChatCompletionRequest request = ChatCompletionRequest.builder()
|
||||
.model("gpt-3.5-turbo")
|
||||
.messages(messages)
|
||||
.temperature(0.8)
|
||||
.maxTokens(100)
|
||||
.build();
|
||||
|
||||
// Get the response
|
||||
ChatCompletionResult result = openAiService.createChatCompletion(request);
|
||||
String generatedText = result.getChoices().get(0).getMessage().getContent().trim();
|
||||
|
||||
// Remove quotes if the AI wrapped the tweet in quotes
|
||||
generatedText = generatedText.replaceAll("^[\"']|[\"']$", "");
|
||||
|
||||
// Ensure it's within Twitter's character limit
|
||||
if (generatedText.length() > MAX_TWEET_LENGTH) {
|
||||
logger.warn("Generated tweet exceeds {} characters, truncating", MAX_TWEET_LENGTH);
|
||||
generatedText = generatedText.substring(0, MAX_TWEET_LENGTH - 3) + "...";
|
||||
}
|
||||
|
||||
logger.info("Generated tweet: {}", generatedText);
|
||||
return generatedText;
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.error("Error generating tweet", e);
|
||||
throw new RuntimeException("Failed to generate tweet: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the OpenAI service
|
||||
*/
|
||||
public void shutdown() {
|
||||
if (openAiService != null) {
|
||||
openAiService.shutdownExecutor();
|
||||
logger.info("OpenAI service shut down");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user