package it.cavallium; import it.tdlight.jni.TdApi; import it.tdlight.jni.TdApi.AuthorizationState; import it.tdlight.jni.TdApi.AuthorizationStateReady; import it.tdlight.jni.TdApi.Chat; import it.tdlight.jni.TdApi.ChatMemberStatusAdministrator; import it.tdlight.jni.TdApi.GetSupergroupFullInfo; import it.tdlight.jni.TdApi.Object; import it.tdlight.jni.TdApi.Supergroup; import it.tdlight.jni.TdApi.SupergroupFullInfo; import it.tdlight.jni.TdApi.Update; import it.tdlight.jni.TdApi.UpdateAuthorizationState; import it.tdlight.jni.TdApi.UpdateNewChat; import it.tdlight.jni.TdApi.UpdateSupergroup; import it.tdlight.jni.TdApi.UpdateSupergroupFullInfo; import it.tdlight.tdlibsession.td.TdResult; import it.tdlight.tdlibsession.td.easy.AsyncTdEasy; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import java.util.stream.Stream; import org.reactivestreams.Publisher; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; public class TransferClient { private final AsyncTdEasy client; private final ConcurrentHashMap supergroupInfos = new ConcurrentHashMap<>(); private final ConcurrentHashMap supergroupFullInfos = new ConcurrentHashMap<>(); private final ConcurrentHashMap chats = new ConcurrentHashMap<>(); public TransferClient(AsyncTdEasy client) { this.client = client; this.client.getIncomingUpdates() .subscribeOn(Schedulers.newParallel("bot_updates")) .flatMap(this::onUpdate) .subscribe(); } private Mono onUpdate(Update update) { switch (update.getConstructor()) { case UpdateSupergroup.CONSTRUCTOR: return this.onUpdateSupergroup(((UpdateSupergroup) update).supergroup); case UpdateSupergroupFullInfo.CONSTRUCTOR: return this.onUpdateSupergroupFullInfo( ((UpdateSupergroupFullInfo) update).supergroupId, ((UpdateSupergroupFullInfo) update).supergroupFullInfo); case UpdateNewChat.CONSTRUCTOR: return this.onChat(((UpdateNewChat) update).chat); case UpdateAuthorizationState.CONSTRUCTOR: return this.onUpdateAuthorizationState(((UpdateAuthorizationState) update).authorizationState); default: return Mono.empty(); } } private Mono onUpdateAuthorizationState(AuthorizationState authorizationState) { switch (authorizationState.getConstructor()) { case AuthorizationStateReady.CONSTRUCTOR: return TransferUtils.getAllHomeChats(this).flatMap(this::onChat).then(); default: return Mono.empty(); } } private Mono onChat(Chat chat) { if (chats.put(chat.id, chat) == null) { // ok } return Mono.empty(); } private Mono onUpdateSupergroup(Supergroup supergroup) { if (supergroupInfos.put(supergroup.id, supergroup) == null) { return this .send(new GetSupergroupFullInfo(supergroup.id)) .filter(TdResult::succeeded) .map(TdResult::result) .flatMap(supergroupFullInfo -> onUpdateSupergroupFullInfo(supergroup.id, supergroupFullInfo)); } return Mono.empty(); } private Mono onUpdateSupergroupFullInfo(int id, SupergroupFullInfo supergroupFullInfo) { if (supergroupFullInfos.put(id, supergroupFullInfo) == null) { // ok } return Mono.empty(); } /** * Sends request to TDLib. * @return The response or {@link TdApi.Error}. */ public Mono> send(TdApi.Function request) { return client.send(request); } public Set getAdminSupergroups(boolean canRestrictMembers, boolean canInviteUsers) { return supergroupFullInfos.entrySet().stream().flatMap(entry -> { int id = entry.getKey(); var fullInfo = entry.getValue(); var chatInfo = chats.get(TransferUtils.chatEntityIdToChatId(id, TChatType.SUPERGROUP)); var baseInfo = supergroupInfos.get(id); if (chatInfo == null || baseInfo == null) { return Stream.empty(); } else { if (baseInfo.status.getConstructor() != ChatMemberStatusAdministrator.CONSTRUCTOR) { return Stream.empty(); } var adminStatus = (ChatMemberStatusAdministrator) baseInfo.status; if (!adminStatus.canRestrictMembers && canRestrictMembers) { return Stream.empty(); } if (!adminStatus.canInviteUsers && canInviteUsers) { return Stream.empty(); } var baseChatInfo = new BaseChatInfo(id, chatInfo.title); return Stream.of(baseChatInfo); } }).collect(Collectors.toSet()); } }