Node.js SDK for Zoho CRM API v2.0 providing OAuth authentication, multi-user support, and complete CRUD operations for CRM data
The Attachments & Files module provides comprehensive file management capabilities for CRM records, including file upload, download, attachment management, and file organization.
Complete attachment management for CRM records.
/**
* Operations for managing file attachments on CRM records
*/
class AttachmentsOperations {
/**
* Download a specific attachment from a record
* @param moduleAPIName - API name of the CRM module
* @param recordId - ID of the record containing the attachment
* @param attachmentId - ID of the attachment to download
* @returns Promise with APIResponse containing file data
*/
downloadAttachment(moduleAPIName: string, recordId: BigInt, attachmentId: BigInt): Promise<APIResponse>;
/**
* Delete a specific attachment from a record
* @param moduleAPIName - API name of the CRM module
* @param recordId - ID of the record containing the attachment
* @param attachmentId - ID of the attachment to delete
* @returns Promise with APIResponse containing deletion results
*/
deleteAttachment(moduleAPIName: string, recordId: BigInt, attachmentId: BigInt): Promise<APIResponse>;
/**
* Upload a file as an attachment to a record
* @param moduleAPIName - API name of the CRM module
* @param recordId - ID of the record to attach the file to
* @param request - File body wrapper containing the file to upload
* @returns Promise with APIResponse containing upload results
*/
uploadAttachment(moduleAPIName: string, recordId: BigInt, request: FileBodyWrapper): Promise<APIResponse>;
/**
* Get list of attachments for a specific record
* @param moduleAPIName - API name of the CRM module
* @param recordId - ID of the record
* @param paramInstance - Optional parameters for filtering and pagination
* @returns Promise with APIResponse containing attachment list
*/
getAttachments(moduleAPIName: string, recordId: BigInt, paramInstance?: ParameterMap): Promise<APIResponse>;
}Attachments Operations Example:
const { AttachmentsOperations } = require("@zohocrm/nodejs-sdk-2.0/core/com/zoho/crm/api/attachments/attachments_operations");
const { FileBodyWrapper } = require("@zohocrm/nodejs-sdk-2.0/core/com/zoho/crm/api/attachments/file_body_wrapper");
const fs = require("fs");
const attachmentsOp = new AttachmentsOperations();
// Get all attachments for a record
const attachmentsResponse = await attachmentsOp.getAttachments("Leads", "record_id_here");
if (attachmentsResponse != null) {
const responseObject = attachmentsResponse.object;
if (responseObject instanceof ResponseWrapper) {
const attachments = responseObject.getData();
attachments.forEach(attachment => {
console.log(`Attachment: ${attachment.getFileName()}, Size: ${attachment.getSize()}`);
});
}
}
// Upload a file attachment
const fileStream = fs.createReadStream("path/to/document.pdf");
const fileWrapper = new FileBodyWrapper();
fileWrapper.setFile(fileStream);
const uploadResponse = await attachmentsOp.uploadAttachment("Leads", "record_id_here", fileWrapper);
if (uploadResponse != null) {
const responseObject = uploadResponse.object;
if (responseObject instanceof ActionWrapper) {
const actionResponses = responseObject.getData();
actionResponses.forEach(actionResponse => {
if (actionResponse instanceof SuccessResponse) {
console.log("File uploaded successfully: " + actionResponse.getMessage());
}
});
}
}
// Download an attachment
const downloadResponse = await attachmentsOp.downloadAttachment("Leads", "record_id_here", "attachment_id_here");
if (downloadResponse != null) {
const responseObject = downloadResponse.object;
if (responseObject instanceof FileBodyWrapper) {
const fileStream = responseObject.getFile();
// Save the file stream to local file system
const writeStream = fs.createWriteStream("downloaded_file.pdf");
fileStream.pipe(writeStream);
}
}
// Delete an attachment
const deleteResponse = await attachmentsOp.deleteAttachment("Leads", "record_id_here", "attachment_id_here");General file upload operations for temporary file storage.
/**
* Operations for general file management and temporary uploads
*/
class FileOperations {
/**
* Upload a file to temporary storage (e.g., for bulk operations)
* @param request - File body wrapper containing the file to upload
* @returns Promise with APIResponse containing file upload results
*/
uploadFile(request: FileBodyWrapper): Promise<APIResponse>;
}File Operations Example:
const { FileOperations } = require("@zohocrm/nodejs-sdk-2.0/core/com/zoho/crm/api/file/file_operations");
const { FileBodyWrapper } = require("@zohocrm/nodejs-sdk-2.0/core/com/zoho/crm/api/file/file_body_wrapper");
const fs = require("fs");
const fileOperations = new FileOperations();
// Upload file for temporary storage
const csvStream = fs.createReadStream("bulk_import_data.csv");
const fileWrapper = new FileBodyWrapper();
fileWrapper.setFile(csvStream);
const uploadResponse = await fileOperations.uploadFile(fileWrapper);
if (uploadResponse != null) {
const responseObject = uploadResponse.object;
if (responseObject instanceof ActionWrapper) {
const actionResponses = responseObject.getData();
actionResponses.forEach(actionResponse => {
if (actionResponse instanceof SuccessResponse) {
const fileId = actionResponse.getDetails().get("file_id");
console.log("Temporary file uploaded with ID: " + fileId);
// Use this file_id for bulk operations
}
});
}
}Core data structures for attachment management.
/**
* Represents a file attachment with all metadata
*/
class Attachment {
/** Get attachment ID */
getId(): string;
/** Set attachment ID */
setId(id: string): void;
/** Get attachment file name */
getFileName(): string;
/** Set attachment file name */
setFileName(fileName: string): void;
/** Get file size in bytes */
getSize(): number;
/** Set file size in bytes */
setSize(size: number): void;
/** Get file type/MIME type */
getType(): string;
/** Set file type/MIME type */
setType(type: string): void;
/** Get attachment description */
getDescription(): string;
/** Set attachment description */
setDescription(description: string): void;
/** Get attachment creation time */
getCreatedTime(): Date;
/** Get attachment modification time */
getModifiedTime(): Date;
/** Get user who uploaded the attachment */
getCreatedBy(): User;
/** Get user who last modified the attachment */
getModifiedBy(): User;
/** Get file owner */
getOwner(): User;
/** Set file owner */
setOwner(owner: User): void;
/** Get parent record ID */
getParentId(): Record;
/** Set parent record ID */
setParentId(parentId: Record): void;
/** Check if attachment is editable */
getEditable(): boolean;
/** Set editable flag */
setEditable(editable: boolean): void;
/** Check if attachment is sharable */
getSharable(): boolean;
/** Set sharable flag */
setSharable(sharable: boolean): void;
/** Get file link URL */
getFileId(): string;
/** Set file link URL */
setFileId(fileId: string): void;
/** Get attachment link URL */
getLinkUrl(): string;
/** Set attachment link URL */
setLinkUrl(linkUrl: string): void;
}
/**
* File body wrapper for file uploads and downloads
*/
class FileBodyWrapper {
/** Get file stream */
getFile(): any;
/** Set file stream for upload */
setFile(file: any): void;
}
/**
* Response wrapper for attachment GET operations
*/
class ResponseWrapper {
/** Get attachments data */
getData(): Attachment[];
/** Get pagination info */
getInfo(): Info;
}
/**
* Action wrapper for attachment POST/PUT/DELETE operations
*/
class ActionWrapper {
/** Get action results */
getData(): ActionResponse[];
}Parameters for customizing attachment operations.
/**
* Parameters for getAttachments operation
*/
class GetAttachmentsParam {
static FIELDS: Param; // Fields to retrieve
static IDS: Param; // Specific attachment IDs
static PAGE: Param; // Page number for pagination
static PER_PAGE: Param; // Attachments per page
}Parameter Usage Example:
const { ParameterMap } = require("@zohocrm/nodejs-sdk-2.0/routes/parameter_map");
const { GetAttachmentsParam } = require("@zohocrm/nodejs-sdk-2.0/core/com/zoho/crm/api/attachments/attachments_operations");
// Setup parameters for getting attachments
const paramMap = new ParameterMap();
await paramMap.add(GetAttachmentsParam.FIELDS, "file_name,size,created_time,created_by");
await paramMap.add(GetAttachmentsParam.PAGE, 1);
await paramMap.add(GetAttachmentsParam.PER_PAGE, 200);
// Get attachments with specific fields
const response = await attachmentsOp.getAttachments("Leads", "record_id_here", paramMap);Utility functions and helpers for file operations.
/**
* File upload configuration and utilities
*/
class FileUploadConfig {
/** Maximum file size in bytes (default: 20MB) */
static MAX_FILE_SIZE: number = 20971520;
/** Supported file types for attachments */
static SUPPORTED_TYPES: string[] = [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"text/plain",
"text/csv",
"image/jpeg",
"image/jpg",
"image/png",
"image/gif",
"image/bmp",
"image/tiff"
];
/** Image file types */
static IMAGE_TYPES: string[] = [
"image/jpeg",
"image/jpg",
"image/png",
"image/gif",
"image/bmp",
"image/tiff"
];
/** Document file types */
static DOCUMENT_TYPES: string[] = [
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"text/plain",
"text/rtf"
];
/** Spreadsheet file types */
static SPREADSHEET_TYPES: string[] = [
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"text/csv"
];
}
/**
* File helper utilities
*/
class FileHelpers {
/**
* Check if file type is supported
* @param mimeType - MIME type of the file
* @returns boolean indicating if file type is supported
*/
static isSupportedType(mimeType: string): boolean {
return FileUploadConfig.SUPPORTED_TYPES.includes(mimeType);
}
/**
* Check if file is an image
* @param mimeType - MIME type of the file
* @returns boolean indicating if file is an image
*/
static isImage(mimeType: string): boolean {
return FileUploadConfig.IMAGE_TYPES.includes(mimeType);
}
/**
* Check if file size is within limits
* @param fileSize - Size of file in bytes
* @returns boolean indicating if size is acceptable
*/
static isValidSize(fileSize: number): boolean {
return fileSize <= FileUploadConfig.MAX_FILE_SIZE;
}
/**
* Get file extension from filename
* @param fileName - Name of the file
* @returns File extension or empty string
*/
static getFileExtension(fileName: string): string {
const lastDot = fileName.lastIndexOf('.');
return lastDot > 0 ? fileName.substring(lastDot + 1).toLowerCase() : '';
}
/**
* Format file size for display
* @param bytes - File size in bytes
* @returns Formatted size string
*/
static formatFileSize(bytes: number): string {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
}File Upload Best Practices Example:
const fs = require("fs");
const path = require("path");
async function uploadFileWithValidation(filePath, moduleAPIName, recordId) {
const attachmentsOp = new AttachmentsOperations();
try {
// Check if file exists
if (!fs.existsSync(filePath)) {
throw new Error("File does not exist: " + filePath);
}
// Get file stats
const stats = fs.statSync(filePath);
const fileName = path.basename(filePath);
const fileExtension = FileHelpers.getFileExtension(fileName);
// Validate file size
if (!FileHelpers.isValidSize(stats.size)) {
throw new Error(`File size ${FileHelpers.formatFileSize(stats.size)} exceeds maximum allowed size of ${FileHelpers.formatFileSize(FileUploadConfig.MAX_FILE_SIZE)}`);
}
// Create file stream
const fileStream = fs.createReadStream(filePath);
const fileWrapper = new FileBodyWrapper();
fileWrapper.setFile(fileStream);
// Upload file
const uploadResponse = await attachmentsOp.uploadAttachment(moduleAPIName, recordId, fileWrapper);
if (uploadResponse != null) {
const responseObject = uploadResponse.object;
if (responseObject instanceof ActionWrapper) {
const actionResponses = responseObject.getData();
for (const actionResponse of actionResponses) {
if (actionResponse instanceof SuccessResponse) {
console.log("File uploaded successfully:", fileName);
return actionResponse.getDetails();
} else if (actionResponse instanceof APIException) {
console.error("Upload failed:", actionResponse.getMessage());
throw new Error(actionResponse.getMessage());
}
}
}
}
} catch (error) {
console.error("Error uploading file:", error.message);
throw error;
}
}
// Usage example
async function uploadDocument() {
try {
const result = await uploadFileWithValidation(
"/path/to/document.pdf",
"Leads",
"123456789012345678"
);
console.log("Upload result:", result);
} catch (error) {
console.error("Upload failed:", error.message);
}
}Install with Tessl CLI
npx tessl i tessl/npm-zohocrm--nodejs-sdk-2-0