Change from Oauth2 to Oauth1
This commit is contained in:
@@ -2,7 +2,8 @@
|
|||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(tree:*)",
|
"Bash(tree:*)",
|
||||||
"Bash(mvn clean compile:*)"
|
"Bash(mvn clean compile:*)",
|
||||||
|
"WebFetch(domain:github.com)"
|
||||||
],
|
],
|
||||||
"deny": [],
|
"deny": [],
|
||||||
"ask": []
|
"ask": []
|
||||||
|
|||||||
7
pom.xml
7
pom.xml
@@ -20,13 +20,6 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Twitter API v2 Client -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.twitter</groupId>
|
|
||||||
<artifactId>twitter-api-java-sdk</artifactId>
|
|
||||||
<version>2.0.3</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- OpenAI Java Client -->
|
<!-- OpenAI Java Client -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.theokanning.openai-gpt3-java</groupId>
|
<groupId>com.theokanning.openai-gpt3-java</groupId>
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
package com.voidcode.tweetbot.service;
|
package com.voidcode.tweetbot.service;
|
||||||
|
|
||||||
import com.twitter.clientlib.TwitterCredentialsOAuth2;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.twitter.clientlib.api.TwitterApi;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.twitter.clientlib.ApiException;
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.twitter.clientlib.model.TweetCreateRequest;
|
|
||||||
import com.twitter.clientlib.model.TweetCreateRequestMedia;
|
|
||||||
import com.twitter.clientlib.model.TweetCreateResponse;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
@@ -22,37 +18,26 @@ import javax.crypto.spec.SecretKeySpec;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
|
||||||
public class TwitterService {
|
public class TwitterService {
|
||||||
private static final Logger logger = LoggerFactory.getLogger(TwitterService.class);
|
private static final Logger logger = LoggerFactory.getLogger(TwitterService.class);
|
||||||
private final TwitterApi apiInstance;
|
|
||||||
private final String apiKey;
|
private final String apiKey;
|
||||||
private final String apiSecret;
|
private final String apiSecret;
|
||||||
private final String accessToken;
|
private final String accessToken;
|
||||||
private final String accessTokenSecret;
|
private final String accessTokenSecret;
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
private static final String MEDIA_UPLOAD_URL = "https://upload.twitter.com/1.1/media/upload.json";
|
private static final String MEDIA_UPLOAD_URL = "https://upload.twitter.com/1.1/media/upload.json";
|
||||||
|
private static final String TWEET_CREATE_URL = "https://api.twitter.com/1.1/statuses/update.json";
|
||||||
|
|
||||||
public TwitterService(String apiKey, String apiSecret, String accessToken, String accessTokenSecret) {
|
public TwitterService(String apiKey, String apiSecret, String accessToken, String accessTokenSecret) {
|
||||||
try {
|
|
||||||
this.apiKey = apiKey;
|
this.apiKey = apiKey;
|
||||||
this.apiSecret = apiSecret;
|
this.apiSecret = apiSecret;
|
||||||
this.accessToken = accessToken;
|
this.accessToken = accessToken;
|
||||||
this.accessTokenSecret = accessTokenSecret;
|
this.accessTokenSecret = accessTokenSecret;
|
||||||
|
this.objectMapper = new ObjectMapper();
|
||||||
// Initialize Twitter API with OAuth 1.0a credentials
|
logger.info("Twitter service initialized successfully with OAuth 1.0a");
|
||||||
TwitterCredentialsOAuth2 credentials = new TwitterCredentialsOAuth2(
|
|
||||||
apiKey,
|
|
||||||
apiSecret,
|
|
||||||
accessToken,
|
|
||||||
accessTokenSecret
|
|
||||||
);
|
|
||||||
|
|
||||||
apiInstance = new TwitterApi(credentials);
|
|
||||||
logger.info("Twitter service initialized successfully");
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Failed to initialize Twitter service", e);
|
|
||||||
throw new RuntimeException("Failed to initialize Twitter service: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,9 +59,9 @@ public class TwitterService {
|
|||||||
try {
|
try {
|
||||||
logger.info("Posting tweet: {}", tweetText);
|
logger.info("Posting tweet: {}", tweetText);
|
||||||
|
|
||||||
// Create the tweet request
|
// Build query parameters
|
||||||
TweetCreateRequest tweetCreateRequest = new TweetCreateRequest();
|
Map<String, String> params = new TreeMap<>();
|
||||||
tweetCreateRequest.setText(tweetText);
|
params.put("status", tweetText);
|
||||||
|
|
||||||
// Upload media if image path is provided
|
// Upload media if image path is provided
|
||||||
if (imagePath != null && !imagePath.isEmpty()) {
|
if (imagePath != null && !imagePath.isEmpty()) {
|
||||||
@@ -87,30 +72,64 @@ public class TwitterService {
|
|||||||
try {
|
try {
|
||||||
String mediaId = uploadMedia(imageFile);
|
String mediaId = uploadMedia(imageFile);
|
||||||
logger.info("Media uploaded successfully. Media ID: {}", mediaId);
|
logger.info("Media uploaded successfully. Media ID: {}", mediaId);
|
||||||
|
params.put("media_ids", mediaId);
|
||||||
// Attach media to tweet
|
|
||||||
TweetCreateRequestMedia media = new TweetCreateRequestMedia();
|
|
||||||
media.addMediaIdsItem(mediaId);
|
|
||||||
tweetCreateRequest.setMedia(media);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to upload media, posting tweet without image", e);
|
logger.error("Failed to upload media, posting tweet without image", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post the tweet
|
// Build URL with query parameters
|
||||||
TweetCreateResponse result = apiInstance.tweets().createTweet(tweetCreateRequest).execute();
|
StringBuilder urlBuilder = new StringBuilder(TWEET_CREATE_URL);
|
||||||
|
urlBuilder.append("?");
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
if (urlBuilder.charAt(urlBuilder.length() - 1) != '?') {
|
||||||
|
urlBuilder.append("&");
|
||||||
|
}
|
||||||
|
urlBuilder.append(urlEncode(entry.getKey())).append("=").append(urlEncode(entry.getValue()));
|
||||||
|
}
|
||||||
|
String fullUrl = urlBuilder.toString();
|
||||||
|
|
||||||
|
// Create OAuth header (include query params in signature)
|
||||||
|
String authHeader = generateOAuthHeader("POST", TWEET_CREATE_URL, params);
|
||||||
|
|
||||||
|
// Make HTTP request
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) new URL(fullUrl).openConnection();
|
||||||
|
connection.setRequestMethod("POST");
|
||||||
|
connection.setRequestProperty("Authorization", authHeader);
|
||||||
|
connection.setRequestProperty("Content-Length", "0");
|
||||||
|
|
||||||
|
// Read response
|
||||||
|
int responseCode = connection.getResponseCode();
|
||||||
|
|
||||||
|
BufferedReader reader;
|
||||||
|
if (responseCode >= 200 && responseCode < 300) {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
|
||||||
|
} else {
|
||||||
|
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
response.append(line);
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
|
||||||
|
if (responseCode != 200) {
|
||||||
|
logger.error("Failed to post tweet. Status code: {}, Response: {}", responseCode, response.toString());
|
||||||
|
throw new IOException("Failed to post tweet. Status code: " + responseCode + ", Response: " + response.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse tweet ID from response (v1.1 format)
|
||||||
|
JsonNode responseJson = objectMapper.readTree(response.toString());
|
||||||
|
String tweetId = responseJson.get("id_str").asText();
|
||||||
|
|
||||||
String tweetId = result.getData().getId();
|
|
||||||
logger.info("Tweet posted successfully. Tweet ID: {}", tweetId);
|
logger.info("Tweet posted successfully. Tweet ID: {}", tweetId);
|
||||||
logger.info("View tweet at: https://twitter.com/user/status/{}", tweetId);
|
logger.info("View tweet at: https://twitter.com/user/status/{}", tweetId);
|
||||||
|
|
||||||
return tweetId;
|
return tweetId;
|
||||||
|
|
||||||
} catch (ApiException e) {
|
|
||||||
logger.error("Error posting tweet. Status code: {}, Response: {}",
|
|
||||||
e.getCode(), e.getResponseBody(), e);
|
|
||||||
throw new RuntimeException("Failed to post tweet: " + e.getMessage(), e);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Unexpected error posting tweet", e);
|
logger.error("Unexpected error posting tweet", e);
|
||||||
throw new RuntimeException("Failed to post tweet: " + e.getMessage(), e);
|
throw new RuntimeException("Failed to post tweet: " + e.getMessage(), e);
|
||||||
@@ -264,10 +283,30 @@ public class TwitterService {
|
|||||||
public boolean verifyCredentials() {
|
public boolean verifyCredentials() {
|
||||||
try {
|
try {
|
||||||
logger.info("Verifying Twitter credentials...");
|
logger.info("Verifying Twitter credentials...");
|
||||||
// Try to get the authenticated user's information
|
|
||||||
apiInstance.users().findMyUser().execute();
|
String verifyUrl = "https://api.twitter.com/1.1/account/verify_credentials.json";
|
||||||
|
String authHeader = generateOAuthHeader("GET", verifyUrl, new TreeMap<>());
|
||||||
|
|
||||||
|
HttpURLConnection connection = (HttpURLConnection) new URL(verifyUrl).openConnection();
|
||||||
|
connection.setRequestMethod("GET");
|
||||||
|
connection.setRequestProperty("Authorization", authHeader);
|
||||||
|
|
||||||
|
int responseCode = connection.getResponseCode();
|
||||||
|
|
||||||
|
if (responseCode == 200) {
|
||||||
logger.info("Twitter credentials verified successfully");
|
logger.info("Twitter credentials verified successfully");
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
response.append(line);
|
||||||
|
}
|
||||||
|
reader.close();
|
||||||
|
logger.error("Failed to verify credentials. Status: {}, Response: {}", responseCode, response.toString());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("Failed to verify Twitter credentials", e);
|
logger.error("Failed to verify Twitter credentials", e);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user