In MailKit How do I get the UniqueId for a message deleted from the OnMessageExpunged Event - mailkit

Using Mailkit and monitoring the Inbox
I have the callback OnMessageExpunged registered on the Inbox so I can track messages deleted from the Inbox by external influences.
Inbox.MessageExpunged += OnMessageExpunged;
...
void OnMessageExpunged( object? sender, MessageEventArgs e )
{
...
}
When the event is fired, the MessageEventArgs has a field Uniqueid but it is null. It only has the message index.
I am tracking all the emails based on UniqueId because all the indexes change when a message is deleted hence I am sorta stuffed unless I rescan the entire Inbox on message deleted and look for any missing UniqueIds.
Am I missing something?

You need to keep consistent state with IMAP so that you can correctly map indexes to UIDs in your local cache.

Related

Laravel Swift add UUID

I'm sending mass messages with custom messages per subscriber, when I get the bounce-back I use my own cocktail to read the STMP emails.
What I haven't figure it out is how to add a unique ID for each email that is sent out, so in my bounce-back I can read the email's code and look for that particular ID, currently when I read the bounce I look for the recipient email compare to what I have based on creation date plus the email...
Is not efficient and 20 emails out of 1K or so gets lost cuz I can't find in bounce the headers due to some servers custom messages although it does return headers but I have nothing to compared with...
So is there a way to add this UUID in Swift services? I have seen that Swift is adding its own UUID but I haven't been able to retrieve it, when the message is sent I want that UUID so that I can save it and then latter I can read it from the bounces...
So, if I can't retrieve it, can I add my own?
I wanna have a relation email and UUID that was use when that message was sent.
$message_out = (new \Swift_Message($out->subject))
->setFrom($out->from_email, $out->from_name)
->setTo($out->email)
->setBody($content, 'text/html')
->setReplyTo('noreply#foo.com', 'No reply');
$message_out->send($mensaje_mail, $errors_sent);
Is this a header I can add the retrieve it in the bounce-back messages?
Thank you.

CloudKit, join or efficient way to add an item to list

I'm using CloudKit to manage a list of messages (record type Message with a field title and body). All messages are public and I want to maintain which Message the user has read using the mobile app.
The app can have thousands of users and messages. And I use swift3.
I've think of different way to do it but they seems quite poor in term of performance:
add a field 'readers' to Message which is a list of string corresponding of user Id. The problem is that if I want to add a new user ID I must load all the list. This is problematic for a mobile app in case of a lot of users have read the message. Can I lazy fetch a list field and add a value to it without downloading all the list (like in classic Orm)?
add another record type 'Reader' which has two fields: a user ID and a message ID. I can't find a way to join Message and Reader in a predicate to download only Message that the user hasn't read. Is that possible?
As suggested by Matthew: add a record type ReadArticle in the private database that stores only a CKReference to a message. The problem is that we need to download all message ID before sending them in a NOT predicate.
I don't know how to solve this problem with a database like CloudKit.
Any advice ?
Readers field
This approach is not ideal for the exact reasons you pointed out, and it additionally is unsafe as a String could theoretically contain anything.
Reader object
Even if there was a way to get this to work you'd be storing user ids in the public database. That's probably not a privacy-conscious thing to do.
ReadMessage Record in Private Database
Suppose you had a Record Type called ReadArticle. This object would contain exactly one field, a CKReference to a Message record.
Then, when someone reads a Message, you take the recordId of that Message, create a CKReference from it, and place that reference in the "message" field of a new CKRecord object of type ReadMessage. Then, you save it to the user's private database. Because it's a CKReference, it won't actually take up hardly any space in iCloud because it's just a pointer, and because you'd use the user's private database there's no need to explicitly identify the user.
Then when you want all unread messages, fetch the ReadMessage record, and create a NOT predicate to receive all Message records where the record id is not any of the read ones. CloudKit definitely supports NOT predicates, but if it happens to not support NOT predicates specifying record ids, than you could use some other unique field on message instead.

java imap, performance issues, fetching all mails

I will use java mail api to handle mails like thunderbird etc. I have to fetch mails having 1000 messages. My design will be: When user performs a synch on a folder, i will get all uids of the messages in the folder:
Message[] msgs = ufolder.getMessagesByUID(1, UIDFolder.LASTUID);
// Use a suitable FetchProfile
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.FLAGS);
I wil then compare the list of uids with the list stored in my db.
For the deleted ones, for example a message is not in the folder but in the db, i will mark it as deleted.
For the new ones, for example a message is in the folder but not in the db, i will mark as possible new. But, because messageuids are not safe (can be changed by the mail server on some cases), for the new mails, i will use additioanlly a custom hash value build from message id in the header + subject + receivedate and build a md5 hash. Only for the possible new mails i will use this hash and catch new mails.
For the moved messages, because their uids will be changed in the new folder, it will be flagged as deleted in the first and will be a new message in new folder, but the message will have same custom hash value becaue message id in the header and other properties will remain same duing the movement.
Question about performance issue: On each click on folder (folder synch) i will do the compare operation of all uids in the folder with the local uid list stored in the db to learn the deleted ones. I could not find another better way to accomplish this. As you know, thunderbird catches immediately a deleted message without relogin, even if the folder is large and the deleted message is very old (5 years). I think thunderbird also compares all message uids in that folder with a list stored locally.
How can i implement a better mechanism for the synch for a better performance? Does thunderbird apply a different approach? How can thunderbird
accomplish it so quickly?
If we were interested only for the new messages, i could have kept last stored uid and only compare the new messages later than that, but for the deleted ones, i already have to compare full folder. Additionally, UIDNEXT value is always -1 in my mail server, if it were set correctly, it will not help to get deleted ones again, a full compare is a must i think, am I wrong?
Note: I canot not use or add message listeners because the appliaction is server-client based and the mail handling task is on the server side and we do not support threads listeners etc. The events should be triggered from the client and the request is being processed on ther server and a response is returned and client handles the response on the gui.
What you want is called condstore or quick resync, RFC7162 in both cases. That's what Thunderbird uses.
That's a pair of extensions support commands like "give me all the UIDs that have changed since last time I connected", "tell me what's been deleted" and so on.
If you can't use threads to listen for these events from the mail server, your options are very limited. Probably the best thing you can do is limit the resynchronization to the messages that are visible to the client.

how to remove local isDirty objects from ember-data before loading a template?

I am have a /customers. I am creating a new customer as :
var new_customer = this.store.createRecord('customer', customer_object);
new_customer.save().then(onSuccess, onError);
where customer_object contains a record for customer. When customer is created successfully, onSuccess gets called which then transit to newly created customer (/customers/<new_customer>). This flow is working as expected. When I get an error (say Unauthorized Access), onError is also getting called which then transit to /customers after showing an error-alert. The problem here is that, though the customer is not created at server-side, when I transit to /customers, it shows that newly created customer (with isDirty as true.) How can I remove such invalid objects from my local ember-array?
You can call
new_customer.deleteRecord();
in onError handler to remove the record after error has occured.

Request factory is sending back the entire List<EntityProxy> even if only one element is altered

When I load an entity proxy which has a nested collection of entity proxies (eg: AddressBook entity proxy containing a list of Contact proxies) and if I make changes to the inner list ( the List of Contacts) like removal of an item, and call a persist on it, Request Factory is sending the entire list of contacts. Is this the expected behaviour, or is it supposed to send only a command to delete the item on the server also?
The question is, does request factory send deltas just for field level changes, or does it calculate deltas for collections also?
ContactProxy
interface ContactProxy extends EntityProxy {
...
//Getters and setters for firstName, lastName, phoneNumber etc...
...
}
AddressBookProxy
interface AddressBookProxy extends EntityProxy {
...
List<ContactProxy> getContacts();
void setContacts(List<ContactProxy> contacts);
...
}
Focus code:
//Assume I received an abProxy from a previous context.
AddressBookRequestContext context = requestFactory.requestContext();
abProxy = context.edit(abProxy);
abProxy.getContacts().remove(0);
context.persist().using(abProxy).fire();
The above piece of code is sending the entire list of contacts received in the previous context, but I expected to send only a delete command to the server. Am I doing something wrong?
Now when I make a change to a single contact in the AddressBook entity proxy and make a call to persist, it is still sending the entire list of contacts. What is the workaround to get deltas working for these kind of collection level changes.
You're modifying the list from a list of 10 elements to a list of 9 elements, so RF sends the new list of 9 elements (and will call the setter with the new list on the server side).
However, it only sends the IDs of the contacts, not their properties, because those haven't changed (and yes, it means all contacts will have to be retrieved on the server-side, in order to populate the new list of 9 elements, before setting it into the address book).
There's probably room for improvement in RF though: when you edit() a proxy, it automatically edits all the proxies it references (recursively), so all 10 contacts are edit()ed, and thus all 10 contacts IDs are sent to the server, an all 10 contacts are retrieved from the database and validated, even though only 9 of them are used afterwards. As a result (and that could be seen as a feature) in the event the removed contact has been updated since originally retrieved on the client, the server will send an EntityProxyChange for the contact to the client in the response.
In a few words: there's no magic, everything comes to a cost, so be careful when designing your "APIs"; you might want to add a removeContact method to your RequestContext instead of modifying the list (and retrieve the address book again –batched in the same RequestContext– to get the update on the client-side)