/// <summary> /// Sends a <see cref="AvatarMetadataSubcribeMessage"/> to subscribe to the avatar metadata node. /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or null in case it should be send to our own PEP provider.</param> /// <returns>Returns a <see cref="MessageResponseHelper{IQMessage}"/> listening for <see cref="AvatarMetadataSubcribeMessage"/> answers.</returns> public Task <MessageResponseHelperResult <IQMessage> > requestAvatarMetadataSubscriptionAsync(string to) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); AvatarMetadataSubcribeMessage msg = new AvatarMetadataSubcribeMessage(CONNECTION.account.getFullJid(), CONNECTION.account.getBareJid(), to); return(helper.startAsync(msg)); }
/// <summary> /// Sends a <see cref="DiscoRequestMessage"/> to query for room information. /// See also: https://xmpp.org/extensions/xep-0045.html#disco-roominfo /// </summary> /// <param name="roomJId">The bare JID for the room that should be queried.</param> /// <returns>Returns the <see cref="MessageResponseHelper{ExtendedDiscoResponseMessage}"/> listening for answers to the request.</returns> public Task <MessageResponseHelperResult <ExtendedDiscoResponseMessage> > requestRoomInfoAsync(string roomJId) { AsyncMessageResponseHelper <ExtendedDiscoResponseMessage> helper = new AsyncMessageResponseHelper <ExtendedDiscoResponseMessage>(CONNECTION); DiscoRequestMessage disco = new DiscoRequestMessage(CONNECTION.account.getFullJid(), roomJId, DiscoType.INFO); return(helper.startAsync(disco)); }
/// <summary> /// Sends a <see cref="RequestAvatarMessage"/> to request the avatar metadata. /// https://xmpp.org/extensions/xep-0084.html#process-pubmeta /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or null in case it should be send to our own PEP provider.</param> /// <param name="avatarHash">The hexadecimal version of the avatar hash you would like to request.</param> /// <returns>Returns a <see cref="MessageResponseHelper{IQMessage}"/> listening for <see cref="RequestAvatarMessage"/> answers.</returns> public Task <MessageResponseHelperResult <IQMessage> > requestAvatarAsync(string to, string avatarHash) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); RequestAvatarMessage msg = new RequestAvatarMessage(CONNECTION.account.getFullJid(), to, avatarHash); return(helper.startAsync(msg)); }
/// <summary> /// Sends a "XEP-0357: Push Notifications" request to disable push notifications. /// </summary> /// <param name="pushServerBareJid">The bare JID of the push server.</param> /// <returns>Returns a <seealso cref="MessageResponseHelperResult"/> listening for <seealso cref="DisablePushNotificationsMessage"/> responses.</returns> public async Task<MessageResponseHelperResult<IQMessage>> disablePushNotificationsAsync(string pushServerBareJid) { Predicate<IQMessage> predicate = (x) => { return true; }; AsyncMessageResponseHelper<IQMessage> helper = new AsyncMessageResponseHelper<IQMessage>(CONNECTION, predicate); DisablePushNotificationsMessage msg = new DisablePushNotificationsMessage(pushServerBareJid); return await helper.startAsync(msg); }
/// <summary> /// Sends a DiscoRequestMessage to the given target to query all PubSub nodes. /// https://xmpp.org/extensions/xep-0060.html#entity-nodes /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or 'pubsub.example.org'.</param> /// <returns>Returns a MessageResponseHelperResult listening for DiscoRequestMessage answers.</returns> public Task <MessageResponseHelperResult <IQMessage> > discoNodesAsync(string to) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); DiscoRequestMessage msg = new DiscoRequestMessage(CONNECTION.account.getFullJid(), to, DiscoType.ITEMS); return(helper.startAsync(msg)); }
/// <summary> /// Sends a SetBookmarksMessage to set bookmarks on the server. /// https://xmpp.org/extensions/xep-0048.html#storage-pubsub-upload /// </summary> /// <param name="conferences">A list of XEP-0048 <seealso cref="Network.XML.Messages.XEP_0048.ConferenceItem"/> objects that should be set.</param> /// <returns>The XEP-0048 SetBookmarksMessage result.</returns> public async Task <MessageResponseHelperResult <IQMessage> > setBookmars_xep_0048Async(IList <Network.XML.Messages.XEP_0048.ConferenceItem> conferences) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); Network.XML.Messages.XEP_0048.SetBookmarksMessage msg = new Network.XML.Messages.XEP_0048.SetBookmarksMessage(CONNECTION.account.getFullJid(), conferences); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a DiscoRequestMessage to the given target to query all PubSub nodes. /// https://xmpp.org/extensions/xep-0060.html#entity-discoveritems /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or 'pubsub.example.org'.</param> /// <returns>Returns a MessageResponseHelperResult listening for DiscoNodeItemsRequestMessage answers.</returns> public async Task <MessageResponseHelperResult <IQMessage> > discoNodesItemsAsync(string to, string nodeName) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); DiscoNodeItemsRequestMessage msg = new DiscoNodeItemsRequestMessage(CONNECTION.account.getFullJid(), to, nodeName); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a PubSubRequestNodeMessage to retreive the content of the given node. /// https://xmpp.org/extensions/xep-0060.html#subscriber-retrieve /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or 'pubsub.example.org'.</param> /// <param name="nodeName">The name of the node, you want retreive the items for.</param> /// <param name="maxItems">The maximum number of items returned (if maxItems > 0, else unsepcified).</param> /// <returns>Returns a MessageResponseHelperResult listening for PubSubRequestNodeMessage answers.</returns> public async Task <MessageResponseHelperResult <IQMessage> > requestNodeAsync(string to, string nodeName, uint maxItems) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); PubSubRequestNodeMessage msg = new PubSubRequestNodeMessage(CONNECTION.account.getFullJid(), to, nodeName, maxItems); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a PubSubSubscribeMessage to subscribe to the given node. /// https://xmpp.org/extensions/xep-0060.html#subscriber-subscribe /// </summary> /// <param name="to">The target e.g. '*****@*****.**' or 'pubsub.example.org'.</param> /// <param name="nodeName">The name of the node, you want to subscribe to.</param> /// <returns>Returns a MessageResponseHelperResult listening for DiscoNodeItemsRequestMessage answers.</returns> public async Task <MessageResponseHelperResult <IQMessage> > requestNodeSubscriptionAsync(string to, string nodeName) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); PubSubSubscribeMessage msg = new PubSubSubscribeMessage(CONNECTION.account.getFullJid(), CONNECTION.account.getBareJid(), to, nodeName); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a PubSubDeleteNodeMessage to delete a pubsub node. /// https://xmpp.org/extensions/xep-0060.html#owner-delete /// </summary> /// <param name="toBareJid">The target pubsub server (can be null).</param> /// <param name="nodeName">The name of the node, you want to delete.</param> /// <returns>The result of the PubSubDeleteNodeMessage.</returns> public async Task <MessageResponseHelperResult <IQMessage> > deleteNodeAsync(string toBareJid, string nodeName) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); PubSubDeleteNodeMessage msg = new PubSubDeleteNodeMessage(CONNECTION.account.getFullJid(), toBareJid, nodeName); return(await helper.startAsync(msg)); }
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- /// <summary> /// Sends a RequestBookmarksMessage to request all bookmarks from the server. /// https://xmpp.org/extensions/xep-0048.html#storage-pubsub-retrieve /// </summary> /// <returns>The XEP-0048 RequestBookmarksMessage result.</returns> public async Task <MessageResponseHelperResult <IQMessage> > requestBookmars_xep_0048Async() { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); Network.XML.Messages.XEP_0048.RequestBookmarksMessage msg = new Network.XML.Messages.XEP_0048.RequestBookmarksMessage(CONNECTION.account.getFullJid()); return(await helper.startAsync(msg)); }
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- /// <summary> /// Sends a <seealso cref="RosterRequestMessage"/> to the server and requests the current roster. /// </summary> /// <returns>The result of the request.</returns> public async Task<MessageResponseHelperResult<IQMessage>> requestRosterAsync() { Predicate<IQMessage> predicate = (x) => { return true; }; AsyncMessageResponseHelper<IQMessage> helper = new AsyncMessageResponseHelper<IQMessage>(CONNECTION, predicate); RosterRequestMessage msg = new RosterRequestMessage(CONNECTION.account.getFullJid(), CONNECTION.account.getBareJid()); return await helper.startAsync(msg); }
/// <summary> /// Sends a <see cref="PublishAvatarMetadataMessage"/> to publish the given avatar metadata. /// https://xmpp.org/extensions/xep-0084.html#process-pubmeta /// </summary> /// <param name="metadata">The avatar metadata to publish.</param> /// <returns>Returns a <see cref="MessageResponseHelper{IQMessage}"/> listening for <see cref="PublishAvatarMetadataMessage"/> answers.</returns> public Task <MessageResponseHelperResult <IQMessage> > publishAvatarMetadataAsync(AvatarMetadataDataPubSubItem metadata) { AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION); PublishAvatarMetadataMessage msg = new PublishAvatarMetadataMessage(CONNECTION.account.getFullJid(), metadata); return(helper.startAsync(msg)); }
/// <summary> /// Sends a "XEP-0280: Message Carbons" request to enable message carbons. /// </summary> /// <returns>Returns a <seealso cref="MessageResponseHelperResult"/> listening for <seealso cref="CarbonsDisableMessage"/> responses.</returns> public async Task<MessageResponseHelperResult<IQMessage>> disableMessageCarbonsAsync() { Predicate<IQMessage> predicate = (x) => { return true; }; AsyncMessageResponseHelper<IQMessage> helper = new AsyncMessageResponseHelper<IQMessage>(CONNECTION, predicate); CarbonsDisableMessage msg = new CarbonsDisableMessage(CONNECTION.account.getFullJid()); return await helper.startAsync(msg); }
/// <summary> /// Sends a <seealso cref="DiscoRequestMessage"/> to the given target. /// </summary> /// <param name="target">The target e.g. '*****@*****.**'.</param> /// <param name="type">The disco type</param> /// <returns>Returns a <seealso cref="MessageResponseHelperResult"/> listening for <seealso cref="DiscoRequestMessage"/> answers.</returns> public async Task<MessageResponseHelperResult<IQMessage>> discoAsync(string target, DiscoType type) { Predicate<IQMessage> predicate = (x) => { return true; }; AsyncMessageResponseHelper<IQMessage> helper = new AsyncMessageResponseHelper<IQMessage>(CONNECTION, predicate); DiscoRequestMessage msg = new DiscoRequestMessage(CONNECTION.account.getFullJid(), target, type); return await helper.startAsync(msg); }
/// <summary> /// Sends a <see cref="RoomConfigMessage"/> and saves the given room configuration. /// </summary> /// <param name="roomJid">The bare JID if the room you would like to save the room configuration for. e.g. '*****@*****.**'</param> /// <param name="roomConfiguration">The new room configuration.</param> /// <returns>The <see cref="RoomConfigMessage"/> result</returns> public async Task <MessageResponseHelperResult <IQMessage> > saveRoomConfigurationAsync(string roomJid, DataForm roomConfiguration) { Predicate <IQMessage> predicate = (x) => { return(true); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); RoomConfigMessage msg = new RoomConfigMessage(CONNECTION.account.getFullJid(), roomJid, roomConfiguration, MUCAffiliation.OWNER); return(await helper.startAsync(msg)); }
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ #region --Misc Methods (Public)-- /// <summary> /// Sends an OmemoRequestBundleInformationMessage to requests the OMEMO bundle information of the given target and deviceId. /// </summary> /// <param name="toBareJid">The bare JID of the target you want to request the OMEMO bundle information from. e.g. 'conference.jabber.org'</param> /// <param name="deviceId">The device id you want to request the OMEMO bundle information for.</param> /// <returns>The OmemoRequestBundleInformationMessage result.</returns> public Task <MessageResponseHelperResult <IQMessage> > requestBundleInformationAsync(string toBareJid, uint deviceId) { Predicate <IQMessage> predicate = (x) => { return(x is OmemoBundleInformationResultMessage || x is IQErrorMessage); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoRequestBundleInformationMessage msg = new OmemoRequestBundleInformationMessage(CONNECTION.account.getFullJid(), toBareJid, deviceId); return(helper.startAsync(msg)); }
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ #region --Set-, Get- Methods-- /// <summary> /// Sends an OmemoSetBundleInformationMessage for updating the given bundle information. /// </summary> /// <param name="bundleInfo">The bundle information you want to update.</param> /// <returns>The OmemoSetBundleInformationMessage result.</returns> public Task <MessageResponseHelperResult <IQMessage> > setBundleInfoAsync(OmemoBundleInformation bundleInfo) { Predicate <IQMessage> predicate = (x) => { return(true); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoSetBundleInformationMessage msg = new OmemoSetBundleInformationMessage(CONNECTION.account.getFullJid(), bundleInfo); return(helper.startAsync(msg)); }
/// <summary> /// Sends an OmemoSubscribeToDeviceListMessage to subscribe to targets device list. /// </summary> /// <param name="toBareJid">The bare JID of the target you want to subscribe to. e.g. 'conference.jabber.org'</param> /// <returns>The OmemoSubscribeToDeviceListMessage result.</returns> public Task <MessageResponseHelperResult <IQMessage> > subscribeToDeviceListAsync(string toBareJid) { Predicate <IQMessage> predicate = (x) => { return(x is PubSubSubscriptionMessage || x is IQErrorMessage); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoSubscribeToDeviceListMessage msg = new OmemoSubscribeToDeviceListMessage(CONNECTION.account.getFullJid(), CONNECTION.account.getBareJid(), toBareJid); return(helper.startAsync(msg)); }
/// <summary> /// Sends an OmemoRequestDeviceListMessage to requests the OMEMO device list of the given target. /// </summary> /// <param name="toBareJid">The bare JID of the target you want to request the OMEMO bundle information from. e.g. 'conference.jabber.org'</param> /// <param name="deviceId">The device id you want to request the OMEMO device list for.</param> /// <returns>The OmemoRequestDeviceListMessage result.</returns> public async Task <MessageResponseHelperResult <IQMessage> > requestDeviceListAsync(string toBareJid) { Predicate <IQMessage> predicate = (x) => { return(x is OmemoDeviceListResultMessage || x is IQErrorMessage); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoRequestDeviceListMessage msg = new OmemoRequestDeviceListMessage(CONNECTION.account.getFullJid(), toBareJid); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a "XEP-0357: Push Notifications" request to enable push notifications. /// </summary> /// <param name="pushServerBareJid">The bare JID of the push server e.g. '*****@*****.**'.</param> /// <param name="node">The "XEP-0060: Publish-Subscribe" node where the server should publish notifications to.</param> /// <param name="secret">The authentication secret for the "XEP-0060: Publish-Subscribe" node, where the server should publish notifications to.</param> /// <returns>Returns a <seealso cref="MessageResponseHelperResult"/> listening for <seealso cref="EnablePushNotificationsMessage"/> responses.</returns> public Task <MessageResponseHelperResult <IQMessage> > enablePushNotificationsAsync(string pushServerBareJid, string node, string secret) { Predicate <IQMessage> predicate = (x) => { return(true); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); EnablePushNotificationsMessage msg = new EnablePushNotificationsMessage(pushServerBareJid, node, secret); return(helper.startAsync(msg)); }
/// <summary> /// Sends an OmemoSetDeviceListMessage to update your OMEMO device list with the given devices. /// </summary> /// <param name="devices">The new OMEMO device list.</param> /// <returns>The OmemoSetDeviceListMessage result.</returns> public Task <MessageResponseHelperResult <IQMessage> > setDeviceListAsync(OmemoXmlDevices devices) { Predicate <IQMessage> predicate = (x) => { return(true); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoSetDeviceListMessage msg = new OmemoSetDeviceListMessage(CONNECTION.account.getFullJid(), devices); return(helper.startAsync(msg)); }
/// <summary> /// Sends a <see cref="RequestRoomConfigurationMessage"/> and requests the current room configuration. /// </summary> /// <param name="roomJid">The bare JID if the room you would like to request the room configuration for. e.g. '*****@*****.**'</param> /// <returns>The <see cref="RequestRoomConfigurationMessage"/> result</returns> public async Task <MessageResponseHelperResult <IQMessage> > requestRoomConfigurationAsync(string roomJid) { Predicate <IQMessage> predicate = (x) => { return(x is RoomConfigMessage || x is IQErrorMessage); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); RequestRoomConfigurationMessage msg = new RequestRoomConfigurationMessage(roomJid, MUCAffiliation.OWNER); return(await helper.startAsync(msg)); }
/// <summary> /// Sends an OmemoRequestDeviceListMessage to requests the OMEMO device list of the given target. /// </summary> /// <param name="toBareJid">The bare JID of the target you want to request the OMEMO bundle information from. e.g. 'conference.jabber.org'</param> /// <param name="deviceId">The device id you want to request the OMEMO device list for.</param> /// <returns>The OmemoRequestDeviceListMessage result.</returns> public Task <MessageResponseHelperResult <IQMessage> > requestDeviceListAsync(string toBareJid) { Logger.Info($"Requesting OMEMO device list for {toBareJid} ..."); Predicate <IQMessage> predicate = (x) => { return(x is OmemoDeviceListResultMessage || x is IQErrorMessage); }; AsyncMessageResponseHelper <IQMessage> helper = new AsyncMessageResponseHelper <IQMessage>(CONNECTION, predicate); OmemoRequestDeviceListMessage msg = new OmemoRequestDeviceListMessage(CONNECTION.account.getFullJid(), toBareJid); return(helper.startAsync(msg)); }
/// <summary> /// Sends a MUCChangeNicknameMessage for changing your own MUC nickname. /// </summary> /// <param name="roomJid">The bare JID if the room you would like to change your nickname for. e.g. '*****@*****.**'</param> /// <param name="newNickname">The new nickname for the given room.</param> /// <returns>Returns a MessageResponseHelper listening for MUCChangeNicknameMessage answers.</returns> public async Task <MessageResponseHelperResult <MUCMemberPresenceMessage> > changeNicknameAsync(string roomJid, string newNickname) { Predicate <MUCMemberPresenceMessage> predicate = (x) => { return(x.getFrom().Contains(roomJid) && ((x.STATUS_CODES.Contains(MUCPresenceStatusCode.PRESENCE_SELFE_REFERENCE) && x.STATUS_CODES.Contains(MUCPresenceStatusCode.MEMBER_NICK_CHANGED)) || (x.STATUS_CODES.Contains(MUCPresenceStatusCode.PRESENCE_SELFE_REFERENCE) && x.STATUS_CODES.Contains(MUCPresenceStatusCode.ROOM_NICK_CHANGED)) || !string.IsNullOrEmpty(x.ERROR_TYPE))); }; AsyncMessageResponseHelper <MUCMemberPresenceMessage> helper = new AsyncMessageResponseHelper <MUCMemberPresenceMessage>(CONNECTION, predicate) { matchId = false }; MUCChangeNicknameMessage msg = new MUCChangeNicknameMessage(CONNECTION.account.getFullJid(), roomJid, newNickname); return(await helper.startAsync(msg)); }
/// <summary> /// Sends a <seealso cref="QueryArchiveMessage"/> to the server and requests the MAM archive. /// </summary> /// <param name="filter">A filter for filtering the MAM results like filtering by JID.</param> /// <param name="rsm">Optional configuration for the result set.</param> /// <param name="to">The target of the request. null for request to your own server. Used for requesting MUC-MAMs.</param> /// <returns>The result of the request.</returns> public async Task <MessageResponseHelperResult <MamResult> > requestMamAsync(QueryFilter filter, Set rsm, string to) { QueryArchiveMessage msg = new QueryArchiveMessage(filter, rsm, CONNECTION.account.getFullJid(), to); List <QueryArchiveResultMessage> results = new List <QueryArchiveResultMessage>(); Predicate <AbstractAddressableMessage> predicate = (x) => { if (x is QueryArchiveResultMessage result && string.Equals(result.QUERY_ID, msg.QUERY_ID)) { results.Insert(0, result); return(false); } if (x is IQErrorMessage && string.Equals(msg.ID, x.ID)) { return(true); } return(x is QueryArchiveFinishMessage fin && string.Equals(fin.ID, msg.ID)); }; AsyncMessageResponseHelper <AbstractAddressableMessage> helper = new AsyncMessageResponseHelper <AbstractAddressableMessage>(CONNECTION, predicate) { matchId = false }; MessageResponseHelperResult <AbstractAddressableMessage> finResult = await helper.startAsync(msg); MamResult mamResult = null; if (finResult.STATE == MessageResponseHelperResultState.SUCCESS) { if (finResult.RESULT is QueryArchiveFinishMessage archiveFinishMessage) { mamResult = new MamResult(finResult.RESULT as QueryArchiveFinishMessage, results); } else { if (finResult.RESULT is IQErrorMessage errorMessage) { Logger.Warn($"Failed to request MAM from {to} with: {errorMessage.ERROR_OBJ}"); } return(new MessageResponseHelperResult <MamResult>(MessageResponseHelperResultState.ERROR, null)); } } return(new MessageResponseHelperResult <MamResult>(finResult.STATE, mamResult)); }
/// <summary> /// Sends a <seealso cref="QueryArchiveMessage"/> to the server and requests the MAM archive. /// </summary> /// <param name="filter">A filter for filtering the MAM results like filtering by JID.</param> /// <param name="rsm">Optional configuration for the result set.</param> /// <param name="to">The target of the request. null for request to your own server. Used for requesting MUC-MAMs.</param> /// <returns>The result of the request.</returns> public async Task<MessageResponseHelperResult<MamResult>> requestMamAsync(QueryFilter filter, Set rsm, string to) { QueryArchiveMessage msg = new QueryArchiveMessage(filter, rsm, CONNECTION.account.getFullJid(), to); List<QueryArchiveResultMessage> results = new List<QueryArchiveResultMessage>(); Predicate<AbstractAddressableMessage> predicate = (x) => { if (x is QueryArchiveResultMessage result && string.Equals(result.QUERY_ID, msg.QUERY_ID)) { results.Insert(0, result); return false; } return x is QueryArchiveFinishMessage fin && string.Equals(fin.ID, msg.ID) && string.Equals(fin.QUERY_ID, msg.QUERY_ID); }; AsyncMessageResponseHelper<AbstractAddressableMessage> helper = new AsyncMessageResponseHelper<AbstractAddressableMessage>(CONNECTION, predicate) { matchId = false }; MessageResponseHelperResult<AbstractAddressableMessage> finResult = await helper.startAsync(msg); MamResult mamResult = null; if (finResult.STATE == MessageResponseHelperResultState.SUCCESS) { mamResult = new MamResult(finResult.RESULT as QueryArchiveFinishMessage, results); } return new MessageResponseHelperResult<MamResult>(finResult.STATE, mamResult); }