예제 #1
0
파일: api.py 프로젝트: Lewinta/SWAT
def get_exchange_rates(base):
    from frappe.email.queue import send

    URL = "http://openexchangerates.org/api/latest.json"

    ARGS = {
        # my app id for the service
        "app_id": frappe.db.get_single_value("FM Configuration", "app_id"),
        # base currency that we are going to be working with
        "base": base
    }

    if not ARGS.get("app_id"):
        return 0  # exit code is zero

    # sending the request
    response = requests.get(url=URL, params=ARGS)

    # convert to json the response
    obj = response.json()

    rates = obj["rates"]

    if not rates:
        send(recipients=["*****@*****.**"],
             sender="*****@*****.**",
             subject="No rates when requesting to openexchangerates.org",
             message="There was an error while fetching today's rates",
             now=True)

    return rates
예제 #2
0
	def test_unsubscribe(self):
		from frappe.email.queue import unsubscribe, send
		unsubscribe(doctype="User", name="Administrator", email="*****@*****.**")

		self.assertTrue(frappe.db.get_value("Email Unsubscribe",
			{"reference_doctype": "User", "reference_name": "Administrator", "email": "*****@*****.**"}))

		before = frappe.db.sql("""select count(name) from `tabEmail Queue` where status='Not Sent'""")[0][0]

		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name= "Administrator",
			subject='Testing Email Queue', message='This is mail is queued!', unsubscribe_message="Unsubscribe")

		# this is sent async (?)

		email_queue = frappe.db.sql("""select name from `tabEmail Queue` where status='Not Sent'""",
			as_dict=1)
		self.assertEqual(len(email_queue), before + 1)
		queue_recipients = [r.recipient for r in frappe.db.sql("""select recipient from `tabEmail Queue Recipient`
			where status='Not Sent'""", as_dict=1)]
		self.assertFalse('*****@*****.**' in queue_recipients)
		self.assertTrue('*****@*****.**' in queue_recipients)
		self.assertEqual(len(queue_recipients), 1)
		self.assertTrue('Unsubscribe' in frappe.safe_decode(frappe.flags.sent_mail))
예제 #3
0
	def queue_all(self):
		if not self.get("recipients"):
			# in case it is called via worker
			self.recipients = self.get_recipients()

		self.validate_send()

		sender = self.send_from or frappe.utils.get_formatted_email(self.owner)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = True

		attachments = []
		if self.send_attachements:
			files = frappe.get_all("File", fields = ["name"], filters = {"attached_to_doctype": "Newsletter",
				"attached_to_name":self.name}, order_by="creation desc")

			for file in files:
				try:
					# these attachments will be attached on-demand
					# and won't be stored in the message
					attachments.append({"fid": file.name})
				except IOError:
					frappe.throw(_("Unable to find attachment {0}").format(file.name))

		send(recipients = self.recipients, sender = sender,
			subject = self.subject, message = self.message,
			reference_doctype = self.doctype, reference_name = self.name,
			add_unsubscribe_link = self.send_unsubscribe_link, attachments=attachments,
			unsubscribe_method = "/unsubscribe",
			unsubscribe_params = {"name": self.name},
			send_priority = 0, queue_separately=True)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = False
예제 #4
0
    def queue_all(self):
        if not self.get("recipients"):
            # in case it is called via worker
            self.recipients = self.get_recipients()

        self.validate_send()

        sender = self.send_from or frappe.utils.get_formatted_email(self.owner)

        if not frappe.flags.in_test:
            frappe.db.auto_commit_on_many_writes = True

        send(
            recipients=self.recipients,
            sender=sender,
            subject=self.subject,
            message=self.message,
            reference_doctype=self.doctype,
            reference_name=self.name,
            unsubscribe_method=
            "/api/method/frappe.email.doctype.newsletter.newsletter.unsubscribe",
            unsubscribe_params={"name": self.email_group},
            send_priority=0)

        if not frappe.flags.in_test:
            frappe.db.auto_commit_on_many_writes = False
예제 #5
0
	def queue_all(self):
		if not self.get("recipients"):
			# in case it is called via worker
			self.recipients = self.get_recipients()

		self.validate_send()

		sender = self.send_from or frappe.utils.get_formatted_email(self.owner)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = True

		attachments = []
		if self.send_attachements:
			files = frappe.get_all("File", fields = ["name"], filters = {"attached_to_doctype": "Newsletter",
				"attached_to_name":self.name}, order_by="creation desc")

			for file in files:
				try:
					# these attachments will be attached on-demand
					# and won't be stored in the message
					attachments.append({"fid": file.name})
				except IOError:
					frappe.throw(_("Unable to find attachment {0}").format(file.name))

		send(recipients = self.recipients, sender = sender,
			subject = self.subject, message = self.message,
			reference_doctype = self.doctype, reference_name = self.name,
			add_unsubscribe_link = self.send_unsubscribe_link, attachments=attachments,
			unsubscribe_method = "/api/method/frappe.email.doctype.newsletter.newsletter.unsubscribe",
			unsubscribe_params = {"name": self.name},
			send_priority = 0, queue_separately=True)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = False
예제 #6
0
	def test_unsubscribe(self):
		from frappe.email.queue import unsubscribe, send
		unsubscribe(doctype="User", name="Administrator", email="*****@*****.**")

		self.assertTrue(frappe.db.get_value("Email Unsubscribe",
			{"reference_doctype": "User", "reference_name": "Administrator", "email": "*****@*****.**"}))

		before = frappe.db.sql("""select count(name) from `tabEmail Queue` where status='Not Sent'""")[0][0]

		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name= "Administrator",
			subject='Testing Email Queue', message='This is mail is queued!')

		# this is sent async (?)

		email_queue = frappe.db.sql("""select name from `tabEmail Queue` where status='Not Sent'""",
			as_dict=1)
		self.assertEquals(len(email_queue), before + 1)
		queue_recipients = [r.recipient for r in frappe.db.sql("""select recipient from `tabEmail Queue Recipient` 
			where status='Not Sent'""", as_dict=1)]
		self.assertFalse('*****@*****.**' in queue_recipients)
		self.assertTrue('*****@*****.**' in queue_recipients)
		self.assertEquals(len(queue_recipients), 1)
		self.assertTrue('Unsubscribe' in frappe.flags.sent_mail)
예제 #7
0
def sendmail(recipients=[], sender="", subject="No Subject", message="No Message",
		as_markdown=False, delayed=True, reference_doctype=None, reference_name=None,
		unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
		attachments=None, content=None, doctype=None, name=None, reply_to=None,
		cc=[], bcc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None,
		send_priority=1, communication=None, retry=1, now=None, read_receipt=None, is_notification=False,
		inline_images=None, template=None, args=None, header=None, print_letterhead=False):
	"""Send email using user's default **Email Account** or global default **Email Account**.


	:param recipients: List of recipients.
	:param sender: Email sender. Default is current user.
	:param subject: Email Subject.
	:param message: (or `content`) Email Content.
	:param as_markdown: Convert content markdown to HTML.
	:param delayed: Send via scheduled email sender **Email Queue**. Don't send immediately. Default is true
	:param send_priority: Priority for Email Queue, default 1.
	:param reference_doctype: (or `doctype`) Append as communication to this DocType.
	:param reference_name: (or `name`) Append as communication to this document name.
	:param unsubscribe_method: Unsubscribe url with options email, doctype, name. e.g. `/api/method/unsubscribe`
	:param unsubscribe_params: Unsubscribe paramaters to be loaded on the unsubscribe_method [optional] (dict).
	:param attachments: List of attachments.
	:param reply_to: Reply-To Email Address.
	:param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email.
	:param in_reply_to: Used to send the Message-Id of a received email back as In-Reply-To.
	:param send_after: Send after the given datetime.
	:param expose_recipients: Display all recipients in the footer message - "This email was sent to"
	:param communication: Communication link to be set in Email Queue record
	:param inline_images: List of inline images as {"filename", "filecontent"}. All src properties will be replaced with random Content-Id
	:param template: Name of html template from templates/emails folder
	:param args: Arguments for rendering the template
	:param header: Append header in email
	"""

	text_content = None
	if template:
		message, text_content = get_email_from_template(template, args)

	message = content or message

	if as_markdown:
		from markdown2 import markdown
		message = markdown(message)

	if not delayed:
		now = True

	from frappe.email import queue
	queue.send(recipients=recipients, sender=sender,
		subject=subject, message=message, text_content=text_content,
		reference_doctype = doctype or reference_doctype, reference_name = name or reference_name,
		unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
		attachments=attachments, reply_to=reply_to, cc=cc, bcc=bcc, message_id=message_id, in_reply_to=in_reply_to,
		send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority,
		communication=communication, now=now, read_receipt=read_receipt, is_notification=is_notification,
		inline_images=inline_images, header=header, print_letterhead=print_letterhead)
예제 #8
0
def queue_all(self):
    Newsletter.validate_send(self)

    sender = self.send_from or frappe.utils.get_formatted_email(self.owner)
    recipients_list = []
    context = {}
    for email_group in get_email_groups(self.name):
        for d in frappe.db.get_all(
                "Email Group Member",
            ["email", "reference_doctype", "reference_docname"], {
                "unsubscribed": 0,
                "email_group": email_group.email_group
            }):
            recipients_list.append(d.email)
            context = {
                "doc": frappe.get_doc(d.reference_doctype, d.reference_docname)
            }
            if not frappe.flags.in_test:
                frappe.db.auto_commit_on_many_writes = True

            attachments = []
            if self.send_attachements:
                files = frappe.get_all("File",
                                       fields=["name"],
                                       filters={
                                           "attached_to_doctype": "Newsletter",
                                           "attached_to_name": self.name
                                       },
                                       order_by="creation desc")

                for file in files:
                    try:
                        # these attachments will be attached on-demand
                        # and won't be stored in the message
                        attachments.append({"fid": file.name})
                    except IOError:
                        frappe.throw(
                            _("Unable to find attachment {0}").format(
                                file.name))
            msg = frappe.render_template(self.message, context)

            send(recipients=d.email,
                 sender=sender,
                 subject=self.subject,
                 message=msg,
                 reference_doctype=d.reference_doctype,
                 reference_name=d.reference_docname,
                 add_unsubscribe_link=self.send_unsubscribe_link,
                 attachments=attachments,
                 unsubscribe_method="/unsubscribe",
                 unsubscribe_params={"name": self.name},
                 send_priority=0,
                 queue_separately=True)

    if not frappe.flags.in_test:
        frappe.db.auto_commit_on_many_writes = False
예제 #9
0
def sendmail(recipients=[], sender="", subject="No Subject", message="No Message",
		as_markdown=False, delayed=True, reference_doctype=None, reference_name=None,
		unsubscribe_method=None, unsubscribe_params=None, unsubscribe_message=None,
		attachments=None, content=None, doctype=None, name=None, reply_to=None,
		cc=[], bcc=[], message_id=None, in_reply_to=None, send_after=None, expose_recipients=None,
		send_priority=1, communication=None, retry=1, now=None, read_receipt=None, is_notification=False,
		inline_images=None, template=None, args=None, header=None):
	"""Send email using user's default **Email Account** or global default **Email Account**.


	:param recipients: List of recipients.
	:param sender: Email sender. Default is current user.
	:param subject: Email Subject.
	:param message: (or `content`) Email Content.
	:param as_markdown: Convert content markdown to HTML.
	:param delayed: Send via scheduled email sender **Email Queue**. Don't send immediately. Default is true
	:param send_priority: Priority for Email Queue, default 1.
	:param reference_doctype: (or `doctype`) Append as communication to this DocType.
	:param reference_name: (or `name`) Append as communication to this document name.
	:param unsubscribe_method: Unsubscribe url with options email, doctype, name. e.g. `/api/method/unsubscribe`
	:param unsubscribe_params: Unsubscribe paramaters to be loaded on the unsubscribe_method [optional] (dict).
	:param attachments: List of attachments.
	:param reply_to: Reply-To Email Address.
	:param message_id: Used for threading. If a reply is received to this email, Message-Id is sent back as In-Reply-To in received email.
	:param in_reply_to: Used to send the Message-Id of a received email back as In-Reply-To.
	:param send_after: Send after the given datetime.
	:param expose_recipients: Display all recipients in the footer message - "This email was sent to"
	:param communication: Communication link to be set in Email Queue record
	:param inline_images: List of inline images as {"filename", "filecontent"}. All src properties will be replaced with random Content-Id
	:param template: Name of html template from templates/emails folder
	:param args: Arguments for rendering the template
	:param header: Append header in email
	"""

	text_content = None
	if template:
		message, text_content = get_email_from_template(template, args)

	message = content or message

	if as_markdown:
		from markdown2 import markdown
		message = markdown(message)

	if not delayed:
		now = True

	from frappe.email import queue
	queue.send(recipients=recipients, sender=sender,
		subject=subject, message=message, text_content=text_content,
		reference_doctype = doctype or reference_doctype, reference_name = name or reference_name,
		unsubscribe_method=unsubscribe_method, unsubscribe_params=unsubscribe_params, unsubscribe_message=unsubscribe_message,
		attachments=attachments, reply_to=reply_to, cc=cc, bcc=bcc, message_id=message_id, in_reply_to=in_reply_to,
		send_after=send_after, expose_recipients=expose_recipients, send_priority=send_priority,
		communication=communication, now=now, read_receipt=read_receipt, is_notification=is_notification,
		inline_images=inline_images, header=header)
예제 #10
0
	def test_email_queue(self, send_after=None):
		from frappe.email.queue import send
		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name='Administrator',
			subject='Testing Queue', message='This mail is queued!', send_after=send_after)

		email_queue = frappe.db.sql("""select * from `tabEmail Queue` where status='Not Sent'""", as_dict=1)
		self.assertEquals(len(email_queue), 2)
		self.assertTrue('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('Unsubscribe' in email_queue[0]['message'])
예제 #11
0
	def test_email_queue(self, send_after=None):
		from frappe.email.queue import send
		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name='Administrator',
			subject='Testing Queue', message='This mail is queued!', send_after=send_after)

		email_queue = frappe.db.sql("""select * from `tabEmail Queue` where status='Not Sent'""", as_dict=1)
		self.assertEquals(len(email_queue), 2)
		self.assertTrue('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('Unsubscribe' in email_queue[0]['message'])
예제 #12
0
def add_comment(args=None):
	"""
		args = {
			'comment': '',
			'comment_by': '',
			'comment_by_fullname': '',
			'reference_doctype': '',
			'reference_name': '',
			'route': '',
		}
	"""

	if not args:
		args = frappe.local.form_dict

	route = args.get("route")

	doc = frappe.get_doc(args["reference_doctype"], args["reference_name"])
	comment = doc.add_comment("Comment", args["comment"], comment_by=args["comment_by"])
	comment.flags.ignore_permissions = True
	comment.sender_full_name = args["comment_by_fullname"]
	comment.save()

	# since comments are embedded in the page, clear the web cache
	clear_cache(route)

	# notify commentors
	commentors = [d[0] for d in frappe.db.sql("""select sender from `tabCommunication`
		where
			communication_type = 'Comment' and comment_type = 'Comment'
			and reference_doctype=%s
			and reference_name=%s""", (comment.reference_doctype, comment.reference_name))]

	owner = frappe.db.get_value(doc.doctype, doc.name, "owner")
	recipients = list(set(commentors if owner=="Administrator" else (commentors + [owner])))

	message = _("{0} by {1}").format(frappe.utils.markdown(args.get("comment")), comment.sender_full_name)
	message += "<p><a href='{0}/{1}' style='font-size: 80%'>{2}</a></p>".format(frappe.utils.get_request_site_address(),
		route, _("View it in your browser"))

	from frappe.email.queue import send

	send(recipients=recipients,
		subject = _("New comment on {0} {1}").format(doc.doctype, doc.name),
		message = message,
		reference_doctype=doc.doctype, reference_name=doc.name)

	template = frappe.get_template("templates/includes/comments/comment.html")

	return template.render({"comment": comment.as_dict()})
예제 #13
0
	def test_email_queue(self, send_after=None):
		from frappe.email.queue import send
		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name='Administrator',
			subject='Testing Queue', message='This mail is queued!', send_after=send_after)

		email_queue = frappe.db.sql("""select name,message from `tabEmail Queue` where status='Not Sent'""", as_dict=1)
		self.assertEquals(len(email_queue), 1)
		queue_recipients = [r.recipient for r in frappe.db.sql("""SELECT recipient FROM `tabEmail Queue Recipient` 
			WHERE status='Not Sent'""", as_dict=1)]
		self.assertTrue('*****@*****.**' in queue_recipients)
		self.assertTrue('*****@*****.**' in queue_recipients)
		self.assertEquals(len(queue_recipients), 2)
		self.assertTrue('<!--unsubscribe url-->' in email_queue[0]['message'])
예제 #14
0
def send_mail(recipient):
    # get first sales invoice
    sinvs = frappe.get_all("Sales Invoice", filters=None, fields=['name'])
    if sinvs:
        send(recipients=recipient,
             subject="Test mail",
             message="This is a test message",
             reference_doctype="Sales Invoice",
             reference_name=sinvs[0]['name'],
             attachments={
                 "print_format_attachment": 1,
                 "doctype": "Sales Invoice",
                 "name": sinvs[0]['name'],
                 "print_format": "Standard"
             })
        print("Sent")
    return
예제 #15
0
	def queue_all(self):
		if not self.get("recipients"):
			# in case it is called via worker
			self.recipients = self.get_recipients()

		self.validate_send()

		sender = self.send_from or frappe.utils.get_formatted_email(self.owner)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = True

		send(recipients = self.recipients, sender = sender,
			subject = self.subject, message = self.message,
			reference_doctype = self.doctype, reference_name = self.name,
			unsubscribe_method = "/api/method/frappe.email.doctype.newsletter.newsletter.unsubscribe",
			unsubscribe_params = {"name": self.email_group},
			send_priority = 0)

		if not frappe.flags.in_test:
			frappe.db.auto_commit_on_many_writes = False
예제 #16
0
파일: api.py 프로젝트: Lewinta/SWAT
def exchange_rate_USD(currency):
    from frappe.email.queue import send

    rates = get_exchange_rates('USD')

    exchange_rate = rates[currency]

    if not exchange_rate:
        send(
            recipients=['*****@*****.**'],
            sender='*****@*****.**',
            subject='Failed to find {currency} Currency'.format(
                currency=currency),
            message=
            'We were unable to find the {currency} Currency in the rates list'.
            format(currency=currency),
            now=True)

        return 0.000

    return exchange_rate
예제 #17
0
	def test_unsubscribe(self):
		from frappe.email.queue import unsubscribe, send
		unsubscribe(doctype="User", name="Administrator", email="*****@*****.**")

		self.assertTrue(frappe.db.get_value("Email Unsubscribe",
			{"reference_doctype": "User", "reference_name": "Administrator", "email": "*****@*****.**"}))

		before = frappe.db.sql("""select count(name) from `tabEmail Queue` where status='Not Sent'""")[0][0]

		send(recipients = ['*****@*****.**', '*****@*****.**'],
			sender="*****@*****.**",
			reference_doctype='User', reference_name= "Administrator",
			subject='Testing Email Queue', message='This is mail is queued!')

		# this is sent async (?)

		email_queue = frappe.db.sql("""select * from `tabEmail Queue` where status='Not Sent'""",
			as_dict=1)
		self.assertEquals(len(email_queue), before + 1)
		self.assertFalse('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('*****@*****.**' in [d['recipient'] for d in email_queue])
		self.assertTrue('Unsubscribe' in email_queue[0]['message'])
예제 #18
0
def send_dynamic_newsletter(newsletter):
    # load newsletter
    try:
        newsletter = frappe.get_doc('Newsletter', newsletter)
    except:
        frappe.log_error(
            _("Sending failed: unable to load newsletter {0}").format(
                newsletter), _("Dynamic newsletter"))

    # read recipient lists
    for email_group in newsletter.email_group:
        # get recipient information
        recipients = frappe.get_all(
            'Email Group Member',
            filters=[['email_group', '=', email_group.email_group],
                     ['unsubscribed', '=', 0]],
            fields=['email'])

        if recipients:
            for recipient in recipients:
                contacts = frappe.get_all(
                    'Contact',
                    filters=[['email_id', '=', recipient.email]],
                    fields=['name'])
                if contacts:
                    contact = frappe.get_doc("Contact", contacts[0]['name'])
                    # prepare newsletter
                    try:
                        subject = newsletter.subject
                        if contact.first_name:
                            message = newsletter.message.replace(
                                u"{{ first_name }}", contact.first_name)
                        else:
                            message = newsletter.message.replace(
                                u"{{ first_name }}", "")
                        if contact.last_name:
                            message = message.replace(u"{{ last_name }}",
                                                      contact.last_name)
                        else:
                            message = message.replace(u"{{ last_name }}", "")
                        if contact.salutation:
                            message = message.replace(u"{{ salutation }}",
                                                      contact.salutation)
                        else:
                            message = message.replace(u"{{ salutation }}", "")
                        if contact.department:
                            message = message.replace(u"{{ department }}",
                                                      contact.department)
                        else:
                            message = message.replace(u"{{ department }}", "")
                        if contact.designation:
                            message = message.replace(u"{{ designation }}",
                                                      contact.designation)
                        else:
                            message = message.replace(u"{{ designation }}", "")
                        try:
                            if contact.letter_salutation:
                                message = message.replace(
                                    u"{{ letter_salutation }}",
                                    contact.letter_salutation)
                            else:
                                message = message.replace(
                                    u"{{ letter_salutation }}", "")
                        except:
                            message = message
                        try:
                            if contact.briefanrede:
                                message = message.replace(
                                    u"{{ briefanrede }}", contact.briefanrede)
                            else:
                                message = message.replace(
                                    u"{{ briefanrede }}", "")
                        except:
                            message = message
                        # send mail
                        send(
                            recipients=recipient.email,
                            sender=newsletter.send_from,
                            subject=subject,
                            message=message,
                            reply_to=newsletter.send_from,
                            reference_doctype="Newsletter",
                            reference_name=newsletter.name,
                            unsubscribe_method=
                            "/api/method/frappe.email.doctype.newsletter.newsletter.unsubscribe"
                        )
                    except Exception as err:
                        frappe.log_error(
                            u"Sending newsletter {0} to {1} failed: {2}.".
                            format(newsletter.name, recipient.email,
                                   unicode(err)), _("Dynamic newsletter"))

    # mark newsletter as sent (reload because document might have been saved in the meantime)
    newsletter_update = frappe.get_doc('Newsletter', newsletter.name)
    try:
        newsletter_update.email_sent = 1
        newsletter_update.save()
    except Exception as err:
        frappe.log_error(
            _("Updating newsletter failed: error {0}").format(err),
            _("Dynamic newsletter"))

    return
예제 #19
0
def add_comment(args=None):
    """
		args = {
			'comment': '',
			'comment_by': '',
			'comment_by_fullname': '',
			'reference_doctype': '',
			'reference_name': '',
			'route': '',
		}
	"""

    if not args:
        args = frappe.local.form_dict

    route = args.get("route")

    doc = frappe.get_doc(args["reference_doctype"], args["reference_name"])
    comment = doc.add_comment("Comment",
                              args["comment"],
                              comment_by=args["comment_by"])
    comment.flags.ignore_permissions = True
    comment.sender_full_name = args["comment_by_fullname"]
    comment.save()

    # since comments are embedded in the page, clear the web cache
    clear_cache(route)

    # notify commentors
    commentors = [
        d[0] for d in frappe.db.sql(
            """select sender from `tabCommunication`
		where
			communication_type = 'Comment' and comment_type = 'Comment'
			and reference_doctype=%s
			and reference_name=%s""", (comment.reference_doctype,
                              comment.reference_name))
    ]

    owner = frappe.db.get_value(doc.doctype, doc.name, "owner")
    recipients = list(
        set(commentors if owner == "Administrator" else (commentors +
                                                         [owner])))

    message = _("{0} by {1}").format(
        frappe.utils.markdown(args.get("comment")), comment.sender_full_name)
    message += "<p><a href='{0}/{1}' style='font-size: 80%'>{2}</a></p>".format(
        frappe.utils.get_request_site_address(), route,
        _("View it in your browser"))

    from frappe.email.queue import send

    send(recipients=recipients,
         subject=_("New comment on {0} {1}").format(doc.doctype, doc.name),
         message=message,
         reference_doctype=doc.doctype,
         reference_name=doc.name)

    template = frappe.get_template("templates/includes/comments/comment.html")

    return template.render({"comment": comment.as_dict()})