Using API v2 for posting
This commit is contained in:
@@ -29,7 +29,7 @@ public class TwitterService {
|
||||
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 TWEET_CREATE_URL = "https://api.twitter.com/1.1/statuses/update.json";
|
||||
private static final String TWEET_CREATE_URL = "https://api.twitter.com/2/tweets";
|
||||
|
||||
public TwitterService(String apiKey, String apiSecret, String accessToken, String accessTokenSecret) {
|
||||
this.apiKey = apiKey;
|
||||
@@ -37,7 +37,7 @@ public class TwitterService {
|
||||
this.accessToken = accessToken;
|
||||
this.accessTokenSecret = accessTokenSecret;
|
||||
this.objectMapper = new ObjectMapper();
|
||||
logger.info("Twitter service initialized successfully with OAuth 1.0a");
|
||||
logger.info("Twitter service initialized successfully with OAuth 1.0a (using API v2 for tweets)");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,9 +59,9 @@ public class TwitterService {
|
||||
try {
|
||||
logger.info("Posting tweet: {}", tweetText);
|
||||
|
||||
// Build query parameters
|
||||
Map<String, String> params = new TreeMap<>();
|
||||
params.put("status", tweetText);
|
||||
// Build JSON request body for Twitter API v2
|
||||
ObjectNode tweetData = objectMapper.createObjectNode();
|
||||
tweetData.put("text", tweetText);
|
||||
|
||||
// Upload media if image path is provided
|
||||
if (imagePath != null && !imagePath.isEmpty()) {
|
||||
@@ -72,32 +72,35 @@ public class TwitterService {
|
||||
try {
|
||||
String mediaId = uploadMedia(imageFile);
|
||||
logger.info("Media uploaded successfully. Media ID: {}", mediaId);
|
||||
params.put("media_ids", mediaId);
|
||||
|
||||
// Add media to tweet (v2 format)
|
||||
ObjectNode media = objectMapper.createObjectNode();
|
||||
media.put("media_ids", objectMapper.createArrayNode().add(mediaId));
|
||||
tweetData.set("media", media);
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to upload media, posting tweet without image", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build URL with query parameters
|
||||
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();
|
||||
String requestBody = objectMapper.writeValueAsString(tweetData);
|
||||
logger.debug("Request body: {}", requestBody);
|
||||
|
||||
// Create OAuth header (include query params in signature)
|
||||
String authHeader = generateOAuthHeader("POST", TWEET_CREATE_URL, params);
|
||||
// Create OAuth header (no query params for v2)
|
||||
String authHeader = generateOAuthHeader("POST", TWEET_CREATE_URL, new TreeMap<>());
|
||||
|
||||
// Make HTTP request
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(fullUrl).openConnection();
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(TWEET_CREATE_URL).openConnection();
|
||||
connection.setRequestMethod("POST");
|
||||
connection.setRequestProperty("Authorization", authHeader);
|
||||
connection.setRequestProperty("Content-Length", "0");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
connection.setDoOutput(true);
|
||||
|
||||
// Send request body
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
byte[] input = requestBody.getBytes(StandardCharsets.UTF_8);
|
||||
os.write(input, 0, input.length);
|
||||
}
|
||||
|
||||
// Read response
|
||||
int responseCode = connection.getResponseCode();
|
||||
@@ -116,14 +119,14 @@ public class TwitterService {
|
||||
}
|
||||
reader.close();
|
||||
|
||||
if (responseCode != 200) {
|
||||
if (responseCode != 200 && responseCode != 201) {
|
||||
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)
|
||||
// Parse tweet ID from response (v2 format)
|
||||
JsonNode responseJson = objectMapper.readTree(response.toString());
|
||||
String tweetId = responseJson.get("id_str").asText();
|
||||
String tweetId = responseJson.get("data").get("id").asText();
|
||||
|
||||
logger.info("Tweet posted successfully. Tweet ID: {}", tweetId);
|
||||
logger.info("View tweet at: https://twitter.com/user/status/{}", tweetId);
|
||||
|
||||
Reference in New Issue
Block a user