Difference between Outlook.MailItem.EntryID and Mapi32.dll MessageID - outlook

I need to do some functionality from outlook VBO. Let say i'm downloading attachments from the outlook.mailitem. So I do save those files by prepending OutLook.MailItem.EntryID where EntryID is unique for each Email.
Now, I have another functionality or application that uses Mapi32.dll and that need to access the Files. So I used the MessageID property to get the files, but the problem is when I retrieve MessageID property from the Mapi32.dll it returns something like AAAAAKHslFt5unxKlnJ80RmsEX8HAEYxSGm4YvNPlCN7Kj9X/A8AAAAAAQwAAEYxSGm4YvNPlCN7Kj9X/A8AAOy+SWQAAA
but the EntryID from Outlook is 1DCBEE7832C89149AFAEBC41B53EAB85
I think both EntryID and MessageID are same, but is that encrypted from MapiEx? How can I decrypt it to get original EntryID ? Or is there any other common property between Outlook.MailItem object and Mapi32.dll MailMessage object that I can use to share information between two tool ?

The former looks like a base64 encoded entry id. The latter looks weird - entry ids usually start with 4 binary 0's (eight "0"s in the hex notation).

Related

How to turn message into a string

Can I turn a message into a string? I've tried just using the variable message to do that but it doesn't seem to work. I've tried...
print(message)
and all it told me was the message id and sender, and not the raw text or content.
You're looking for message.content. Just printing out message will give you the attributes and such values that you'll have access to.
If you're planning on seeing the "clean" version of the content, if it has mentions of users or channels in it, you can instead use the message.clean_content attribute.
See the references for more info on the attributes of the Message object.
References:
Message.content
Message.clean_content

Access the replied/forwarded/etc state from REST

I am trying to get and set the forwarded/replied state of an email message in the Graph API. This is the represented in OWA by the little icon in the right column.
It seems there is not a first class way to access this information, at least it does not come out in the unfiltered JSON dump.
Google suggests this is stored in the extended properties for PidTagLastVerbExecuted or PidTagIconIndex, however attempts to access these just give back 404:
https://graph.microsoft.com/beta/me/mailFolders/{id}/messages?$select=SingleValueExtendedProperties&$expand=SingleValueExtendedProperties($filter%3Did+eq+'String+0x1081')
Other extended properties like 0x0070 do work, so it seems the syntax is correct, and 0x1081 comes from here https://learn.microsoft.com/en-us/office/client-developer/outlook/mapi/pidtaglastverbexecuted-canonical-property
This information is stored, you can see it in OWA, the Outlook apps, and you can see it in IMAP.
Is there some way to do this? It seems strange this basic information about the email state is not made available.
Your specifying the wrong datatype that property is defined as a Long in the documentation (but the doco is for MAPI) so its actually an Integer in EWS and Graph eg this is something i used to return both PidTagLastVerbExecuted and PidTagLastVerbExecutedTime (which gives you the time of the last action)for a particular message
/v1.0/users('user#domaincom')/MailFolders/AllItems/messages/?$select=ReceivedDateTime,Sender,Subject,IsRead,inferenceClassification,InternetMessageId,parentFolderId,hasAttachments,webLink,InternetMessageHeaders&$Top=1000&$filter=internetMessageId+eq+%27%3cSG2PR04MB3223962312D5B46D0C9CA1B5C89C0%40SG2PR04MB3223.apcprd04.prod.outlook.com%3e%27&$expand=SingleValueExtendedProperties($filter=(Id%20eq%20'Integer%200x1081')%20or%20(Id%20eq%20'SystemTime%200x1082'))

Attach meta data / custom data to slack messages sent through the API

I am developing a series of Slack apps for my workspace, and some of them are meant to interact with the content (messages) delivered by the other apps : extracting content IDs that may be referred to by other messages
A concrete example :
Suppose I have an app A "FindUser" that is capable of giving me the user profile when a slack user types find me#example.com, and it replies in the thread with a formatted view of the user profile
I am developing an app B "EditTags", which basically gives me a right click option with "edit tags" (see Slack's Interactive Components/Actions), the idea being that a user could first ask app A to find a user, and then right click on the reply from App A and click the "edit tags" action given by the other app. What this app B does it actually retrieve the tags for the user mentionned by the previous message from app A, and in another reply to the thread it gives some controls to either delete an existing tag OR it shows a select with autocomplete to add new tags.
The B app needs to retrieve the user ID that the A app mentionned previously. So I need some way to pass that data directly in the slack message. When looking at the examples, slack does not seem to provide a way to add arbitrary "metadata" to a message, am I wrong ? Do you have workaround for this ? I mean I could totally send the user ID say, in the footer, so I can just read the footer, but I was planning to use the footer for something else... Is there a way to pass metadata hrough properties that would be hidden to the end user ?
Although this does not feel relevant, I am building a slack nodeJS app using the node slack sdk (and especially the #slack/interactive-messages package)
For the most part the Slack API does not provide any official means to attach custom data / meta data to messages. But with some simple "hacks" it is still possible. Here is how:
Approach
The basic approach is to use an existing field of the message as container for your data. Obviously you want to pick a field that is not directly linked to Slack functionality.
Some field are not always needed, so you can just use that field as data container. Or if its needed, you can include the functional value of that field along with your custom data in the data container.
For example for message buttons you could use the value field of a button and structure your code in a way that you do not need it in its original function. Usually its sufficient to know which button the user client (via the name field), so the value field is free to be used for your custom data. Or you can include the functional value of your button along with the custom data in a data container (e.g. a JSON string) in that field.
Serialization
All messages are transported through HTTP and mostly encoded as UTF-8 in JSON. So you want to serialize / de-serialize your data accordingly, especially if its binary data. If possible I would recommend to use JSON.
Length
The maximum allowed length of most fields is documented in the official Slack API documentation. e.g. for the value field for message buttons can contain up to 2.000 characters. Keep in mind that you need to consider the length of your data after serialization. e.g. if you convert binary data into Base64 so it can be transported with HTTP you will end up with about 1.33 characters for every byte.
Contents
In general I would recommend to keep your data container as small as possible and not include the actual data, but only IDs. Here are two common approaches:
Include IDs of your data objects and load the actual objects
from a data store when the request is later processed.
Include the ID of server session and when processing the request you
can restore the corresponding server session which contains all data
objects.
In addition you might need to include functional values so that the functionality of the field you are using still works (e.g. value of a menu option, see below)
Implementation
Dialogs
Dialogs provide an official field for custom data called state. Up to 3.000 characters.
Message buttons
For Message buttons you can use the message action fields / value. Up to 2.000 characters. Its also possible to use the name field, but I would advise against it, because the maximum allowed length of that field is not documented.
Message menus
For Message menus you can use the value field of an option or the name field of the menu action.
Usually the value field is the better approach, since you have a documented max length of 2.000 and it gives you more flexibility. However, you will need to combine you custom data with the actual functional value for each option. Also, this will not work for dynamic select elements (like users), where you can not control the value field.
When using the name field note, keep in mind that the maximum allowed length of name is not documented, so you want to keep you data as short as possible. Also, if you want to use more than one menu per attachment you need to include the actual name of the menu into your data container.
Normal message attachments
Normal message attachments do not contain any suitable field to be used as container for custom data, since all fields are linked to Slack functionality.
Technically you could use the fallback field, but only if you are 100% sure that your app is never used on a client that can not display attachments. Otherwise your data will be displayed to the user.

Setting properties while composing an Outlook Mail without forcing TNEF, and referring to those properties after sending

I am having a similar problem to the one described in this previously asked question, but I am looking for a bit more detail in the answer as my lack of experience in this area doesn't allow me to fill in some of the blanks:
Tag Outlook MailItem with ID number before send without causing TNEF (RTF) send
Like the asker of that question, I would like to set a User Property, say it's named "XXXX", to a MailItem while the user is composing it, so that when the user later revisits that same MailItem in his or her Sent Items folder I could read the "XXXX" property's value again.
My additional questions would be as follows:
Dmitry Streblechenko suggests using MailItem.PropertyAccessor.SetProperty, but wherever I see that used I see people using a schema link to represent the property. What would be the correct schema link to use if I want my property still to be known as "XXXX"? In other words, what would be the correct syntax to use in Dmitry's suggestion?
I gather I could use a ".GetProperty" call to read the property later from the Sent Items, but the problem is that our add-in has been around for years, and users sent items are already full of MailItems with the original UserProperty "XXXX" in them. Will I still be able to use UserProperties to get property "XXXX" even if I use .PropertyAccessor.SetProperty to set them?
Alternatively, if I kept using the original code to set UserProperties while composing the message, but I then used .PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8582000B", false) during the ItemSend, like the original poster is suggesting, then I understand the UserProperties are not sent out with the message, which is fine by me, but will they still be available when revisiting the message in the Sent Items folder? Eugene Astafiev suggests that it's safe to use that .SetProperty call, but he doesn't clarify whether it affects what happens to the message at the Sender's end.
My personal preference would be a solution that would a) allow me to send the item without having to force Outlook in any way to send the message in any particular format and b) be able to continue to access the properties in the users' inboxes as we always have through the MailItem's UserProperties, but I am aware that I may be asking for something impossible here.
You need a property in the PS_INTERNET_HEADERS namespace. E.g. http://schemas.microsoft.com/mapi/string/{00020386-0000-0000-C000-000000000046}/x-my-prop.
Yes if you specify the full DASL name.
Yes, the user property will still be there in the Sent Items folder.

Decode a YAML serialized object

I have serialized an object in YAML and send it to a remote worker.
The worker doesent have the object definition so i get a YAML::Object.
How can i access the field inside it?
A text field seems like that base64 encoded, how can i decode that? (no, decode64 not works).
you can pass the object as something "known between both sides" (like an openstruct or hash) or give the description to the client.
It would be interesting to have a serialization format that also serialized the class and its methods...I'll have to think about that one...
try c["bar"]
you can also see all the provided keys using c.keys

Resources