Question

Request to create custom user greeting returns socket hang up error

  • 15 August 2022
  • 4 replies
  • 374 views

I am attempting to migrate the part of my app for creating a custom user greeting from using a local file to using a file publicly hosted online. Here is my current code:


async function create_greeting() {
  try {
    let FormData = require('form-data');
    formData = new FormData();
    let body = {
        type: "Introductory",
        answeringRule: {id: "3839201036"}
    }
 
    formData.append('json', new Buffer.from(JSON.stringify(body)), {
          filename: 'request.json',
          contentType: 'application/json'
          });
 
    formData.append('binary', fs.createReadStream('URL_to_file'));
    let resp = await platform.post('/restapi/v1.0/account/~/extension/2896037036/greeting?apply=true', formData);
    let jsonObj = await resp.json()
      .then(() => console.log(JSON.stringify(jsonObj)));
  } catch(e) {
    console.log(e.message)
  }
}

When I changed the file reference on line 15 from a local file path to a public URL I got the following response: "request to https://platform.ringcentral.com/restapi/v1.0/account/~/extension/2896037036/greeting?apply=true failed, reason: socket hang up". How do I change the function to use a web-hosted file? Language is Node.js and I am using Google Cloud Storage to host the file.


4 replies

Userlevel 1

Google does not allow accessing its Cloud Storage that way. Ask Google support or search on the stack overflow such as this one to learn how to download or read to a stream.

https://stackoverflow.com/questions/71097537/how-to-download-file-from-google-cloud-storage

After referencing that article and the Google Cloud Storage documentation I can't get the create greeting endpoint to accept the data downloaded into memory. For the purposes of this app, downloading to a file is not an option. Here is my current code:

  1. async function downloadIntoMemory() {
  2. // Downloads the file into a buffer in memory.
  3. const contents = await storage.bucket(bucketName).file(destFileName).download();
  4.  
  5. console.log(
  6. `Contents have been downloaded`
  7. );
  8.  
  9. //console.log(Buffer.from(contents.toString()).toString());
  10. create_greeting(contents.toString('binary'));
  11. }
  12.  
  13. async function create_greeting(data) {
  14. try {
  15. let FormData = require('form-data');
  16. formData = new FormData();
  17. let body = {
  18. type: "Introductory",
  19. answeringRule: {id: "3839201036"}
  20. }
  21. formData.append('json', new Buffer.from(JSON.stringify(body)), {
  22. filename: 'request.json',
  23. contentType: 'application/json'
  24. });
  25. formData.append('binary', fs.createReadStream(data));
  26. let resp = await platform.post('/restapi/v1.0/account/~/extension/2896037036/greeting?apply=true', formData);
  27. let jsonObj = await resp.json()
  28. .then(() => console.log(JSON.stringify(jsonObj)));
  29. } catch(e) {
  30. console.log(e.message)
  31. }
  32. }
  33.  
  34. downloadIntoMemory().catch(console.error);

When I run this code I get the error: "The argument 'path' must be a string or Uint8Array without null bytes". How can I change the data buffer from the Cloud Storage download into an acceptable format?

After reviewing the article and the Google Cloud Storage documentation, I can't get the FormData to accept the data downloaded into a buffer. I've tried the raw buffer data, converting to string, converting to binary, and I can't get it to accept the data format. For the purposes of this app, downloading to a file is not an option. Here is my current code:


async function downloadIntoMemory() {
  // Downloads the file into a buffer in memory.
  const contents = await storage.bucket(bucketName).file(destFileName).download();

  console.log(
    `Contents have been downloaded`
  );

  //console.log(Buffer.from(contents.toString()).toString());
  create_greeting(contents.toString('binary'));
}

async function create_greeting(data) {
    try {
      let FormData = require('form-data');
      formData = new FormData();
      let body = {
          type: "Introductory",
          answeringRule: {id: "3839201036"}
      }
   
      formData.append('json', new Buffer.from(JSON.stringify(body)), {
            filename: 'request.json',
            contentType: 'application/json'
            });
   
      formData.append('binary', data);
      let resp = await platform.post('/restapi/v1.0/account/~/extension/2896037036/greeting?apply=true', formData);
      let jsonObj = await resp.json()
        .then(() => console.log(JSON.stringify(jsonObj)));
    } catch(e) {
      console.log(e.message)
    }
}


When I run this code, I get the error: "Invalid attachment media type". When I run the code but with fs.createReadStream(data) instead, I get this error: "The argument 'path' must be a string or Uint8Array without null bytes. Received 'ID3x04x00x00x00x00x00x1CTSSEx00x00x00x00x00x03Googlex00x00x00x00x00x00x00x00x00x00x00Dx00x00x00...". How can I get it to accept the data type without creating a file?

After referencing that article and the Google Cloud Storage documentation I can't get the create greeting endpoint to accept the data downloaded into memory. For the purposes of this app, downloading to a file is not an option. Here is my current code:

  1. async function downloadIntoMemory() {
  2. // Downloads the file into a buffer in memory.
  3. const contents = await storage.bucket(bucketName).file(destFileName).download();
  4.  
  5. console.log(
  6. `Contents have been downloaded`
  7. );
  8.  
  9. //console.log(Buffer.from(contents.toString()).toString());
  10. create_greeting(contents.toString('binary'));
  11. }
  12.  
  13. async function create_greeting(data) {
  14. try {
  15. let FormData = require('form-data');
  16. formData = new FormData();
  17. let body = {
  18. type: "Introductory",
  19. answeringRule: {id: "3839201036"}
  20. }
  21. formData.append('json', new Buffer.from(JSON.stringify(body)), {
  22. filename: 'request.json',
  23. contentType: 'application/json'
  24. });
  25. formData.append('binary', fs.createReadStream(data));
  26. let resp = await platform.post('/restapi/v1.0/account/~/extension/2896037036/greeting?apply=true', formData);
  27. let jsonObj = await resp.json()
  28. .then(() => console.log(JSON.stringify(jsonObj)));
  29. } catch(e) {
  30. console.log(e.message)
  31. }
  32. }
  33.  
  34. downloadIntoMemory().catch(console.error);

When I run this code I get the error: "The argument 'path' must be a string or Uint8Array without null bytes. Received 'ID3x04x00x00x00x00x00x1CTSSEx00x00x00x00x00x03Googlex00x00x00x00x00x00x00x00x00x00x00Dx00x00x00...". How can I change the data buffer from the Cloud Storage download into an acceptable format?

Reply