Edgewall Software

Notification Customizations

TracNotification customizations can often be implemented with a short plugin. Some custom examples are given on this page. Trac ≥ 1.2 is needed for all of these examples.

Add or change email header

Some projects like to add or change special email headers to notification emails.

For example by default Trac sends notifications with email header Precedence: bulk, but some projects prefer to use Precedence: list:

  1. Create a single file plugin that implements IEmailDecorator:
    # -*- coding: utf-8 -*-
    #
    # Copyright (C) 2017 Edgewall Software
    # All rights reserved.
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://trac.edgewall.org/wiki/TracLicense.
    #
    # This software consists of voluntary contributions made by many
    # individuals. For the exact contribution history, see the revision
    # history and logs, available at http://trac.edgewall.org/log/.
    
    from trac.core import Component, implements
    from trac.notification.api import IEmailDecorator
    from trac.notification.mail import set_header
    
    class ListPrecedenceEmailDecorator(Component):
    
        implements(IEmailDecorator)
    
        # IEmailDecorator methods
        
        def decorate_message(self, event, message, charset):
            set_header(message, 'Precedence', 'list', charset)
    

See also: #7499

Add ticket fields to email headers

Some projects need email headers with the current or changed values of ticket fields:

  1. Create a single file plugin that implements IEmailDecorator:
    # -*- coding: utf-8 -*-
    #
    # Copyright (C) 2017 Edgewall Software
    # All rights reserved.
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://trac.edgewall.org/wiki/TracLicense.
    #
    # This software consists of voluntary contributions made by many
    # individuals. For the exact contribution history, see the revision
    # history and logs, available at http://trac.edgewall.org/log/.
    
    from trac.config import ListOption
    from trac.core import Component, implements
    from trac.notification.api import IEmailDecorator
    from trac.notification.mail import set_header
    
    class TicketFieldEmailDecorator(Component):
    
        implements(IEmailDecorator)
    
        smtp_x_trac_ticket_headers = ListOption('notification',
                'smtp_x_trac_ticket_headers', 'CHANGED',
                doc="""Possible values: ''ALL'', ''CHANGED'' or comma-separated
                list of ticket properties.
    
                Those properties are put into the e-mail headers when notifying
                about ticket updates.""")
    
        # IEmailDecorator methods
        
        def decorate_message(self, event, message, charset):
            if event.realm != 'ticket' or event.category == 'batchmodify':
                return
            def header(value, *parts):
                name = '-'.join(part.capitalize() for part in parts)
                set_header(message, name, value, charset)
            fields = list(self.smtp_x_trac_ticket_headers)
            prefix = 'X-Trac-Ticket'
            if fields == ['CHANGED']:
                for item, change in event.changes['fields'].iteritems():
                    for type, value in change.iteritems():
                        header(value, prefix, item, type)
            elif fields == ['ALL']:
                for item in event.target.values:
                    header(event.target.values[item], prefix, item)
            else:
                for item in fields:
                    if item in event.target.values:
                        header(event.target.values[item], prefix, item)
    
  2. Set the configuration [notification] smtp_x_trac_ticket_headers to ALL or to a list of ticket field names.

See also: #6516

Attachments in Notification Emails

This email decorator can be used to send new ticket attachments as email attachments with the notification emails.

  1. Create a single file plugin that implements IEmailDecorator:
    # -*- coding: utf-8 -*-
    #
    # Copyright (C) 2017 Edgewall Software
    # All rights reserved.
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://trac.edgewall.org/wiki/TracLicense.
    #
    # This software consists of voluntary contributions made by many
    # individuals. For the exact contribution history, see the revision
    # history and logs, available at http://trac.edgewall.org/log/.
    
    from email.mime.application import MIMEApplication
    
    from trac.core import Component, implements
    from trac.notification.api import IEmailDecorator
    
    class AttachmentEmailDecorator(Component):
    
        implements(IEmailDecorator)
    
        # IEmailDecorator methods
        
        def decorate_message(self, event, message, charset):
            if event.category == 'attachment added':
                attachment = event.attachment
                filename = attachment.filename
                with attachment.open() as fd:
                    part = MIMEApplication(fd.read(), Name=filename)
                part['Content-Disposition'] = 'attachment; filename="%s"' % filename
                message.attach(part)
    

See also: #3054

Reply-To Ticket Owner

Some projects want to replies to ticket email notifications to be directly sent to the ticket owner's email address.

  1. Create a single file plugin that implements IEmailDecorator:
    # -*- coding: utf-8 -*-
    #
    # Copyright (C) 2017 Edgewall Software
    # All rights reserved.
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://trac.edgewall.org/wiki/TracLicense.
    #
    # This software consists of voluntary contributions made by many
    # individuals. For the exact contribution history, see the revision
    # history and logs, available at http://trac.edgewall.org/log/.
    
    from trac.core import Component, implements
    from trac.notification.api import IEmailDecorator
    from trac.notification.mail import RecipientMatcher, set_header
    
    class ReplyToTicketOwnerEmailDecorator(Component):
        """Use the ticket owner in the Reply-To header in notification emails."""
    
        implements(IEmailDecorator)
    
        def decorate_message(self, event, message, charset):
            if event.realm != 'ticket':
                return
            owner = event.target['owner']
            matcher = RecipientMatcher(self.env)
            owner = matcher.match_from_author(owner)
            if owner:
                set_header(message, 'Reply-To', owner, charset)
    

Variations

  • Reply to ticket updater by changing event.target['owner'] to event.author.

See also: #6789, #10578

Reply-To Ticket Notification Emails

th:EmailtoTracScript and a small plugin to change the Reply-To address allow users to reply directly to notification emails to append comments to a ticket.

The Reply-To header is changed depending on the ticket id so replies are sent to for example 10044@trac-hacks.org and can be appended to ticket #10044:

  1. Create a single file plugin that implements IEmailDecorator:
    # -*- coding: utf-8 -*-
    #
    # Copyright (C) 2017 Edgewall Software
    # All rights reserved.
    #
    # This software is licensed as described in the file COPYING, which
    # you should have received as part of this distribution. The terms
    # are also available at http://trac.edgewall.org/wiki/TracLicense.
    #
    # This software consists of voluntary contributions made by many
    # individuals. For the exact contribution history, see the revision
    # history and logs, available at http://trac.edgewall.org/log/.
    
    from trac.core import Component, implements
    from trac.config import Option
    from trac.notification.api import IEmailDecorator
    from trac.notification.mail import set_header
    
    class ReplyToTicketDecorator(Component):
        """Replaces the 'Reply-To' header for tickets with a dynamic email address.
    
        Uses a new config option 'ticket_smtp_replyto'.
        """
        implements(IEmailDecorator)
    
        ticket_smtp_replyto = Option('notification', 'ticket_smtp_replyto', '__id__@localhost',
                    """Reply-To address for ticket notification emails.
    
                       ` __id__` is replaced with the ticket id.""")
    
        def decorate_message(self, event, message, charset):
            if event.realm == 'ticket':
                replyto = self.ticket_email_replyto.replace('__id__', str(event.target.id))
                set_header(message, 'Reply-To', replyto, charset)
    
  2. Install and configure th:EmailtoTracScript.

See also: th:EmailtoTracScript, th:comment:4:ticket:10044

Last modified 6 years ago Last modified on Sep 6, 2018, 3:39:36 AM
Note: See TracWiki for help on using the wiki.