0
# Favorites and Likes
1
2
Managing tweet favorites (likes) and retrieving favorite lists.
3
4
## Core Favorites Operations
5
6
### Liking and Unliking Tweets
7
8
Add and remove favorites (likes) on tweets.
9
10
```java { .api }
11
interface FavoritesResources {
12
/**
13
* Like a tweet (add to favorites)
14
* @param id Tweet ID to like
15
* @return Liked tweet status
16
*/
17
Status createFavorite(long id) throws TwitterException;
18
19
/**
20
* Unlike a tweet (remove from favorites)
21
* @param id Tweet ID to unlike
22
* @return Unliked tweet status
23
*/
24
Status destroyFavorite(long id) throws TwitterException;
25
}
26
```
27
28
**Usage Examples:**
29
30
```java
31
TwitterV1 v1 = twitter.v1();
32
33
// Like a tweet
34
Status likedTweet = v1.favorites().createFavorite(1234567890L);
35
System.out.println("Liked tweet: " + likedTweet.getText());
36
System.out.println("Total likes: " + likedTweet.getFavoriteCount());
37
38
// Unlike a tweet
39
Status unlikedTweet = v1.favorites().destroyFavorite(1234567890L);
40
System.out.println("Unliked tweet: " + unlikedTweet.getText());
41
```
42
43
### Retrieving Favorites
44
45
Get lists of liked tweets for any user.
46
47
```java { .api }
48
interface FavoritesResources {
49
/**
50
* Get authenticated user's favorite tweets
51
* @return List of favorited tweets (20 most recent)
52
*/
53
ResponseList<Status> getFavorites() throws TwitterException;
54
55
/**
56
* Get authenticated user's favorites with pagination
57
* @param paging Pagination parameters
58
* @return List of favorited tweets
59
*/
60
ResponseList<Status> getFavorites(Paging paging) throws TwitterException;
61
62
/**
63
* Get specific user's favorite tweets by user ID
64
* @param userId User ID
65
* @return List of user's favorited tweets
66
*/
67
ResponseList<Status> getFavorites(long userId) throws TwitterException;
68
69
/**
70
* Get specific user's favorites with pagination by user ID
71
* @param userId User ID
72
* @param paging Pagination parameters
73
* @return List of user's favorited tweets
74
*/
75
ResponseList<Status> getFavorites(long userId, Paging paging) throws TwitterException;
76
77
/**
78
* Get specific user's favorite tweets by screen name
79
* @param screenName User's screen name (without @)
80
* @return List of user's favorited tweets
81
*/
82
ResponseList<Status> getFavorites(String screenName) throws TwitterException;
83
84
/**
85
* Get specific user's favorites with pagination by screen name
86
* @param screenName User's screen name (without @)
87
* @param paging Pagination parameters
88
* @return List of user's favorited tweets
89
*/
90
ResponseList<Status> getFavorites(String screenName, Paging paging) throws TwitterException;
91
}
92
```
93
94
**Usage Examples:**
95
96
```java
97
// Get your own favorites
98
ResponseList<Status> myFavorites = v1.favorites().getFavorites();
99
for (Status favorite : myFavorites) {
100
System.out.println("Liked: " + favorite.getText());
101
System.out.println("By: @" + favorite.getUser().getScreenName());
102
}
103
104
// Get specific user's favorites
105
ResponseList<Status> userFavorites = v1.favorites().getFavorites("twitterapi");
106
for (Status tweet : userFavorites) {
107
System.out.println("@twitterapi liked: " + tweet.getText());
108
}
109
110
// Get favorites with pagination
111
Paging paging = Paging.ofCount(200).maxId(9876543210L);
112
ResponseList<Status> paginatedFavorites = v1.favorites().getFavorites("twitterapi", paging);
113
114
// Get all favorites for a user (with pagination)
115
List<Status> allFavorites = new ArrayList<>();
116
Paging currentPaging = Paging.ofCount(200);
117
118
while (true) {
119
ResponseList<Status> batch = v1.favorites().getFavorites("username", currentPaging);
120
if (batch.isEmpty()) break;
121
122
allFavorites.addAll(batch);
123
124
// Set up next page
125
long oldestId = batch.get(batch.size() - 1).getId();
126
currentPaging = Paging.ofCount(200).maxId(oldestId - 1);
127
128
// Rate limiting
129
RateLimitStatus rateLimit = batch.getRateLimitStatus();
130
if (rateLimit.getRemaining() <= 1) {
131
Thread.sleep(rateLimit.getSecondsUntilReset() * 1000L);
132
}
133
}
134
```
135
136
## Favorites Analysis
137
138
### Favorites Statistics
139
140
Analyze favorited content patterns.
141
142
```java
143
public class FavoritesAnalyzer {
144
private final TwitterV1 v1;
145
146
public FavoritesStats analyzeFavorites(String screenName) throws TwitterException {
147
List<Status> allFavorites = getAllFavorites(screenName);
148
149
FavoritesStats stats = new FavoritesStats();
150
stats.totalFavorites = allFavorites.size();
151
152
// Analyze by content type
153
stats.originalTweets = (int) allFavorites.stream()
154
.filter(s -> s.getRetweetedStatus() == null)
155
.count();
156
stats.retweets = stats.totalFavorites - stats.originalTweets;
157
158
// Analyze by media content
159
stats.tweetsWithMedia = (int) allFavorites.stream()
160
.filter(s -> s.getMediaEntities().length > 0)
161
.count();
162
stats.tweetsWithImages = (int) allFavorites.stream()
163
.filter(s -> Arrays.stream(s.getMediaEntities())
164
.anyMatch(media -> "photo".equals(media.getType())))
165
.count();
166
stats.tweetsWithVideo = (int) allFavorites.stream()
167
.filter(s -> Arrays.stream(s.getMediaEntities())
168
.anyMatch(media -> "video".equals(media.getType()) ||
169
"animated_gif".equals(media.getType())))
170
.count();
171
172
// Most favorited authors
173
stats.topFavoritedAuthors = allFavorites.stream()
174
.collect(Collectors.groupingBy(
175
s -> s.getUser().getScreenName(),
176
Collectors.counting()
177
))
178
.entrySet().stream()
179
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
180
.limit(10)
181
.collect(Collectors.toMap(
182
Map.Entry::getKey,
183
Map.Entry::getValue,
184
(e1, e2) -> e1,
185
LinkedHashMap::new
186
));
187
188
// Most common hashtags in favorites
189
stats.topHashtags = allFavorites.stream()
190
.flatMap(s -> Arrays.stream(s.getHashtagEntities()))
191
.collect(Collectors.groupingBy(
192
HashtagEntity::getText,
193
Collectors.counting()
194
))
195
.entrySet().stream()
196
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
197
.limit(10)
198
.collect(Collectors.toMap(
199
Map.Entry::getKey,
200
Map.Entry::getValue,
201
(e1, e2) -> e1,
202
LinkedHashMap::new
203
));
204
205
// Engagement analysis
206
stats.averageRetweetCount = allFavorites.stream()
207
.mapToInt(Status::getRetweetCount)
208
.average().orElse(0.0);
209
stats.averageFavoriteCount = allFavorites.stream()
210
.mapToInt(Status::getFavoriteCount)
211
.average().orElse(0.0);
212
213
return stats;
214
}
215
216
private List<Status> getAllFavorites(String screenName) throws TwitterException {
217
List<Status> allFavorites = new ArrayList<>();
218
Paging paging = Paging.ofCount(200);
219
220
while (allFavorites.size() < 3200) { // Twitter limit for favorites
221
ResponseList<Status> batch = v1.favorites().getFavorites(screenName, paging);
222
if (batch.isEmpty()) break;
223
224
allFavorites.addAll(batch);
225
226
// Set up next page
227
long oldestId = batch.get(batch.size() - 1).getId();
228
paging = Paging.ofCount(200).maxId(oldestId - 1);
229
230
// Rate limiting
231
RateLimitStatus rateLimit = batch.getRateLimitStatus();
232
if (rateLimit.getRemaining() <= 1) {
233
try {
234
Thread.sleep(rateLimit.getSecondsUntilReset() * 1000L);
235
} catch (InterruptedException e) {
236
Thread.currentThread().interrupt();
237
break;
238
}
239
}
240
}
241
242
return allFavorites;
243
}
244
245
public static class FavoritesStats {
246
public int totalFavorites;
247
public int originalTweets;
248
public int retweets;
249
public int tweetsWithMedia;
250
public int tweetsWithImages;
251
public int tweetsWithVideo;
252
public Map<String, Long> topFavoritedAuthors;
253
public Map<String, Long> topHashtags;
254
public double averageRetweetCount;
255
public double averageFavoriteCount;
256
}
257
}
258
```
259
260
### Favorites Management
261
262
Tools for managing large numbers of favorites.
263
264
```java
265
public class FavoritesManager {
266
private final TwitterV1 v1;
267
268
public void cleanupOldFavorites(int daysOld) throws TwitterException {
269
LocalDateTime cutoffDate = LocalDateTime.now().minusDays(daysOld);
270
ResponseList<Status> favorites = v1.favorites().getFavorites(Paging.ofCount(200));
271
272
for (Status favorite : favorites) {
273
if (favorite.getCreatedAt().isBefore(cutoffDate)) {
274
try {
275
v1.favorites().destroyFavorite(favorite.getId());
276
System.out.println("Unliked old tweet: " + favorite.getId());
277
278
Thread.sleep(1000); // Rate limiting - be conservative
279
} catch (TwitterException e) {
280
if (e.getStatusCode() == 144) {
281
// Tweet no longer exists
282
System.out.println("Tweet " + favorite.getId() + " no longer exists");
283
} else {
284
System.err.println("Error unliking tweet " + favorite.getId() + ": " + e.getMessage());
285
}
286
}
287
}
288
}
289
}
290
291
public void bulkFavoriteFromSearch(String searchQuery, int maxFavorites) throws TwitterException {
292
Query query = Query.of(searchQuery)
293
.count(100)
294
.resultType(Query.ResultType.popular);
295
296
QueryResult result = v1.search().search(query);
297
int favoritedCount = 0;
298
299
for (Status tweet : result.getTweets()) {
300
if (favoritedCount >= maxFavorites) break;
301
302
try {
303
// Don't favorite your own tweets or already favorited tweets
304
if (!tweet.isFavorited() && !tweet.getUser().getScreenName().equals(getMyScreenName())) {
305
v1.favorites().createFavorite(tweet.getId());
306
favoritedCount++;
307
System.out.println("Favorited: " + tweet.getText().substring(0, 50) + "...");
308
309
Thread.sleep(2000); // Conservative rate limiting
310
}
311
} catch (TwitterException e) {
312
if (e.getStatusCode() == 144) {
313
System.out.println("Tweet no longer exists");
314
} else if (e.getStatusCode() == 139) {
315
System.out.println("Already favorited this tweet");
316
} else {
317
System.err.println("Error favoriting tweet: " + e.getMessage());
318
}
319
}
320
}
321
}
322
323
public void exportFavorites(String screenName, String filename) throws TwitterException, IOException {
324
List<Status> favorites = getAllUserFavorites(screenName);
325
326
try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
327
writer.println("Date,Author,Tweet,URL");
328
329
for (Status favorite : favorites) {
330
String date = favorite.getCreatedAt().format(DateTimeFormatter.ISO_LOCAL_DATE);
331
String author = favorite.getUser().getScreenName();
332
String text = favorite.getText().replace(",", ";").replace("\n", " ");
333
String url = "https://twitter.com/" + author + "/status/" + favorite.getId();
334
335
writer.println(String.join(",",
336
date, author, "\"" + text + "\"", url));
337
}
338
}
339
340
System.out.println("Exported " + favorites.size() + " favorites to " + filename);
341
}
342
343
private List<Status> getAllUserFavorites(String screenName) throws TwitterException {
344
// Implementation similar to FavoritesAnalyzer.getAllFavorites()
345
// Return all favorites for the user
346
return new ArrayList<>(); // Placeholder
347
}
348
349
private String getMyScreenName() {
350
// Cache and return authenticated user's screen name
351
return "myusername"; // Placeholder
352
}
353
}
354
```
355
356
### Smart Favorites Recommendations
357
358
Find tweets similar to your existing favorites.
359
360
```java
361
public class FavoritesRecommendation {
362
private final TwitterV1 v1;
363
364
public List<Status> recommendSimilarTweets(int limit) throws TwitterException {
365
// Get recent favorites to understand preferences
366
ResponseList<Status> recentFavorites = v1.favorites().getFavorites(Paging.ofCount(100));
367
368
// Extract common hashtags and keywords from favorites
369
Set<String> favoriteHashtags = recentFavorites.stream()
370
.flatMap(s -> Arrays.stream(s.getHashtagEntities()))
371
.map(HashtagEntity::getText)
372
.collect(Collectors.toSet());
373
374
// Find authors you frequently favorite
375
Map<String, Long> favoriteAuthors = recentFavorites.stream()
376
.collect(Collectors.groupingBy(
377
s -> s.getUser().getScreenName(),
378
Collectors.counting()
379
));
380
381
List<Status> recommendations = new ArrayList<>();
382
383
// Search for tweets with similar hashtags
384
for (String hashtag : favoriteHashtags.stream().limit(5).collect(Collectors.toList())) {
385
Query query = Query.of("#" + hashtag)
386
.count(20)
387
.resultType(Query.ResultType.popular);
388
389
QueryResult result = v1.search().search(query);
390
391
// Filter out tweets you've already favorited
392
List<Status> newTweets = result.getTweets().stream()
393
.filter(tweet -> !tweet.isFavorited())
394
.filter(tweet -> !tweet.getUser().getScreenName().equals(getMyScreenName()))
395
.collect(Collectors.toList());
396
397
recommendations.addAll(newTweets);
398
399
if (recommendations.size() >= limit) break;
400
401
Thread.sleep(1000); // Rate limiting
402
}
403
404
// Search for recent tweets from frequently favorited authors
405
for (Map.Entry<String, Long> entry : favoriteAuthors.entrySet()) {
406
if (entry.getValue() >= 3) { // Authors you've favorited at least 3 times
407
try {
408
ResponseList<Status> authorTweets = v1.timelines()
409
.getUserTimeline(entry.getKey(), Paging.ofCount(10));
410
411
List<Status> unfavoritedTweets = authorTweets.stream()
412
.filter(tweet -> !tweet.isFavorited())
413
.collect(Collectors.toList());
414
415
recommendations.addAll(unfavoritedTweets);
416
417
if (recommendations.size() >= limit) break;
418
419
Thread.sleep(500);
420
} catch (TwitterException e) {
421
// Handle protected accounts or other errors
422
continue;
423
}
424
}
425
}
426
427
// Remove duplicates and return top recommendations
428
return recommendations.stream()
429
.distinct()
430
.limit(limit)
431
.collect(Collectors.toList());
432
}
433
434
private String getMyScreenName() {
435
return "myusername"; // Placeholder
436
}
437
}
438
```
439
440
## Error Handling
441
442
Common favorites operations errors and handling:
443
444
```java
445
try {
446
Status favorite = v1.favorites().createFavorite(tweetId);
447
System.out.println("Successfully liked tweet");
448
} catch (TwitterException e) {
449
switch (e.getStatusCode()) {
450
case 139:
451
System.out.println("Tweet already favorited");
452
break;
453
case 144:
454
System.out.println("Tweet not found or deleted");
455
break;
456
case 403:
457
if (e.getErrorCode() == 261) {
458
System.out.println("Cannot favorite: application write access required");
459
} else {
460
System.out.println("Forbidden: " + e.getMessage());
461
}
462
break;
463
case 429:
464
System.out.println("Rate limit exceeded");
465
int retryAfter = e.getRetryAfter();
466
System.out.println("Retry after " + retryAfter + " seconds");
467
break;
468
default:
469
System.out.println("Error: " + e.getMessage());
470
}
471
}
472
473
try {
474
ResponseList<Status> favorites = v1.favorites().getFavorites("protecteduser");
475
} catch (TwitterException e) {
476
if (e.getStatusCode() == 401) {
477
System.out.println("User's favorites are protected");
478
} else if (e.getStatusCode() == 404) {
479
System.out.println("User not found");
480
}
481
}
482
```