4.4
Directline is returning a default placeholder after uploading an image, causing the image to break in the webchat ui.
Use the Web Chat to upload an image using directline:

After we upload the image we shouldn't get an activity message from directline with a default placeholder, it should keep the valid url so it doesn't break image displayed in the webchat ui.
[bug]
A couple questions:


Hey there! Is there any update on this issue? It is currently impacting many of our solutions. Are there any workarounds?
Possibly related to https://github.com/microsoft/BotFramework-WebChat/issues/2138
Hey Jamie, here is the client side work around we discussed. If you have any questions, feel free to ask them here.
• We should respect aspect ratio and limit the size to maximum 480px
• We should downscale image only, and leave non-image files as-is
• This works with multiple attachments
(async function () {
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
const { token } = await res.json();
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => handleWebChatUpload(next, action));
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
store
}, document.getElementById('webchat'));
function eventToPromise(target, name) {
return new Promise((resolve, reject) => {
const handler = event => {
target.removeEventListener(name, handler);
resolve(event);
};
target.addEventListener(name, handler);
});
}
async function downscaleImage(imageURL, contentType, maxSize) {
const image = document.createElement('img');
const imageLoadPromise = eventToPromise(image, 'load');
image.src = imageURL;
await imageLoadPromise;
const canvas = document.createElement('canvas');
canvas.height = image.height > image.width ? maxSize : ~~(image.height / image.width * maxSize);
canvas.width = image.width > image.height ? maxSize : ~~(image.width / image.height * maxSize);
canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL(contentType);
return dataURL;
}
async function handleWebChatUpload(next, action) {
if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
if (action.payload.activity && action.payload.activity.attachments) {
const downscaledImages = await Promise.all(
action.payload.activity.attachments.map(
({ contentType, contentUrl }) => /^image\//.test(contentType) ? downscaleImage(contentUrl, contentType, 480) : null
)
);
(action.payload.activity.channelData || (action.payload.activity.channelData = {})).thumbnails = downscaledImages;
}
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
const activity = action.payload.activity;
if (activity && activity.attachments && activity.channelData && activity.channelData.thumbnails) {
action.payload.activity.attachments = activity.attachments.map((attachment, index) => ({
...attachment,
contentUrl: activity.channelData.thumbnails[index] || attachment.contentUrl
}));
}
}
return next(action);
}
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
The WebChat team is tracking this work on https://github.com/microsoft/BotFramework-WebChat/issues/2138 - we'll keep this open as a duplicate until #2138 is resolved.
Closing as resolved :)
Most helpful comment
Hey Jamie, here is the client side work around we discussed. If you have any questions, feel free to ask them here.
• We should respect aspect ratio and limit the size to maximum 480px
• We should downscale image only, and leave non-image files as-is
• This works with multiple attachments