Hello everyone, I need help in uploading PDF files...
# general
y
Hello everyone, I need help in uploading PDF files (file may contain images, special characters, text) to file cabinet folder using restlet/suitelet/suitetalk api to netsuite, I am able to load CSV, however pdf are giving error. Can someone please help?? Thanks,
b
netsuite expects base64 encoding to be used for bainary content like pdfs
from both the suitescript and suitetalk apis
y
I am using the below suitelet
Copy code
/**
 * @NApiVersion 2.x
 * @NScriptType Suitelet
 */
define(['N/file', 'N/record', 'N/runtime', 'N/encode', 'N/log'], function(file, record, runtime, encode, log) {
    function onRequest(context) {
        if (context.request.method === 'POST') {
            try {
                // Log the entire request for debugging
                log.debug('Request Details', JSON.stringify(context.request));

                var base64Content = context.request.parameters.fileContent; // assuming the base64 content is sent with the key 'fileContent'
                if (!base64Content) {
                    throw new Error("Base64 content is missing");
                }

                var decodedContent = encode.convert({
                    string: base64Content,
                    inputEncoding: encode.Encoding.BASE_64,
                    outputEncoding: encode.Encoding.UTF_8
                });
                
                var fileName = context.request.parameters.fileName; // assuming the file name is sent with the key 'fileName'
                if (!fileName) {
                    throw new Error("File name is missing");
                }

                var fileType = file.Type.PDF; // modify this as per your file type

                var uploadFile = file.create({
                    name: fileName,
                    fileType: fileType,
                    contents: decodedContent,
                    folder: 8977501 // Specify your folder ID here
                });
                var fileId = uploadFile.save();

                // Load the file to get its URL
                var fileRecord = file.load({
                    id: fileId
                });
                var fileUrl = fileRecord.url;

                context.response.write({
                    output: 'Success! File uploaded. File ID: ' + fileId + ', File URL: ' + fileUrl
                });
            } catch (e) {
                log.error('Error in Suitelet', e.toString());
                context.response.write({
                    output: 'Error: ' + e.toString()
                });
            }
        }
    }

    return {
        onRequest: onRequest
    };
});
and function to post pdf using python:
Copy code
def upload_to_ns(file_name, base64_data, folder_id, logger):
    NS_URL = secrets['restletapi']['ns_url2']

    oauth = OAuth1(C_KEY,
                    client_secret=C_SECRET,
                    resource_owner_key=A_TOKEN,
                    resource_owner_secret=A_SECRET,
                    signature_method='HMAC-SHA256',
                    realm=REALM)
    
    headers = {
        'prefer': 'transient',
        'Content-Type': 'application/json',
        'Cookie': 'NS_ROUTING_VERSION=LAGGING'
    }

    
    url = NS_URL


    payload = {
    'fileName': file_name,
    'fileContent': base64_data.decode()
}


    
    try:
        <http://logger.info|logger.info>(f"Attempting to upload {file_name} to NetSuite folder with ID - {folder_id}")

#        response = <http://requests.post|requests.post>(url, auth=oauth, headers=headers, files=payload)
        response = <http://requests.post|requests.post>(url, auth=oauth, headers=headers, json=payload)
                
        response.raise_for_status()  # raise an HTTPError if the response status is not 2xx

        # Process the response
        if response.status_code == 200:
            response_json = response.json()

            print("\nUpload Result:")
            print(response_json["output"])

    except requests.exceptions.HTTPError as errh:
        logger.error(f"HTTP error occurred while uploading {file_name} to NetSuite. error : {errh}")
        raise
    except requests.exceptions.ConnectionError as errc:
        logger.error(f"Error Connecting while uploading {file_name} to NetSuite. error : {errc}")
        raise
    except requests.exceptions.Timeout as errt:
        logger.error(f"Timeout Error while uploading {file_name} to NetSuite. error : {errt}")
        raise
    except requests.exceptions.RequestException as err:
        logger.error(f"Error occurred while uploading {file_name} to NetSuite. error : {err}")
        raise



# --- Time --- #
def get_time():
    _now = datetime.datetime.now()
    _d1 = now.strftime("%Y%m%d%H%M%S_%f")[:-3]
    return _d1

# ------------ Related to Logging ---------- #
_time = get_time()
log_file_name = "upload_to_ns_"+_time+".log"

# Set up the logger
logger = setup_logger(_name_, log_file_name)


# # --------- execute it -------- #
file_name = "Origin.pdf"

with open("Origin.pdf", "rb") as f:
        file_contents = f.read()
        base64_bytes = base64.b64encode(file_contents) # Here you should use file_contents, not f.read()

folder_id = "8856479"        
upload_to_ns(file_name, base64_bytes, folder_id, logger)
=============================
Error :
  File "/Users/yogi/Downloads/Vendors/Vendor_new_code/post_csv.py", line 185, in <module>
    upload_to_ns(file_name, base64_bytes, folder_id, logger)
  File "/Users/yogi/Downloads/Vendors/Vendor_new_code/post_csv.py", line 139, in upload_to_ns
    response.raise_for_status()  # raise an HTTPError if the response status is not 2xx
  File "/Users/yogi/Library/Python/3.10/lib/python/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: <https://xxxxxxxxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=1750&deploy=1>
Error : File "/Users/yogi/Downloads/Vendors/Vendor_new_code/post_csv.py", line 185, in <module> upload_to_ns(file_name, base64_bytes, folder_id, logger) File "/Users/yogi/Downloads/Vendors/Vendor_new_code/post_csv.py", line 139, in upload_to_ns response.raise_for_status() # raise an HTTPError if the response status is not 2xx File "/Users/yogi/Library/Python/3.10/lib/python/site-packages/requests/models.py", line 1021, in raise_for_status raise HTTPError(http_error_msg, response=self) requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://xxxxxxxxx.restlets.api.netsuite.com/app/site/hosting/restlet.nl?script=1750&amp;deploy=1
b
a restlet should be your first choice, suitelets werent designed for use as an api
y
Thanks
Copy code
/**
 * @NApiVersion 2.x
 * @NScriptType Restlet
 */
define(['N/file', 'N/encode'], function (file, encode) {
    function post(context) {
        try {
            var base64Content = context.fileContent;
            var folderId = context.folderId; // Retrieve the folder ID from the context
            var fileName = context.fileName;
            var fileType = file.Type.PDF; // Modify this as per your file type

            var uploadFile = file.create({
                name: fileName,
                fileType: fileType,
                contents: base64Content,
                folder: folderId // Use the provided folder ID here
            });
            
            var fileId = uploadFile.save();

            // Load the file to get its URL
            var fileRecord = file.load({
                id: fileId
            });

            var fileUrl = "<https://xxxxxxx-sb1.app.netsuite.com>" + fileRecord.url; // Concatenate with base URL

            return {
                success: true,
                message: 'File uploaded successfully!',
                fileId: fileId,
                fileUrl: fileUrl // Return the full URL
            };
        } catch (e) {
            return {
                success: false,
                message: e.toString()
            };
        }
    }

    return {
        post: post
    };
});
The above code worked
b
use url.resolveDomain for code more likely to work in different accounts
you may also want to consider changing how your errors work, you application will need to handle how netsuite normally responds to errors
adding your own in the catch means another form of error to handle