0

I'm trying to send images to a whatsapp user via Twilio, but I'm always getting 400 error

(400) Bad Request. -> {"code": 21620, "message": "Media urls: https://image-charts.com/chart?cht=pd&chd=a:10238,10200&chs=400x300&chdls=9e9e9e,10&chco=FFC00C,03A9F4&chtt=Ocupaci%C3%B3n%20en%20almac%C3%A9n&chdl=Contratado%7COcupado&chli=100.37%25&chl=10238%7C10200&chdlp=b&chof=.png are invalid. Please use only valid http and https urls", "more_info": "https://www.twilio.com/docs/errors/21620", "status": 400}

The image works fine in browser or when is send directly to the user directly in whatsapp

I'm encoding the image like this (js):

    img_url = encodeURI(img_url);

Any ideas or workaround?

thanks

  • Check this link: https://www.twilio.com/docs/api/errors Your error code refers to this message: 'Invalid media URL(s)'. Your media url was probably badly encoded, or Twilio for some reason cannot 'download' the image. – stfno.me Apr 20 '20 at 09:30

1 Answers1

0

It seems not every parameter was encoded, example: chd=a:10238,10200 should be chd=a%3A10238%2C10200.

encodeURI won't produce URL safe, you will need to rely on encodeURIComponent but it will encode the whole url ('/chart?' included) so it's not an option either.

If you are doing this server-side from NodeJS:

// node v10+
const url = require('url');
const querystring = require('querystring');

function encode_uri(chart_url) {
  const parsed_url = url.parse(chart_url);
  // parse the querytring and then encode every parameter values
  parsed_url.query = querystring.stringify(querystring.parse(parsed_url.query));
  // generate the full url
  return url.format({
    ...parsed_url,
    href:undefined,
    path:undefined,
    search:'?' + parsed_url.query,
  });
}


let chart_url = 'https://image-charts.com/chart?cht=pd&chd=a:10238,10200&chs=400x300&chdlp=b&chdls=9e9e9e,10&chco=FFC00C,03A9F4&chtt=Ocupación en almacén&chli=100.37%&chl=10238|10200&chdl=Contratado|Ocupado&chof=.png';
console.log(encode_uri(chart_url));

// Fully encoded URL
// https://image-charts.com/chart?cht=pd&chd=a%3A10238%2C10200&chs=400x300&chdlp=b&chdls=9e9e9e%2C10&chco=FFC00C%2C03A9F4&chtt=Ocupaci%C3%B3n%20en%20almac%C3%A9n&chli=100.37%25&chl=10238%7C10200&chdl=Contratado%7COcupado&chof=.png

If you are doing this on the browser side then use:

function encode_uri(chart_url) {
  // use https://developer.mozilla.org/en-US/docs/Web/API/URL
  // not supported in IE10
  const parsed_url = new URL(chart_url); 

  // encode every parameter values
  [...parsed_url.searchParams.keys()].forEach(key => parsed_url.searchParams.set(key, encodeURIComponent(parsed_url.searchParams.get(key))));

  // generate back the full url
  return parsed_url.toString();
}

let chart_url = 'https://image-charts.com/chart?cht=pd&chd=a:10238,10200&chs=400x300&chdlp=b&chdls=9e9e9e,10&chco=FFC00C,03A9F4&chtt=Ocupación en almacén&chli=100.37%&chl=10238|10200&chdl=Contratado|Ocupado&chof=.png';

console.log(encode_uri(chart_url));
// https://image-charts.com/chart?cht=pd&chd=a%253A10238%252C10200&chs=400x300&chdlp=b&chdls=9e9e9e%252C10&chco=FFC00C%252C03A9F4&chtt=Ocupaci%25C3%25B3n%2520en%2520almac%25C3%25A9n&chli=100.37%2525&chl=10238%257C10200&chdl=Contratado%257COcupado&chof=.png
FGRibreau
  • 7,021
  • 2
  • 39
  • 48