Emil Svensson
Emil Svensson

Reputation: 41

Preview image attachments in ChatMessage

We are using the ms graph api to post messages to a teams channel from a internal desktop application. The main purpose is to attach images to the message. We upload the image files into the one-drive folder of the channel as shown below.


                var uploadProps = new DriveItemUploadableProperties
                {
                    ODataType = null,
                    AdditionalData = new Dictionary<string, object>
                    {
                        { "@microsoft.graph.conflictBehavior", "replace" }
                    }
                };


                var session = await graphClient.Drives[driveId]
                    .Items[parentId].ItemWithPath(fileName).CreateUploadSession(uploadProps).Request().PostAsync(token);

                int maxSliceSize = 320 * 1024;

                var fileUploadTask =
                    new LargeFileUploadTask<DriveItem>(session, fileStream, maxSliceSize);

                // Create a callback that is invoked after each slice is uploaded
                IProgress<long> progress = new Progress<long>(reportAsync);

                // Upload the file
                var uploadResult = await fileUploadTask.UploadAsync(progress);

                if (uploadResult.UploadSucceeded)
                {
                    return uploadResult.ItemResponse;
                }

We then send a message to the channel and attach the images uploaded previously as reference attachments.

var chatMsg = new ChatMessage();

chatMsg.Body = new ItemBody();
chatMsg.Body.ContentType = BodyType.Html;
chatMsg.Body.Content = msg + " " + string.Join(" ", attachments.Select(d => $"<attachment id=\"{parseEtag(d.ETag)}\"></attachment>"));

chatMsg.Attachments = attachments.Select(d => new ChatMessageAttachment()
{
   Id = parseEtag(d.ETag),
   ContentType = "reference",
   ContentUrl = d.WebUrl,
   Name = d.Name
});

return await this.graphClient.Teams[teamId].Channels[channelId].Messages
                .Request()
                .AddAsync(chatMsg, token);

The problem is that the message only shows the names of the attachments with no preview as seen in the message at the bottom. We want to have a preview as seen (top message) when attaching a file within the teams application.

Imgur

We've tried to set the thumbnailurl property of the attachment to the thumbnail url fetched from the ms-graph api with no success.

We've uploaded a file using the teams application (with preview) and then created an identical message with the same file (same driveitem id) in our application (show's no preview). Then we fetched both messages using the graph api and could not discern any differences between the two besides the message id's ofc.

We've scoured these forums, the ms documentations and even suggestion pages and found nothing.

We have been able to show previews separately in the body of the message referencing the thumbnail urls and in messagecards but ideally we want the preview directly in the attachments.

EDIT

The thumbnail urls seem to expire after 24 hours and are therefor not a great solution.

Upvotes: 4

Views: 1235

Answers (1)

Mtjody
Mtjody

Reputation: 41

We managed to solve exactly this problem using the Simple Upload Api, with the added ?$expand=thumbnails query parameter. I haven't tried but the query param ought to work for the endpoint you're using as well.

Pick a size from the ThumbnailSet in the upload response and add it to the body of your message as an image tag. See below:

// channel, file, extractIdFromEtag, message omitted for brevity.

// PUT /groups/{group-id}/drive/items/{parent-id}:/{filename}:/content
const uploadUrl = `https://graph.microsoft.com/beta/groups/${channel.teamId}/drive/items/root:/${channel.displayName}/${file.name}:/content?$expand=thumbnails`;
const res = await this.http.put(uploadUrl, file).toPromise(); // FYI Using Angular http service

const attachment = {
  id: extractIdFromEtag(res.eTag),
  contentType: 'reference',
  contentUrl: res.webUrl,
  name: res.name,
  thumbnailUrl: res.webUrl
};

const postBody = {
  subject: null,
  body: {
    contentType: 'html',
    content: message
  },
};
// This is what makes the image show in the message as if posted from teams
postBody.body.content += `<br><br><img src="${res.thumbnails[0].large.url}" alt="${res.name}"/>`;

const messageUrl = `https://graph.microsoft.com/beta/teams/${channel.teamId}/channels/${channel.id}/messages`;
const result = await this.http.post(messageUrl, postBody).toPromise();
// Done

You can also keep adding the attachment as you already do, if you want the original image attached as a file, as well as showing the image preview in the message.

Upvotes: 1

Related Questions