Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to upload an image from a URL #1107

Closed
BurnyBoi opened this issue Dec 8, 2019 · 17 comments
Closed

How to upload an image from a URL #1107

BurnyBoi opened this issue Dec 8, 2019 · 17 comments

Comments

@BurnyBoi
Copy link

BurnyBoi commented Dec 8, 2019

Similar to what is being done in #238, I am trying to take an image url, and pipe the image into uploadContent(). Here is what I am testing with:

var infoMatrix = {
		    "name": "test",
		    "type": "image/jpg",
		    "rawResponse": 0,
		    "onlyContentUri": 1
		};
		
		request.get("http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg", function(err, res, body){
			
			matrixClient.uploadContent(body, infoMatrix).done(function(url) {
		                
				console.log(url);
				var content = {
		                    msgtype: "m.image",
		                    body: "difhsiudfhvos.jpg",
		                    url: url
		                };
		                matrixClient.sendMessage(room.roomId, content);
            		});
			
		});

When I run this, it runs the command without any errors, but the message does not have the image, just a blank file:

2019-12-08_14-36-30_283x64_scrot
Attempting to click download does not show the file either. It just says: "The image cannot be displayed because it has errors." Could I get some clarification on how to accomplish this?

@turt2live
Copy link
Member

This issue tracker is not a great place to get support - please visit #matrix-dev:matrix.org instead to get some help with the js-sdk.

@scottwestover
Copy link

@BurnyBoi I was also having the same issue. I was finally able to get the uploadContent method to work. Hopefully this helps you:

const axios = require('axios');
const MatrixJsSdk = require('matrix-js-sdk');

(async () => {
  const url = 'http://i3.ytimg.com/vi/J---aiyznGQ/mqdefault.jpg';
  try {
    const imageResponse = await axios.get(url, { responseType: 'arraybuffer' });
    const imageType = imageResponse.headers['content-type'];
    const matrixClient = MatrixJsSdk.createClient('http://localhost:8008');
    await matrixClient.login('m.login.password', {
      password: 'foo',
      user: '@bob:synapse',
    });
    const uploadResponse = await matrixClient.uploadContent(imageResponse.data, { rawResponse: false, type: imageType });
    const matrixUrl = uploadResponse.content_uri;
    console.log(matrixUrl);
    const sendImageResponse = await matrixClient.sendImageMessage('!JIsalWHQCskeFGvtZs:synapse', matrixUrl, {}, '');
    console.log(sendImageResponse);
  } catch (error) {
    console.log(error);
  }
})();

Screen Shot 2019-12-11 at 12 22 53 PM

@mmeksasi
Copy link

mmeksasi commented Jun 9, 2021

You need to add in opts { onlyContentUri: false }
export const SendImageMessage = async ({ url, roomID, info, text }) => {
try {
const imageResponse = await axios.get(url, { responseType: 'arraybuffer' });
const imageType = imageResponse.headers['content-type'];
const uploadResponse = await matrixAlias.uploadContent(imageResponse.data, {
rawResponse: false,
type: imageType,
onlyContentUri: false,
});
const matrixUrl = uploadResponse.content_uri;
const result = await matrixAlias.sendImageMessage(
roomID,
matrixUrl,
info,
text
);
console.log('SEND MESSAGE IMAGE RESULT ', result);
} catch (err) {
console.log('SEND MESSAGE IMAGE ERROR ', err);
}
};

@oelison
Copy link

oelison commented Jul 27, 2022

Why give a hint to a chat group and not improve or at least check the documentation and close it?

@nukeop
Copy link

nukeop commented Jul 16, 2023

This is horrible. Why does it need so much manual work? The bot sdk is even worse. Why can't it be a single line to upload an image? That's a very common use case.

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

Because downloading an image isn't easy in certain Javascript environments. Like web with CORS.

@nukeop
Copy link

nukeop commented Jul 16, 2023

How does that influence poor sdk design?

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

The SDK has no consistent cross platform way to download an image that wasn't uploaded to matrix to begin with. So you need to download it yourself. As for why uploading content and sending an event is separate is that it's very different for encrypted events. So having a single method only usable for unencrypted events would be very inconsistent SDK design.

@nukeop
Copy link

nukeop commented Jul 16, 2023

You know in Discord it only takes a single line: https://discordjs.guide/popular-topics/embeds.html#using-the-embed-constructor

You only need to give it a link to the image you want to embed. Why can't matrix do it?

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

Discord doesn't support encryption. Discord can also have their server accept a url and just use that as media. Matrix API doesn't support that. Makes for a much thicker SDK. They're not really comparable other than on the UX or surface level.

@nukeop
Copy link

nukeop commented Jul 16, 2023

I don't get it, what does encryption change here? It's unrelated to SDK or API design.

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

Encryption requires you to generate a thumbnail or poster frame client side which is very difficult to do in one way cross platform. Super easy to do in the web, hard to do in Node or Deno which can't render these medias. The SDK has wide Javascript runtime support which means it doesn't have web specific or node specific or any other specific code.

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

Unless you want an api which looks like

Client.sendImage(downloadFn, thumbnailFn, room Id)

Where you pass callbacks on how to perform the download and thumbnailing in your specific environment.

@nukeop
Copy link

nukeop commented Jul 16, 2023

Why can't the server do it? This is not my problem, as a consumer of the API.

@t3chguy
Copy link
Member

t3chguy commented Jul 16, 2023

The server can't generate thumbnails for encrypted media to which it has no keys. That's the whole point of end to end encryption.

@nukeop
Copy link

nukeop commented Jul 16, 2023

How about in rooms with no encryption? That seems like a serious anti-feature

@t3chguy
Copy link
Member

t3chguy commented Jul 17, 2023

@nukeop in such a case a one-liner doing both upload (local file/buffer) and send would be feasible, but having to use a very different API depending on if a room is encrypted or not sounds like poor SDK design. As for the case of wanting the SDK to handle uploading files from a URL it'd want something like matrix-org/matrix-spec-proposals#2370

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants