Graph API not returning file extension for MSG files - microsoft-graph-api

I am using the the following Graph API URL to retrieve the filename(s) attached to an email:
https://graph.microsoft.com/v1.0/me/messages/*/attachments
however, it is no longer returning the attached filename(s) for '.msg' files. The file extension is missing. Please see below example returns:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('')/messages('')/attachments",
"value": [
{
"#odata.type": "#microsoft.graph.itemAttachment",
"id": "*",
"lastModifiedDateTime": "2021-08-13T11:21:29Z",
"name": "Original Email",
"contentType": null,
"size": 45795,
"isInline": false
}
]
}
Where as it is for other file types:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('')/messages('')/attachments",
"value": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"#odata.mediaContentType": "application/octet-stream",
"id": "",
"lastModifiedDateTime": "2021-08-13T11:14:07Z",
"name": "Original Email.mht",
"contentType": "application/octet-stream",
"size": 54693,
"isInline": false,
"contentId": null,
"contentLocation": null,
"contentBytes": ""
}
]
}
NB: sensitive info has been redacted (*).
I can see that the #odata.type is returned differently:
#odata.type": "#microsoft.graph.itemAttachment
#odata.type": "#microsoft.graph.fileAttachment
I'm not sure why this is, the email is attached in the same way.
In both of the above cases, using Outlook, I sent myself an email, saved it to my local filesystem, created another email, attached the previously saved file and sent myself the new email with the saved email attached. Then made the request using the stated URL (and many other variations).
I have looked all over and no request URL that I have used returns the file extension for this type.
Is there a way to return the filename for '.msg' files?

Edit: this is how (java) I'm getting the filename for Attachment(s) (except ReferenceAttachment as I'm not handling them)
public String getCurrentAttachmentName()
{
String fileName = null;
if (currentAttachment instanceof FileAttachment)
{
fileName = currentAttachment.name;
} else if (currentAttachment instanceof ItemAttachment)
{
if (null != currentAttachment.contentType)
{
fileName = currentAttachment.name;
} else
{// outlook email or contact etc., add extension
ItemAttachment itemAttachment = (ItemAttachment) currentAttachment;
if (itemAttachment.item instanceof Contact)
{
fileName = currentAttachment.name + ".vcf";
} else if (itemAttachment.item instanceof Message)
{
fileName = currentAttachment.name + ".eml";
} else if (itemAttachment.item instanceof Event)
{
fileName = currentAttachment.name + ".ics";
} else
{
fileName = currentAttachment.name + ".bin"; // should be unreachable but just in case.
}
}
}
// looping does not allow ReferenceAttachment so we don't need to handle that type
return fileName;
}

MS graph differentiates the attachments at resource level ie fileAttachment resource type and itemAttachment resource type
Even though attached the same way, the contact, event, or message attachments belong to itemAttachment resource type and have different props from the file attachments.

Related

GUPSHUP send template message with attachment

I am trying to send a template message via gupshup using their unified single sendmessage API endpoint https://api.gupshup.io/sm/api/v1/msg
We have a template message approved with the relevant wording in it, and specified that there should be an attachment. When we try and send the attachment it fails with the following message, (1005) Message sending failed as user is inactive for session message and template did not match
Within the message element which is encoded JSON I have tried the a couple of options, all of which reject with the same message as above.
innerJson = { "isHSM": "true", "type": "file", "url": fileURL + location, "filename": filename, "text": message }
innerJson = { "isHSM": "true", "type": "file", "url": fileURL + location, "filename": filename, "caption": message }
innerJson = { "type": "file", "url": fileURL + location, "filename": filename, "text": message }
innerJson = { "type": "file", "url": fileURL + location, "filename": filename, "caption": message }
Can't find any explicit examples in the gupshup documentation of how to do this.
I send you a link with the correct endpoint for sending templates.
Also here's an example of how to use it in node.js:
const sendTemplateWhatsapp = (templateId, phone, media, callbackFunc) => {
innerJson = { "type":"file","url":"your_url" }
const params = new URLSearchParams()
params.append('channel', 'whatsapp');
params.append('source', waba_number);
params.append('destination', phone);
params.append('src.name', waba_name);
params.append('template', templateId);
params.append('message', JSON.stringify(innerJson));
const config = {
headers: {
'apikey': 'your_apikey',
'Content-Type': 'application/x-www-form-urlencoded'
}
}
axios.post('http://api.gupshup.io/sm/api/v1/template/msg', params, config)
.then((result) => {
console.log('Template sent to whatsapp');
callbackFunc(result.data);
})
.catch((err) => {
console.log(err);
callbackFunc(err);
})
}
Hope this helps

Unable to get attributes value from inbound MMS "messageAdded" event's payload

const manager = Manager.getInstance()
manager.chatClient.on('messageAdded', payload => {
console.log('payload', payload) // it is correct
console.log('payload state attributes', payload.state.attributes)
})
Attributes are correct on chrome's console log
{
"body": "",
"media": null,
"attributes": {
"media": "https://api.twilio.com/2010-04-01/Accounts/ACfba1ba518fcc2321c11142f4041efa23/Messages/MM762e5ab98a2adde2970303db9ab6f4ba/Media/ME77ada464c9d50d6441501abf7bbd45c3",
"mediaType": "image/jpeg"
},
}
But with payload.state.attributes, the attributes changed to:
{
"proxied": true
[[Prototype]]: Object
}
Finally, figured it out after reading the Twilio flex "source code" from "node_module". If reason of "attributes" included from "updateReasons", then we can get the { media, mediaType } from "message.state.attributes".
I cannot find this mentioned anywhere from Twilio's documents.
manager.chatClient.on('messageUpdated', ({ message, updateReasons }) => {
console.log('message', message)
console.log('updateReasons', updateReasons)
})

Jira API: Add Comment Using Edit Endpoint

Jira has a an /edit endpoint which can be used to add a comment. There is an example in their documentation that suggests this input body to accomplish this:
{
"update": {
"comment": [
{
"add": {
"body": "It is time to finish this task"
}
}
]
}
}
I create the exact same input in my Java code:
private String createEditBody() {
JsonNodeFactory jsonNodeFactory = JsonNodeFactory.instance;
ObjectNode payload = jsonNodeFactory.objectNode();
ObjectNode update = payload.putObject("update");
ArrayNode comments = update.putArray("comment");
ObjectNode add = comments.addObject();
ObjectNode commentBody = add.putObject("add");
commentBody.put("body", "this is a test");
return payload.toString();
}
but when I send this PUT request I get an error saying that the "Operation value must be of type Atlassian Document Format"!
Checking the ADF format it says that "version", "type" and "content" are required for this format. So although their documentation example doesn't seem to be ADF format, I'm trying to guess the format and change it. Here's what I accomplished after modifying my code:
{
"update": {
"comment": [
{
"add": {
"version": 1,
"type": "paragraph",
"content": [
{
"body": "this is a test"
}
]
}
}
]
}
}
the add operation seems to be an ADF but now I get 500 (internal server error). Can you help me find the issue?
Note that the above example from Atlassian documentation is for "Jira Server Platform" but the instance I'm working with is "Jira Cloud Platform" although I think the behaviour should be the same for this endpoint.
after tinkering with the input body, I was able to form the right request body! This will work:
{
"update": {
"comment": [
{
"add": {
"body": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "this is a test"
}
]
}
]
}
}
}
]
}
}
The annoying things that I learned along the way:
Jira's documentation is WRONG!! Sending the request in their example will fail!!
after making a few changes, I was able to get 204 from the endpoint while still comment was not being posted! And I guessed that the format is not correct and kept digging! But don't know why Jira returns 204 when it fails!!!

TFS Attachement size 0KB via REST Call

Whenever i tried to attach attachment with TFS WorkItem via REST call, attachment size is 0KB.
First I upload an attachment in Attachment Store using below code.
https://{instance}/DefaultCollection/_apis/wit/attachments?api-version=1.0&filename="{fileName}"
I send data in bytes array through rest call. and after this i attach that attachment with workitem.
Attaching attachment is success but size of an attachment is zero KB
Is there is an issue with TFS or something i am doing wrong?
I am using C# language for programming and REST Sharp for accessing VSTS APIs
Dim restClient = New RestClient("Server URL")
restClient.Authenticator = New HttpBasicAuthenticator("UserId", "Password")
Dim request = New RestRequest("API_Name", Method.POST)
request.AlwaysMultipartFormData = False
request.AddParameter(String.Format("{0}; charset=utf-8", contentType), File.ReadAllBytes(filePath), ParameterType.RequestBody)
request.RequestFormat = DataFormat.Json
Dim response As IRestResponse = restClient.Execute(request)
Return response
I am sending file data in bytes.
Attaching Attachment with WorkItem.
Dim restClient = New RestClient(ACCESS_URL)
restClient.Authenticator = New HttpBasicAuthenticator(USER_NAME, PASSWORD)
Dim request = New
RestRequest("CollectionName}/_apis/wit/workitems/{WorkItem_ID}", Method.PATCH)
request.AddParameter("application/json-patch+json; charset=utf-8",
"post_Data", ParameterType.RequestBody)
request.RequestFormat = DataFormat.Json
Dim response As IRestResponse = restClient.Execute(request)
Return response
Post_Data is an json string which take this type of data
[{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "AttachementURI",
}]
You missed "attributes" section in the Post_Data, try with below:
[{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "AttachementURI",
"attributes": {
}
}]
I can reproduce this issue when keep the { file-contents } as empty.
So, make sure you have specified the { file-contents }.
To attach a file to a work item, upload the attachment to the
attachment store, then attach it to the work item. See Add an attachment for details.
Upload an attachment:
POST https://{instance}/DefaultCollection/_apis/wit/attachments?api-version={version}&filename=Spec.txt
Content-Type: application/octet-stream
{ file-contents }
Add an attachment for specific work item:
PATCH https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/workitems/299?api-version=1.0
Content-Type: application/json-patch+json
[
{
"op": "test",
"path": "/rev",
"value": 3
},
{
"op": "add",
"path": "/fields/System.History",
"value": "Adding the necessary spec"
},
{
"op": "add",
"path": "/relations/-",
"value": {
"rel": "AttachedFile",
"url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/wit/attachments/098a279a-60b9-40a8-868b-b7fd00c0a439?fileName=Spec.txt",
"attributes": {
"comment": "Spec for the work"
}
}
}
]
See below C# sample to upload and add the attachment for a work item:
C# (UploadTextFile method)
C# (AddAttachment method)

How to retrieve contents of an itemAttachment via the Microsoft Graph API

I'm currently developing a solution which is retrieving e-mails via the Microsoft Graph API. In november 2015 Microsoft stated it is ready for production and I've read in another forum post that if you start now on developing using a Microsoft API, you should use the Graph API, since it is the future.
Everything is going well except for one thing and that is the following.
I must retrieve e-mails. Inside these e-mails there are of course attachments. These attachments come in some variaties. fileAttachment (images, documents etc.), referenceAttachments and itemAttachments (outlook-item). The issue here is with the itemAttachments. An itemAttachment can be anything from an appointment to another message. The problem here is that I'm not able to get and retrieve the contentBytes in some way which is working for fileAttachments. A related object to itemAttachment is outlookItem. There is also a page with a description made for this outlookItem, but the examples and the details are missing.
The user rights are set to Mail.Read and Mail.ReadWrite.
Links:
General overview: http://graph.microsoft.io/docs/overview/overview
Get outlookItem (empty?):
Example call and response I get. Please note the types of the attachments.
https://graph.microsoft.com/v1.0 /users/ /messages/ /attachments
{
"#odata.context": "link",
"value": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAGhN_vm1RlBPt7V4N9a89UY=",
"lastModifiedDateTime": "2016-01-13T14:25:33Z",
"name": "image001.png",
"contentType": "image/png",
"size": 5077,
"isInline": true,
"contentId": "image001.png#01D14E16.A3A32480",
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAIAAABOyVRHAAAAAXNSR0IArs4c6QAAEndJREFUeF7tXQ1QFFe2bkbU... (truncated)"
},
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAFnSLgIC5wZOosmLtBWK8gE=",
"lastModifiedDateTime": "2016-01-13T14:25:34Z",
"name": "image002.png",
"contentType": "image/png",
"size": 3722,
"isInline": true,
"contentId": "image002.png#01D14E16.A3A32480",
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAPoAAABSCAYAAAB9o8m+AAAAGXRFWHRTb... (truncated)"
},
{
"#odata.type": "#microsoft.graph.fileAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQANOuw7m8sW1Ot3MivYQ5OYU=",
"lastModifiedDateTime": "2016-01-13T14:25:24Z",
"name": "Knipsel.PNG",
"contentType": null,
"size": 7641,
"isInline": false,
"contentId": null,
"contentLocation": null,
"contentBytes": "iVBORw0KGgoAAAANSUhEUgAAAKAAAACCCAYAAADBq8MQAAA... (truncated)"
},
{
"#odata.type": "#microsoft.graph.itemAttachment",
"id": "AAMkAGU2NmIwMTcxLTljYzUtNGRiMi1hZjczLTllNzhiZDRiNWZlZABGAAAAPAD_Lx_gimDGRqSr98J_O_e6BwDcWyYHlO7rS5_XpLHCx6NSAAIMC0V-AADcWyYHlO7rS5_XpLHCx6NSAAIMC6RgAAABEgAQAPEUC740tjtAlNTe8NpopUI=",
"lastModifiedDateTime": "2016-01-14T15:55:07Z",
"name": "RE: Test met plaatje",
"contentType": null,
"size": 36972,
"isInline": false
}
]
}
I've tried to change the GET-statement by pasting the attachment id with or without the messages path and the expand feature (which is only supported one level deep), but I can't seem te find the solution.
Something I've found is this question, which is kind of the same, however it is for the office365 unified API. How to retrieve ItemAttachment contents from Office 365 REST API?.
So, the question: How can I retrieve the contents of an outlookItem via the Microsoft Graph API? And how do I know what to expect? Can anybody help me getting past this obstacle.
Use $expand option:
GET https://graph.microsoft.com/v1.0/me/messages('AAMkADA1M-zAAA=')/attachments('AAMkADA1M-CJKtzmnlcqVgqI=')/?$expand=microsoft.graph.itemattachment/item
Response:
HTTP/1.1 200 OK
Content-type: application/json
{
"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments/$entity",
"#odata.type":"#microsoft.graph.itemAttachment",
"id":"AAMkADA1MCJKtzmnlcqVgqI=",
"lastModifiedDateTime":"2017-07-21T00:20:34Z",
"name":"Reminder - please bring laptop",
"contentType":null,
"size":32005,
"isInline":false,
"item#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users('d1a2fae9-db66-4cc9-8133-2184c77af1b8')/messages('AAMkADA1M-zAAA%3D')/attachments('AAMkADA1M-CJKtzmnlcqVgqI%3D')/microsoft.graph.itemAttachment/item/$entity",
"item":{
"#odata.type":"#microsoft.graph.message",
"id":"",
"createdDateTime":"2017-07-21T00:20:41Z",
"lastModifiedDateTime":"2017-07-21T00:20:34Z",
"receivedDateTime":"2017-07-21T00:19:55Z",
"sentDateTime":"2017-07-21T00:19:52Z",
"hasAttachments":false,
"internetMessageId":"<BY2PR15MB05189A084C01F466709E414F9CA40#BY2PR15MB0518.namprd15.prod.outlook.com>",
"subject":"Reminder - please bring laptop",
"importance":"normal",
"conversationId":"AAQkADA1MzMyOGI4LTlkZDctNDkzYy05M2RiLTdiN2E1NDE3MTRkOQAQAMG_NSCMBqdKrLa2EmR-lO0=",
"isDeliveryReceiptRequested":false,
"isReadReceiptRequested":false,
"isRead":false,
"isDraft":false,
"webLink":"https://outlook.office365.com/owa/?ItemID=AAMkADA1M3MTRkOQAAAA%3D%3D&exvsurl=1&viewmodel=ReadMessageItem",
"body":{
"contentType":"html",
"content":"<html><head>\r\n</head>\r\n<body>\r\n</body>\r\n</html>"
},
"sender":{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
},
"from":{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
},
"toRecipients":[
{
"emailAddress":{
"name":"Alex Wilbur",
"address":"AlexW#contoso.onmicrosoft.com"
}
}
],
"ccRecipients":[
{
"emailAddress":{
"name":"Adele Vance",
"address":"AdeleV#contoso.onmicrosoft.com"
}
}
]
}
}
Source: https://developer.microsoft.com/en-us/graph/docs/api-reference/v1.0/api/attachment_get#request-2
The official documentation: https://graph.microsoft.io/en-us/docs/api-reference/beta/api/attachment_get.htm . Use valid Bearer authentication access code, and check for appropriate Graph API permissions on the Azure management portal. Attachment is based64 encoded string, coming in the contentBytes field. Correct Uri for loading list of a message attachments is: https://graph.microsoft.com/beta/me/messages/[ message Id ]/attachments. Sample code to call attachments endpoint is below:
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Get,
"https://graph.microsoft.com/beta/me/messages/..id../attachments"))
{
request.Headers.Authorization =
new AuthenticationHeaderValue("Bearer", "...valid access token...");
using (HttpResponseMessage response = await client.SendAsync(request))
{
if (response.StatusCode == HttpStatusCode.OK)
{
result = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(result);
}
}
}
}
Get attachment using MS Graph API for Java:
First build the graph client. Sample code
ClientSecretCredential clientSecretCredential = new ClientSecretCredentialBuilder()
.clientId(yourClientId).clientSecret(yourClientSecret)
.tenantId(yourTenantId).build();
TokenCredentialAuthProvider tokenCredAuthProvider = new TokenCredentialAuthProvider(clientSecretCredential);
GraphServiceClient<Request> gClient = GraphServiceClient.builder().authenticationProvider(tokenCredAuthProvider)
.buildClient();
Either get all the attachments for a message-
FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments().buildRequest().get();
Or get a particular attachment by passing the attachment id:
FileAttachment fa = (FileAttachment) graphClient.users(id).messages(messageId).attachments(attachmentId).buildRequest().get();
//Copy file attachment into a File from byte stream using FileUtils.
FileUtils.writeByteArrayToFile(new File(yourFileLocation), fa.contentBytes);
You can also similarly either get all users, messages or attachments or pass particular id to get a unique result for these entities.

Resources