Attachments with frappe.sendmail

Hello,

I’m trying to write a custom server side script that automatically attaches File pieces that are linked to items to an email that is being sent when a form submits. Here is the usage case:

The email is a Request for Quotation that gets sent to a supplier. I need to include the RFQ (which is a printed version of the Request for Quotation doctype), plus other files for all the items that are being quoted (some pdf and other file formats). I have attached the appropriate files in the Item doctype, and can call them up as needed.

The place I am having an issue is with the actual frappe.sendmail command. I can attach the pdf of the doctype, but not the other files. Here is what I have:

Attaching the pdf of the current doctype (works):

my_attachments = [frappe.attach_print(self.doctype, self.name, file_name=self.name)]

Sending the email (works):

frappe.sendmail(
		recipients=[self.supplier_email],
		subject=self.title,
		message=self.comments,
		reference_doctype=self.doctype,
		reference_name=self.name,
		attachments=my_attachments
		)

Function that tries to get the attached file

 def create_attachment(filename):
    	file = frappe.get_doc("File",filename)
    	frappe.msgprint(_("Adding {0}".format(file.file_name)))
    	with open(file.file_url, "rb") as fileobj:
    		filedata = fileobj.read() 
    	out = {
    		"fname": file.file_name,
    		"fcontent": filedata 
    	}

The error I’m getting is:

I realize that the path I’m specifying probably isn’t complete, which is why it isn’t finding it, but I can’t seem to find where this path goes, and I’m not sure this is the right way to do it even if I was to specify the right file.

Any help would be greatly appreciated!

1 Like

To get the site page, use frappe.get_site_path("/private/files/filename")

1 Like

Your suggestion didn’t seem to work, but I was able to use get_file_path(file.file_name) from frappe.utils.file_manager to get the file. Here is my working function for generating an “attachment”, for reference:

def create_attachment(filename):

	file = frappe.get_doc("File",filename)
	path = get_file_path(file.file_name,)  

	with open(path, "rb") as fileobj:
		filedata = fileobj.read() 

	out = {
		"fname": file.file_name,
		"fcontent": filedata
	}
	return out 

Thank you for the help!

1 Like

Use get_site_path here

@Ben_Cornwell_Mott are you open sourcing your app?

We are developing a Request for Quotation doc.Given that this is my first time working with python and with app development in frappe, I want to spend a bit more time getting it right/working before sharing it. Currently it is a separate app, but I think it is very likely universally usable so could get integrated into ERPNext.

Hi there,

any hint on how to attach txt file to an email? i cant understand how it works :disappointed_relieved:

Thx

Here’s how I’ve done it:

You basically need to attach the file to the record you are emailing. I haven’t done anything with Email module at all, so if that’s what you’re referring to I don’t know for sure, but I’d imagine all you need to do is attach to the Email record.

1 Like

@Ben_Cornwell_Mott actually i solved using your previous script as i do not need to email the record but only the file generated at runtime. Btw i’ll keep in mind this solution in case i need it!

Thx for the hint!

I was able to send file on site file system as attachment to email using below code

with open(encode(path), 'r') as f:
	    content = f.read()


    attachments = [{
			'fname': filename,
			'fcontent': content
		}]