Browse Source
Convert some web repo and service classes to kotlin
renovate/org.robolectric-robolectric-4.x
Convert some web repo and service classes to kotlin
renovate/org.robolectric-robolectric-4.x
Ammar Githam
4 years ago
18 changed files with 630 additions and 638 deletions
-
11app/src/main/java/awais/instagrabber/activities/MainActivity.kt
-
179app/src/main/java/awais/instagrabber/repositories/DirectMessagesRepository.kt
-
2app/src/main/java/awais/instagrabber/webservices/CollectionService.java
-
939app/src/main/java/awais/instagrabber/webservices/DirectMessagesService.kt
-
2app/src/main/java/awais/instagrabber/webservices/DiscoverService.java
-
2app/src/main/java/awais/instagrabber/webservices/FeedService.java
-
2app/src/main/java/awais/instagrabber/webservices/FriendshipService.java
-
2app/src/main/java/awais/instagrabber/webservices/GifService.java
-
2app/src/main/java/awais/instagrabber/webservices/GraphQLService.java
-
2app/src/main/java/awais/instagrabber/webservices/LocationService.java
-
2app/src/main/java/awais/instagrabber/webservices/MediaService.java
-
2app/src/main/java/awais/instagrabber/webservices/NewsService.java
-
2app/src/main/java/awais/instagrabber/webservices/ProfileService.java
-
133app/src/main/java/awais/instagrabber/webservices/RetrofitFactory.kt
-
2app/src/main/java/awais/instagrabber/webservices/SearchService.java
-
2app/src/main/java/awais/instagrabber/webservices/StoriesService.java
-
2app/src/main/java/awais/instagrabber/webservices/TagsService.java
-
2app/src/main/java/awais/instagrabber/webservices/UserService.java
@ -1,155 +1,182 @@ |
|||
package awais.instagrabber.repositories; |
|||
|
|||
import java.util.Map; |
|||
|
|||
import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectItemSeenResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadDetailsChangeResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse; |
|||
import retrofit2.Call; |
|||
import retrofit2.http.FieldMap; |
|||
import retrofit2.http.FormUrlEncoded; |
|||
import retrofit2.http.GET; |
|||
import retrofit2.http.POST; |
|||
import retrofit2.http.Path; |
|||
import retrofit2.http.Query; |
|||
import retrofit2.http.QueryMap; |
|||
|
|||
public interface DirectMessagesRepository { |
|||
package awais.instagrabber.repositories |
|||
|
|||
import awais.instagrabber.repositories.responses.directmessages.* |
|||
import retrofit2.Call |
|||
import retrofit2.http.* |
|||
|
|||
interface DirectMessagesRepository { |
|||
@GET("/api/v1/direct_v2/inbox/") |
|||
Call<DirectInboxResponse> fetchInbox(@QueryMap Map<String, Object> queryMap); |
|||
fun fetchInbox(@QueryMap queryMap: Map<String, String>): Call<DirectInboxResponse?> |
|||
|
|||
@GET("/api/v1/direct_v2/pending_inbox/") |
|||
Call<DirectInboxResponse> fetchPendingInbox(@QueryMap Map<String, Object> queryMap); |
|||
fun fetchPendingInbox(@QueryMap queryMap: Map<String, String>): Call<DirectInboxResponse?> |
|||
|
|||
@GET("/api/v1/direct_v2/threads/{threadId}/") |
|||
Call<DirectThreadFeedResponse> fetchThread(@Path("threadId") String threadId, |
|||
@QueryMap Map<String, Object> queryMap); |
|||
fun fetchThread( |
|||
@Path("threadId") threadId: String, |
|||
@QueryMap queryMap: Map<String, String>, |
|||
): Call<DirectThreadFeedResponse?> |
|||
|
|||
@GET("/api/v1/direct_v2/get_badge_count/?no_raven=1") |
|||
Call<DirectBadgeCount> fetchUnseenCount(); |
|||
fun fetchUnseenCount(): Call<DirectBadgeCount?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/broadcast/{item}/") |
|||
Call<DirectThreadBroadcastResponse> broadcast(@Path("item") String item, |
|||
@FieldMap final Map<String, String> signedForm); |
|||
fun broadcast( |
|||
@Path("item") item: String, |
|||
@FieldMap signedForm: Map<String, String>, |
|||
): Call<DirectThreadBroadcastResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/add_user/") |
|||
Call<DirectThreadDetailsChangeResponse> addUsers(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun addUsers( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/remove_users/") |
|||
Call<String> removeUsers(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun removeUsers( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/update_title/") |
|||
Call<DirectThreadDetailsChangeResponse> updateTitle(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun updateTitle( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/add_admins/") |
|||
Call<String> addAdmins(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun addAdmins( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/remove_admins/") |
|||
Call<String> removeAdmins(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun removeAdmins( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/items/{itemId}/delete/") |
|||
Call<String> deleteItem(@Path("threadId") String threadId, |
|||
@Path("itemId") String itemId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun deleteItem( |
|||
@Path("threadId") threadId: String, |
|||
@Path("itemId") itemId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@GET("/api/v1/direct_v2/ranked_recipients/") |
|||
Call<RankedRecipientsResponse> rankedRecipients(@QueryMap Map<String, String> queryMap); |
|||
fun rankedRecipients(@QueryMap queryMap: Map<String, String>): Call<RankedRecipientsResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/broadcast/forward/") |
|||
Call<DirectThreadBroadcastResponse> forward(@FieldMap final Map<String, String> form); |
|||
fun forward(@FieldMap form: Map<String, String>): Call<DirectThreadBroadcastResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/create_group_thread/") |
|||
Call<DirectThread> createThread(@FieldMap final Map<String, String> signedForm); |
|||
fun createThread(@FieldMap signedForm: Map<String, String>): Call<DirectThread?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/mute/") |
|||
Call<String> mute(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun mute( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/unmute/") |
|||
Call<String> unmute(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun unmute( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/mute_mentions/") |
|||
Call<String> muteMentions(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun muteMentions( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String?>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/unmute_mentions/") |
|||
Call<String> unmuteMentions(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun unmuteMentions( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@GET("/api/v1/direct_v2/threads/{threadId}/participant_requests/") |
|||
Call<DirectThreadParticipantRequestsResponse> participantRequests(@Path("threadId") String threadId, |
|||
@Query("page_size") int pageSize, |
|||
@Query("cursor") String cursor); |
|||
fun participantRequests( |
|||
@Path("threadId") threadId: String, |
|||
@Query("page_size") pageSize: Int, |
|||
@Query("cursor") cursor: String?, |
|||
): Call<DirectThreadParticipantRequestsResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/approve_participant_requests/") |
|||
Call<DirectThreadDetailsChangeResponse> approveParticipantRequests(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun approveParticipantRequests( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/deny_participant_requests/") |
|||
Call<DirectThreadDetailsChangeResponse> declineParticipantRequests(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun declineParticipantRequests( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/approval_required_for_new_members/") |
|||
Call<DirectThreadDetailsChangeResponse> approvalRequired(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun approvalRequired( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/approval_not_required_for_new_members/") |
|||
Call<DirectThreadDetailsChangeResponse> approvalNotRequired(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun approvalNotRequired( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/leave/") |
|||
Call<DirectThreadDetailsChangeResponse> leave(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun leave( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/remove_all_users/") |
|||
Call<DirectThreadDetailsChangeResponse> end(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun end( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectThreadDetailsChangeResponse?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/approve/") |
|||
Call<String> approveRequest(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun approveRequest( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/decline/") |
|||
Call<String> declineRequest(@Path("threadId") String threadId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun declineRequest( |
|||
@Path("threadId") threadId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<String?> |
|||
|
|||
@FormUrlEncoded |
|||
@POST("/api/v1/direct_v2/threads/{threadId}/items/{itemId}/seen/") |
|||
Call<DirectItemSeenResponse> markItemSeen(@Path("threadId") String threadId, |
|||
@Path("itemId") String itemId, |
|||
@FieldMap final Map<String, String> form); |
|||
fun markItemSeen( |
|||
@Path("threadId") threadId: String, |
|||
@Path("itemId") itemId: String, |
|||
@FieldMap form: Map<String, String>, |
|||
): Call<DirectItemSeenResponse?> |
|||
} |
@ -1,476 +1,483 @@ |
|||
package awais.instagrabber.webservices; |
|||
|
|||
import androidx.annotation.NonNull; |
|||
import androidx.annotation.Nullable; |
|||
|
|||
import com.google.common.collect.ImmutableMap; |
|||
|
|||
import org.json.JSONArray; |
|||
|
|||
import java.util.Collection; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.Objects; |
|||
import java.util.UUID; |
|||
import java.util.stream.Collectors; |
|||
|
|||
import awais.instagrabber.repositories.DirectMessagesRepository; |
|||
import awais.instagrabber.repositories.requests.directmessages.AnimatedMediaBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.BroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.LinkBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.MediaShareBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.PhotoBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.ReactionBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.StoryReplyBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.TextBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.ThreadIdOrUserIds; |
|||
import awais.instagrabber.repositories.requests.directmessages.VideoBroadcastOptions; |
|||
import awais.instagrabber.repositories.requests.directmessages.VoiceBroadcastOptions; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectBadgeCount; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectInboxResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectItem; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectItemSeenResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThread; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadBroadcastResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadDetailsChangeResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadFeedResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.DirectThreadParticipantRequestsResponse; |
|||
import awais.instagrabber.repositories.responses.directmessages.RankedRecipientsResponse; |
|||
import awais.instagrabber.repositories.responses.giphy.GiphyGif; |
|||
import awais.instagrabber.utils.TextUtils; |
|||
import awais.instagrabber.utils.Utils; |
|||
import retrofit2.Call; |
|||
|
|||
public class DirectMessagesService extends BaseService { |
|||
private static final String TAG = "DiscoverService"; |
|||
|
|||
private static DirectMessagesService instance; |
|||
|
|||
private final DirectMessagesRepository repository; |
|||
private final String csrfToken; |
|||
private final long userId; |
|||
private final String deviceUuid; |
|||
|
|||
private DirectMessagesService(@NonNull final String csrfToken, |
|||
final long userId, |
|||
@NonNull final String deviceUuid) { |
|||
this.csrfToken = csrfToken; |
|||
this.userId = userId; |
|||
this.deviceUuid = deviceUuid; |
|||
repository = RetrofitFactory.getInstance() |
|||
.getRetrofit() |
|||
.create(DirectMessagesRepository.class); |
|||
} |
|||
|
|||
public String getCsrfToken() { |
|||
return csrfToken; |
|||
} |
|||
|
|||
public long getUserId() { |
|||
return userId; |
|||
} |
|||
|
|||
public String getDeviceUuid() { |
|||
return deviceUuid; |
|||
} |
|||
|
|||
public static DirectMessagesService getInstance(@NonNull final String csrfToken, |
|||
final long userId, |
|||
@NonNull final String deviceUuid) { |
|||
if (instance == null |
|||
|| !Objects.equals(instance.getCsrfToken(), csrfToken) |
|||
|| !Objects.equals(instance.getUserId(), userId) |
|||
|| !Objects.equals(instance.getDeviceUuid(), deviceUuid)) { |
|||
instance = new DirectMessagesService(csrfToken, userId, deviceUuid); |
|||
} |
|||
return instance; |
|||
} |
|||
|
|||
public Call<DirectInboxResponse> fetchInbox(final String cursor, |
|||
final long seqId) { |
|||
final ImmutableMap.Builder<String, Object> queryMapBuilder = ImmutableMap.<String, Object>builder() |
|||
.put("visual_message_return_type", "unseen") |
|||
.put("thread_message_limit", 10) |
|||
.put("persistentBadging", true) |
|||
.put("limit", 10); |
|||
if (!TextUtils.isEmpty(cursor)) { |
|||
queryMapBuilder.put("cursor", cursor); |
|||
queryMapBuilder.put("direction", "older"); |
|||
} |
|||
if (seqId != 0) { |
|||
queryMapBuilder.put("seq_id", seqId); |
|||
} |
|||
return repository.fetchInbox(queryMapBuilder.build()); |
|||
} |
|||
|
|||
public Call<DirectThreadFeedResponse> fetchThread(final String threadId, |
|||
final String cursor) { |
|||
final ImmutableMap.Builder<String, Object> queryMapBuilder = ImmutableMap.<String, Object>builder() |
|||
.put("visual_message_return_type", "unseen") |
|||
.put("limit", 20) |
|||
.put("direction", "older"); |
|||
if (!TextUtils.isEmpty(cursor)) { |
|||
queryMapBuilder.put("cursor", cursor); |
|||
} |
|||
return repository.fetchThread(threadId, queryMapBuilder.build()); |
|||
} |
|||
|
|||
public Call<DirectBadgeCount> fetchUnseenCount() { |
|||
return repository.fetchUnseenCount(); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastText(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String text, |
|||
@Nullable final String repliedToItemId, |
|||
@Nullable final String repliedToClientContext) { |
|||
final List<String> urls = TextUtils.extractUrls(text); |
|||
if (!urls.isEmpty()) { |
|||
return broadcastLink(clientContext, threadIdOrUserIds, text, urls, repliedToItemId, repliedToClientContext); |
|||
} |
|||
final TextBroadcastOptions broadcastOptions = new TextBroadcastOptions(clientContext, threadIdOrUserIds, text); |
|||
if (repliedToItemId != null && repliedToClientContext != null) { |
|||
broadcastOptions.setRepliedToItemId(repliedToItemId); |
|||
broadcastOptions.setRepliedToClientContext(repliedToClientContext); |
|||
} |
|||
return broadcast(broadcastOptions); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastLink(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String linkText, |
|||
@NonNull final List<String> urls, |
|||
@Nullable final String repliedToItemId, |
|||
@Nullable final String repliedToClientContext) { |
|||
final LinkBroadcastOptions broadcastOptions = new LinkBroadcastOptions(clientContext, threadIdOrUserIds, linkText, urls); |
|||
if (repliedToItemId != null && repliedToClientContext != null) { |
|||
broadcastOptions.setRepliedToItemId(repliedToItemId); |
|||
broadcastOptions.setRepliedToClientContext(repliedToClientContext); |
|||
} |
|||
return broadcast(broadcastOptions); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastPhoto(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String uploadId) { |
|||
return broadcast(new PhotoBroadcastOptions(clientContext, threadIdOrUserIds, true, uploadId)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastVideo(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String uploadId, |
|||
@NonNull final String videoResult, |
|||
final boolean sampled) { |
|||
return broadcast(new VideoBroadcastOptions(clientContext, threadIdOrUserIds, videoResult, uploadId, sampled)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastVoice(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String uploadId, |
|||
@NonNull final List<Float> waveform, |
|||
final int samplingFreq) { |
|||
return broadcast(new VoiceBroadcastOptions(clientContext, threadIdOrUserIds, uploadId, waveform, samplingFreq)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastStoryReply(@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String text, |
|||
@NonNull final String mediaId, |
|||
@NonNull final String reelId) { |
|||
return broadcast(new StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdOrUserIds, text, mediaId, reelId)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastReaction(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String itemId, |
|||
@Nullable final String emoji, |
|||
final boolean delete) { |
|||
return broadcast(new ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastAnimatedMedia(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final GiphyGif giphyGif) { |
|||
return broadcast(new AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif)); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> broadcastMediaShare(@NonNull final String clientContext, |
|||
@NonNull final ThreadIdOrUserIds threadIdOrUserIds, |
|||
@NonNull final String mediaId) { |
|||
return broadcast(new MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId)); |
|||
} |
|||
|
|||
private Call<DirectThreadBroadcastResponse> broadcast(@NonNull final BroadcastOptions broadcastOptions) { |
|||
if (TextUtils.isEmpty(broadcastOptions.getClientContext())) { |
|||
throw new IllegalArgumentException("Broadcast requires a valid client context value"); |
|||
} |
|||
final Map<String, Object> form = new HashMap<>(); |
|||
if (!TextUtils.isEmpty(broadcastOptions.getThreadId())) { |
|||
form.put("thread_id", broadcastOptions.getThreadId()); |
|||
package awais.instagrabber.webservices |
|||
|
|||
import awais.instagrabber.repositories.DirectMessagesRepository |
|||
import awais.instagrabber.repositories.requests.directmessages.* |
|||
import awais.instagrabber.repositories.responses.directmessages.* |
|||
import awais.instagrabber.repositories.responses.giphy.GiphyGif |
|||
import awais.instagrabber.utils.TextUtils.extractUrls |
|||
import awais.instagrabber.utils.TextUtils.isEmpty |
|||
import awais.instagrabber.utils.Utils |
|||
import org.json.JSONArray |
|||
import retrofit2.Call |
|||
import java.util.* |
|||
|
|||
class DirectMessagesService private constructor( |
|||
val csrfToken: String, |
|||
val userId: Long, |
|||
val deviceUuid: String, |
|||
) : BaseService() { |
|||
private val repository: DirectMessagesRepository = RetrofitFactory.retrofit.create(DirectMessagesRepository::class.java) |
|||
|
|||
fun fetchInbox( |
|||
cursor: String?, |
|||
seqId: Long, |
|||
): Call<DirectInboxResponse?> { |
|||
val queryMap = mutableMapOf( |
|||
"visual_message_return_type" to "unseen", |
|||
"thread_message_limit" to 10.toString(), |
|||
"persistentBadging" to true.toString(), |
|||
"limit" to 10.toString(), |
|||
) |
|||
if (!cursor.isNullOrBlank()) { |
|||
queryMap["cursor"] = cursor |
|||
queryMap["direction"] = "older" |
|||
} |
|||
if (seqId != 0L) { |
|||
queryMap["seq_id"] = seqId.toString() |
|||
} |
|||
return repository.fetchInbox(queryMap) |
|||
} |
|||
|
|||
fun fetchThread( |
|||
threadId: String, |
|||
cursor: String?, |
|||
): Call<DirectThreadFeedResponse?> { |
|||
val queryMap = mutableMapOf( |
|||
"visual_message_return_type" to "unseen", |
|||
"limit" to 20.toString(), |
|||
"direction" to "older", |
|||
) |
|||
if (!cursor.isNullOrBlank()) { |
|||
queryMap["cursor"] = cursor |
|||
} |
|||
return repository.fetchThread(threadId, queryMap) |
|||
} |
|||
|
|||
fun fetchUnseenCount(): Call<DirectBadgeCount?> { |
|||
return repository.fetchUnseenCount() |
|||
} |
|||
|
|||
fun broadcastText( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
text: String, |
|||
repliedToItemId: String?, |
|||
repliedToClientContext: String?, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
val urls = extractUrls(text) |
|||
if (urls.isNotEmpty()) { |
|||
return broadcastLink(clientContext, threadIdOrUserIds, text, urls, repliedToItemId, repliedToClientContext) |
|||
} |
|||
val broadcastOptions = TextBroadcastOptions(clientContext, threadIdOrUserIds, text) |
|||
if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { |
|||
broadcastOptions.repliedToItemId = repliedToItemId |
|||
broadcastOptions.repliedToClientContext = repliedToClientContext |
|||
} |
|||
return broadcast(broadcastOptions) |
|||
} |
|||
|
|||
private fun broadcastLink( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
linkText: String, |
|||
urls: List<String>, |
|||
repliedToItemId: String?, |
|||
repliedToClientContext: String?, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
val broadcastOptions = LinkBroadcastOptions(clientContext, threadIdOrUserIds, linkText, urls) |
|||
if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { |
|||
broadcastOptions.repliedToItemId = repliedToItemId |
|||
broadcastOptions.repliedToClientContext = repliedToClientContext |
|||
} |
|||
return broadcast(broadcastOptions) |
|||
} |
|||
|
|||
fun broadcastPhoto( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
uploadId: String, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(PhotoBroadcastOptions(clientContext, threadIdOrUserIds, true, uploadId)) |
|||
} |
|||
|
|||
fun broadcastVideo( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
uploadId: String, |
|||
videoResult: String, |
|||
sampled: Boolean, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(VideoBroadcastOptions(clientContext, threadIdOrUserIds, videoResult, uploadId, sampled)) |
|||
} |
|||
|
|||
fun broadcastVoice( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
uploadId: String, |
|||
waveform: List<Float>, |
|||
samplingFreq: Int, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(VoiceBroadcastOptions(clientContext, threadIdOrUserIds, uploadId, waveform, samplingFreq)) |
|||
} |
|||
|
|||
fun broadcastStoryReply( |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
text: String, |
|||
mediaId: String, |
|||
reelId: String, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(StoryReplyBroadcastOptions(UUID.randomUUID().toString(), threadIdOrUserIds, text, mediaId, reelId)) |
|||
} |
|||
|
|||
fun broadcastReaction( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
itemId: String, |
|||
emoji: String?, |
|||
delete: Boolean, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(ReactionBroadcastOptions(clientContext, threadIdOrUserIds, itemId, emoji, delete)) |
|||
} |
|||
|
|||
fun broadcastAnimatedMedia( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
giphyGif: GiphyGif, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(AnimatedMediaBroadcastOptions(clientContext, threadIdOrUserIds, giphyGif)) |
|||
} |
|||
|
|||
fun broadcastMediaShare( |
|||
clientContext: String, |
|||
threadIdOrUserIds: ThreadIdOrUserIds, |
|||
mediaId: String, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
return broadcast(MediaShareBroadcastOptions(clientContext, threadIdOrUserIds, mediaId)) |
|||
} |
|||
|
|||
private fun broadcast(broadcastOptions: BroadcastOptions): Call<DirectThreadBroadcastResponse?> { |
|||
require(!isEmpty(broadcastOptions.clientContext)) { "Broadcast requires a valid client context value" } |
|||
val form = mutableMapOf<String, Any>() |
|||
val threadId = broadcastOptions.threadId |
|||
if (!threadId.isNullOrBlank()) { |
|||
form["thread_id"] = threadId |
|||
} else { |
|||
form.put("recipient_users", new JSONArray(broadcastOptions.getUserIds()).toString()); |
|||
} |
|||
form.put("_csrftoken", csrfToken); |
|||
form.put("_uid", userId); |
|||
form.put("__uuid", deviceUuid); |
|||
form.put("client_context", broadcastOptions.getClientContext()); |
|||
form.put("mutation_token", broadcastOptions.getClientContext()); |
|||
if (!TextUtils.isEmpty(broadcastOptions.getRepliedToItemId()) && !TextUtils.isEmpty(broadcastOptions.getRepliedToClientContext())) { |
|||
form.put("replied_to_item_id", broadcastOptions.getRepliedToItemId()); |
|||
form.put("replied_to_client_context", broadcastOptions.getRepliedToClientContext()); |
|||
} |
|||
form.putAll(broadcastOptions.getFormMap()); |
|||
form.put("action", "send_item"); |
|||
final Map<String, String> signedForm = Utils.sign(form); |
|||
return repository.broadcast(broadcastOptions.getItemType().getValue(), signedForm); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> addUsers(final String threadId, |
|||
final Collection<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
); |
|||
return repository.addUsers(threadId, form); |
|||
} |
|||
|
|||
public Call<String> removeUsers(final String threadId, |
|||
final Collection<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
); |
|||
return repository.removeUsers(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> updateTitle(final String threadId, |
|||
final String title) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"title", title |
|||
); |
|||
return repository.updateTitle(threadId, form); |
|||
} |
|||
|
|||
public Call<String> addAdmins(final String threadId, |
|||
final Collection<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
); |
|||
return repository.addAdmins(threadId, form); |
|||
} |
|||
|
|||
public Call<String> removeAdmins(final String threadId, |
|||
final Collection<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
); |
|||
return repository.removeAdmins(threadId, form); |
|||
} |
|||
|
|||
public Call<String> deleteItem(final String threadId, |
|||
final String itemId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.deleteItem(threadId, itemId, form); |
|||
} |
|||
|
|||
public Call<RankedRecipientsResponse> rankedRecipients(@Nullable final String mode, |
|||
@Nullable final Boolean showThreads, |
|||
@Nullable final String query) { |
|||
val userIds = broadcastOptions.userIds |
|||
require(!userIds.isNullOrEmpty()) { |
|||
"Either provide a thread id or pass a list of user ids" |
|||
} |
|||
form["recipient_users"] = JSONArray(userIds).toString() |
|||
} |
|||
form["_csrftoken"] = csrfToken |
|||
form["_uid"] = userId |
|||
form["__uuid"] = deviceUuid |
|||
form["client_context"] = broadcastOptions.clientContext |
|||
form["mutation_token"] = broadcastOptions.clientContext |
|||
val repliedToItemId = broadcastOptions.repliedToItemId |
|||
val repliedToClientContext = broadcastOptions.repliedToClientContext |
|||
if (!repliedToItemId.isNullOrBlank() && !repliedToClientContext.isNullOrBlank()) { |
|||
form["replied_to_item_id"] = repliedToItemId |
|||
form["replied_to_client_context"] = repliedToClientContext |
|||
} |
|||
form.putAll(broadcastOptions.formMap) |
|||
form["action"] = "send_item" |
|||
val signedForm = Utils.sign(form) |
|||
return repository.broadcast(broadcastOptions.itemType.value, signedForm) |
|||
} |
|||
|
|||
fun addUsers( |
|||
threadId: String, |
|||
userIds: Collection<Long>, |
|||
): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
) |
|||
return repository.addUsers(threadId, form) |
|||
} |
|||
|
|||
fun removeUsers( |
|||
threadId: String, |
|||
userIds: Collection<Long>, |
|||
): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
) |
|||
return repository.removeUsers(threadId, form) |
|||
} |
|||
|
|||
fun updateTitle( |
|||
threadId: String, |
|||
title: String, |
|||
): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"title" to title, |
|||
) |
|||
return repository.updateTitle(threadId, form) |
|||
} |
|||
|
|||
fun addAdmins( |
|||
threadId: String, |
|||
userIds: Collection<Long>, |
|||
): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
) |
|||
return repository.addAdmins(threadId, form) |
|||
} |
|||
|
|||
fun removeAdmins( |
|||
threadId: String, |
|||
userIds: Collection<Long>, |
|||
): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
) |
|||
return repository.removeAdmins(threadId, form) |
|||
} |
|||
|
|||
fun deleteItem( |
|||
threadId: String, |
|||
itemId: String, |
|||
): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.deleteItem(threadId, itemId, form) |
|||
} |
|||
|
|||
fun rankedRecipients( |
|||
mode: String?, |
|||
showThreads: Boolean?, |
|||
query: String?, |
|||
): Call<RankedRecipientsResponse?> { |
|||
// String correctedMode = mode; |
|||
// if (TextUtils.isEmpty(mode) || (!mode.equals("raven") && !mode.equals("reshare"))) { |
|||
// correctedMode = "raven"; |
|||
// } |
|||
final ImmutableMap.Builder<String, String> builder = ImmutableMap.builder(); |
|||
if (mode != null) { |
|||
builder.put("mode", mode); |
|||
val queryMap = mutableMapOf<String, String>() |
|||
if (!mode.isNullOrBlank()) { |
|||
queryMap["mode"] = mode |
|||
} |
|||
if (query != null) { |
|||
builder.put("query", query); |
|||
if (!query.isNullOrBlank()) { |
|||
queryMap["query"] = query |
|||
} |
|||
if (showThreads != null) { |
|||
builder.put("showThreads", String.valueOf(showThreads)); |
|||
} |
|||
return repository.rankedRecipients(builder.build()); |
|||
} |
|||
|
|||
public Call<DirectThreadBroadcastResponse> forward(@NonNull final String toThreadId, |
|||
@NonNull final String itemType, |
|||
@NonNull final String fromThreadId, |
|||
@NonNull final String itemId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"action", "forward_item", |
|||
"thread_id", toThreadId, |
|||
"item_type", itemType, |
|||
"forwarded_from_thread_id", fromThreadId, |
|||
"forwarded_from_thread_item_id", itemId |
|||
); |
|||
return repository.forward(form); |
|||
} |
|||
|
|||
public Call<DirectThread> createThread(@NonNull final List<Long> userIds, |
|||
@Nullable final String threadTitle) { |
|||
final List<String> userIdStringList = userIds.stream() |
|||
.filter(Objects::nonNull) |
|||
.map(String::valueOf) |
|||
.collect(Collectors.toList()); |
|||
final ImmutableMap.Builder<String, Object> formBuilder = ImmutableMap.<String, Object>builder() |
|||
.put("_csrftoken", csrfToken) |
|||
.put("_uuid", deviceUuid) |
|||
.put("_uid", userId) |
|||
.put("recipient_users", new JSONArray(userIdStringList).toString()); |
|||
if (threadTitle != null) { |
|||
formBuilder.put("thread_title", threadTitle); |
|||
} |
|||
final Map<String, String> signedForm = Utils.sign(formBuilder.build()); |
|||
return repository.createThread(signedForm); |
|||
} |
|||
|
|||
public Call<String> mute(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.mute(threadId, form); |
|||
} |
|||
|
|||
public Call<String> unmute(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.unmute(threadId, form); |
|||
} |
|||
|
|||
public Call<String> muteMentions(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.muteMentions(threadId, form); |
|||
} |
|||
|
|||
public Call<String> unmuteMentions(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.unmuteMentions(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadParticipantRequestsResponse> participantRequests(@NonNull final String threadId, |
|||
final int pageSize, |
|||
@Nullable final String cursor) { |
|||
return repository.participantRequests(threadId, pageSize, cursor); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> approveParticipantRequests(@NonNull final String threadId, |
|||
@NonNull final List<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
// , "share_join_chat_story", String.valueOf(true) |
|||
); |
|||
return repository.approveParticipantRequests(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> declineParticipantRequests(@NonNull final String threadId, |
|||
@NonNull final List<Long> userIds) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid, |
|||
"user_ids", new JSONArray(userIds).toString() |
|||
); |
|||
return repository.declineParticipantRequests(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> approvalRequired(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.approvalRequired(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> approvalNotRequired(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.approvalNotRequired(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> leave(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.leave(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectThreadDetailsChangeResponse> end(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.end(threadId, form); |
|||
} |
|||
|
|||
public Call<DirectInboxResponse> fetchPendingInbox(final String cursor, final long seqId) { |
|||
final ImmutableMap.Builder<String, Object> queryMapBuilder = ImmutableMap.<String, Object>builder() |
|||
.put("visual_message_return_type", "unseen") |
|||
.put("thread_message_limit", 20) |
|||
.put("persistentBadging", true) |
|||
.put("limit", 10); |
|||
if (!TextUtils.isEmpty(cursor)) { |
|||
queryMapBuilder.put("cursor", cursor); |
|||
queryMapBuilder.put("direction", "older"); |
|||
} |
|||
if (seqId != 0) { |
|||
queryMapBuilder.put("seq_id", seqId); |
|||
} |
|||
return repository.fetchPendingInbox(queryMapBuilder.build()); |
|||
} |
|||
|
|||
public Call<String> approveRequest(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.approveRequest(threadId, form); |
|||
} |
|||
|
|||
public Call<String> declineRequest(@NonNull final String threadId) { |
|||
final ImmutableMap<String, String> form = ImmutableMap.of( |
|||
"_csrftoken", csrfToken, |
|||
"_uuid", deviceUuid |
|||
); |
|||
return repository.declineRequest(threadId, form); |
|||
} |
|||
|
|||
@Nullable |
|||
public Call<DirectItemSeenResponse> markAsSeen(@NonNull final String threadId, |
|||
@NonNull final DirectItem directItem) { |
|||
if (directItem.getItemId() == null) return null; |
|||
final ImmutableMap<String, String> form = ImmutableMap.<String, String>builder() |
|||
.put("_csrftoken", csrfToken) |
|||
.put("_uuid", deviceUuid) |
|||
.put("use_unified_inbox", "true") |
|||
.put("action", "mark_seen") |
|||
.put("thread_id", threadId) |
|||
.put("item_id", directItem.getItemId()) |
|||
.build(); |
|||
return repository.markItemSeen(threadId, directItem.getItemId(), form); |
|||
queryMap["showThreads"] = showThreads.toString() |
|||
} |
|||
return repository.rankedRecipients(queryMap) |
|||
} |
|||
|
|||
fun forward( |
|||
toThreadId: String, |
|||
itemType: String, |
|||
fromThreadId: String, |
|||
itemId: String, |
|||
): Call<DirectThreadBroadcastResponse?> { |
|||
val form = mapOf( |
|||
"action" to "forward_item", |
|||
"thread_id" to toThreadId, |
|||
"item_type" to itemType, |
|||
"forwarded_from_thread_id" to fromThreadId, |
|||
"forwarded_from_thread_item_id" to itemId, |
|||
) |
|||
return repository.forward(form) |
|||
} |
|||
|
|||
fun createThread( |
|||
userIds: List<Long>, |
|||
threadTitle: String?, |
|||
): Call<DirectThread?> { |
|||
val userIdStringList = userIds.asSequence() |
|||
.filterNotNull() |
|||
.map { it.toString() } |
|||
val form = mutableMapOf<String, Any>( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"_uid" to userId, |
|||
"recipient_users" to JSONArray(userIdStringList).toString(), |
|||
) |
|||
if (!threadTitle.isNullOrBlank()) { |
|||
form["thread_title"] = threadTitle |
|||
} |
|||
val signedForm = Utils.sign(form) |
|||
return repository.createThread(signedForm) |
|||
} |
|||
|
|||
fun mute(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid |
|||
) |
|||
return repository.mute(threadId, form) |
|||
} |
|||
|
|||
fun unmute(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.unmute(threadId, form) |
|||
} |
|||
|
|||
fun muteMentions(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.muteMentions(threadId, form) |
|||
} |
|||
|
|||
fun unmuteMentions(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.unmuteMentions(threadId, form) |
|||
} |
|||
|
|||
fun participantRequests( |
|||
threadId: String, |
|||
pageSize: Int, |
|||
cursor: String?, |
|||
): Call<DirectThreadParticipantRequestsResponse?> { |
|||
return repository.participantRequests(threadId, pageSize, cursor) |
|||
} |
|||
|
|||
fun approveParticipantRequests( |
|||
threadId: String, |
|||
userIds: List<Long>, |
|||
): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
// "share_join_chat_story" to String.valueOf(true) |
|||
) |
|||
return repository.approveParticipantRequests(threadId, form) |
|||
} |
|||
|
|||
fun declineParticipantRequests( |
|||
threadId: String, |
|||
userIds: List<Long>, |
|||
): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"user_ids" to JSONArray(userIds).toString(), |
|||
) |
|||
return repository.declineParticipantRequests(threadId, form) |
|||
} |
|||
|
|||
fun approvalRequired(threadId: String): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.approvalRequired(threadId, form) |
|||
} |
|||
|
|||
fun approvalNotRequired(threadId: String): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.approvalNotRequired(threadId, form) |
|||
} |
|||
|
|||
fun leave(threadId: String): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.leave(threadId, form) |
|||
} |
|||
|
|||
fun end(threadId: String): Call<DirectThreadDetailsChangeResponse?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.end(threadId, form) |
|||
} |
|||
|
|||
fun fetchPendingInbox(cursor: String?, seqId: Long): Call<DirectInboxResponse?> { |
|||
val queryMap = mutableMapOf( |
|||
"visual_message_return_type" to "unseen", |
|||
"thread_message_limit" to 20.toString(), |
|||
"persistentBadging" to true.toString(), |
|||
"limit" to 10.toString(), |
|||
) |
|||
if (!cursor.isNullOrBlank()) { |
|||
queryMap["cursor"] = cursor |
|||
queryMap["direction"] = "older" |
|||
} |
|||
if (seqId != 0L) { |
|||
queryMap["seq_id"] = seqId.toString() |
|||
} |
|||
return repository.fetchPendingInbox(queryMap) |
|||
} |
|||
|
|||
fun approveRequest(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.approveRequest(threadId, form) |
|||
} |
|||
|
|||
fun declineRequest(threadId: String): Call<String?> { |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
) |
|||
return repository.declineRequest(threadId, form) |
|||
} |
|||
|
|||
fun markAsSeen( |
|||
threadId: String, |
|||
directItem: DirectItem, |
|||
): Call<DirectItemSeenResponse?>? { |
|||
val itemId = directItem.itemId ?: return null |
|||
val form = mapOf( |
|||
"_csrftoken" to csrfToken, |
|||
"_uuid" to deviceUuid, |
|||
"use_unified_inbox" to "true", |
|||
"action" to "mark_seen", |
|||
"thread_id" to threadId, |
|||
"item_id" to itemId, |
|||
) |
|||
return repository.markItemSeen(threadId, itemId, form) |
|||
} |
|||
|
|||
companion object { |
|||
private lateinit var instance: DirectMessagesService |
|||
|
|||
@JvmStatic |
|||
fun getInstance( |
|||
csrfToken: String, |
|||
userId: Long, |
|||
deviceUuid: String, |
|||
): DirectMessagesService { |
|||
if (!this::instance.isInitialized |
|||
|| instance.csrfToken != csrfToken |
|||
|| instance.userId != userId |
|||
|| instance.deviceUuid != deviceUuid |
|||
) { |
|||
instance = DirectMessagesService(csrfToken, userId, deviceUuid) |
|||
} |
|||
return instance |
|||
} |
|||
} |
|||
|
|||
} |
@ -1,98 +1,57 @@ |
|||
package awais.instagrabber.webservices; |
|||
|
|||
import com.google.gson.FieldNamingPolicy; |
|||
import com.google.gson.Gson; |
|||
import com.google.gson.GsonBuilder; |
|||
|
|||
import java.io.File; |
|||
|
|||
import awais.instagrabber.BuildConfig; |
|||
import awais.instagrabber.repositories.responses.Caption; |
|||
import awais.instagrabber.repositories.serializers.CaptionDeserializer; |
|||
import awais.instagrabber.utils.Utils; |
|||
import awais.instagrabber.webservices.interceptors.AddCookiesInterceptor; |
|||
import awais.instagrabber.webservices.interceptors.IgErrorsInterceptor; |
|||
import okhttp3.Cache; |
|||
import okhttp3.OkHttpClient; |
|||
import retrofit2.Retrofit; |
|||
import retrofit2.converter.gson.GsonConverterFactory; |
|||
import retrofit2.converter.scalars.ScalarsConverterFactory; |
|||
|
|||
public final class RetrofitFactory { |
|||
private static final Object LOCK = new Object(); |
|||
|
|||
private static RetrofitFactory instance; |
|||
|
|||
private final int cacheSize = 10 * 1024 * 1024; // 10 MB |
|||
private final Cache cache = new Cache(new File(Utils.cacheDir), cacheSize); |
|||
|
|||
private IgErrorsInterceptor igErrorsInterceptor; |
|||
private Retrofit.Builder builder; |
|||
private Retrofit retrofit; |
|||
private Retrofit retrofitWeb; |
|||
|
|||
public static RetrofitFactory getInstance() { |
|||
if (instance == null) { |
|||
synchronized (LOCK) { |
|||
if (instance == null) { |
|||
instance = new RetrofitFactory(); |
|||
} |
|||
} |
|||
} |
|||
return instance; |
|||
} |
|||
|
|||
private Retrofit.Builder getRetrofitBuilder() { |
|||
if (builder == null) { |
|||
igErrorsInterceptor = new IgErrorsInterceptor(); |
|||
final OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder() |
|||
.followRedirects(false) |
|||
.followSslRedirects(false) |
|||
.cache(cache); |
|||
package awais.instagrabber.webservices |
|||
|
|||
import awais.instagrabber.BuildConfig |
|||
import awais.instagrabber.repositories.responses.Caption |
|||
import awais.instagrabber.repositories.serializers.CaptionDeserializer |
|||
import awais.instagrabber.utils.Utils |
|||
import awais.instagrabber.webservices.interceptors.AddCookiesInterceptor |
|||
import awais.instagrabber.webservices.interceptors.IgErrorsInterceptor |
|||
import com.google.gson.FieldNamingPolicy |
|||
import com.google.gson.GsonBuilder |
|||
import okhttp3.Cache |
|||
import okhttp3.OkHttpClient |
|||
import retrofit2.Retrofit |
|||
import retrofit2.converter.gson.GsonConverterFactory |
|||
import retrofit2.converter.scalars.ScalarsConverterFactory |
|||
import java.io.File |
|||
|
|||
object RetrofitFactory { |
|||
private const val cacheSize: Long = 10 * 1024 * 1024 // 10 MB |
|||
private val cache = Cache(File(Utils.cacheDir), cacheSize) |
|||
private val igErrorsInterceptor: IgErrorsInterceptor by lazy { IgErrorsInterceptor() } |
|||
|
|||
private val retrofitBuilder: Retrofit.Builder by lazy { |
|||
val clientBuilder = OkHttpClient.Builder().apply { |
|||
followRedirects(false) |
|||
followSslRedirects(false) |
|||
cache(cache) |
|||
addInterceptor(AddCookiesInterceptor()) |
|||
addInterceptor(igErrorsInterceptor) |
|||
if (BuildConfig.DEBUG) { |
|||
// clientBuilder.addInterceptor(new LoggingInterceptor()); |
|||
// addInterceptor(new LoggingInterceptor()); |
|||
} |
|||
clientBuilder.addInterceptor(new AddCookiesInterceptor()) |
|||
.addInterceptor(igErrorsInterceptor); |
|||
final Gson gson = new GsonBuilder() |
|||
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) |
|||
.registerTypeAdapter(Caption.class, new CaptionDeserializer()) |
|||
.setLenient() |
|||
.create(); |
|||
builder = new Retrofit.Builder() |
|||
.addConverterFactory(ScalarsConverterFactory.create()) |
|||
.addConverterFactory(GsonConverterFactory.create(gson)) |
|||
.client(clientBuilder.build()); |
|||
} |
|||
return builder; |
|||
val gson = GsonBuilder().apply { |
|||
setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) |
|||
registerTypeAdapter(Caption::class.java, CaptionDeserializer()) |
|||
setLenient() |
|||
}.create() |
|||
Retrofit.Builder().apply { |
|||
addConverterFactory(ScalarsConverterFactory.create()) |
|||
addConverterFactory(GsonConverterFactory.create(gson)) |
|||
client(clientBuilder.build()) |
|||
} |
|||
} |
|||
|
|||
public Retrofit getRetrofit() { |
|||
if (retrofit == null) { |
|||
retrofit = getRetrofitBuilder() |
|||
val retrofit: Retrofit by lazy { |
|||
retrofitBuilder |
|||
.baseUrl("https://i.instagram.com") |
|||
.build(); |
|||
} |
|||
return retrofit; |
|||
.build() |
|||
} |
|||
|
|||
public Retrofit getRetrofitWeb() { |
|||
if (retrofitWeb == null) { |
|||
retrofitWeb = getRetrofitBuilder() |
|||
val retrofitWeb: Retrofit by lazy { |
|||
retrofitBuilder |
|||
.baseUrl("https://www.instagram.com") |
|||
.build(); |
|||
} |
|||
return retrofitWeb; |
|||
} |
|||
|
|||
public void destroy() { |
|||
if (igErrorsInterceptor != null) { |
|||
igErrorsInterceptor.destroy(); |
|||
} |
|||
igErrorsInterceptor = null; |
|||
retrofit = null; |
|||
retrofitWeb = null; |
|||
builder = null; |
|||
instance = null; |
|||
.build() |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue