Opened 12 years ago

Last modified 7 years ago

#10044 closed enhancement

support context-based sender address — at Version 14

Reported by: eu@… Owned by: Steffen Hoffmann
Priority: normal Component: AnnouncerPlugin
Severity: normal Keywords:
Cc: Trac Release: 0.12

Description (last modified by Ryan J Ollos)

It would be nice if the sender's email address could be made dependent on the context, based on some template rules. For instance, all nofitications for ticket #123 would be sent from 123@bugs.domain (subject being the ticket title) and similar (think of 123@bugs.debian.org).

Along with some customization of email2trac, seamless two-way communication channel over e-mail would be established.

Change History (15)

comment:1 Changed 12 years ago by Bas van der Vlies

I just want to support 2 formats:

  • <ticket_id>@email2trac.sara.nl
  • email2trac+<ticket_id>@sara.nl

comment:2 Changed 11 years ago by Robert Corsaro

Owner: changed from Robert Corsaro to Steffen Hoffmann

comment:3 in reply to:  1 Changed 11 years ago by anonymous

Replying to bas:

I just want to support 2 formats:

  • <ticket_id>@email2trac.sara.nl
  • email2trac+<ticket_id>@sara.nl

any progress

comment:4 Changed 11 years ago by Peter Suter

I have not tested this, but I think it should be possible to implement something useful using a IAnnouncementEmailDecorator. For example something like:

from email.utils import parseaddr, formataddr

from trac.core import Component, implements

from announcer.distributors.mail import IAnnouncementEmailDecorator
from announcer.util.mail import next_decorator, set_header

class FromTicketDecorator(Component):
    """Replaces the 'From' header for ticket events with a dynamic email address.

    Uses a new config option 'ticket_email_from'.
    """

    implements(IAnnouncementEmailDecorator)

    ticket_email_from = Option('announcer', 'ticket_email_from', '__id__@localhost',
                 """Sender address to use in ticket notification emails.

                 __id__ is replaced with the ticket id.
                 """)

    def decorate_message(self, event, message, decorators):
        if event.realm == 'ticket':
            from_header = formataddr(
                 (parseaddr(message['From'])[0],
                  self.ticket_email_from.replace('__id__', str(event.target['id']))))
            set_header(message, 'From', from_header)
        return next_decorator(event, message, decorators)
Last edited 11 years ago by Peter Suter (previous) (diff)

comment:5 Changed 11 years ago by bas.vandervlies@…

Thanks for the ezample/hint. This is the correct code ;-)

class FromTicketDecorator(Component):
    """
    Replaces the 'From' header for ticket events with a dynamic email address.
    Uses a new config option 'ticket_email_from'.
    """
    implements(IAnnouncementEmailDecorator)

    ticket_email_replyto = Option('announcer', 'ticket_email_replyto', '__id__@localhost',
                """Reply address to use in ticket notification emails. ` __id__` is replaced with the ticket id.  """)

    def decorate_message(self, event, message, decorators):
        if event.realm == 'ticket':
                if  not self.ticket_email_replyto in ['__id__@localhost', '']:
                    replyto_addr =  self.ticket_email_replyto.replace('__id__', str(event.target.id))
                    self.log.debug("HvB: ticket id %s" %(str(event.target.id)))
                    set_header(message, 'Reply-To', replyto_addr)
        return next_decorator(event, message, decorators)

comment:6 Changed 11 years ago by eu@…

Nice work. Can I just suggest that a more standard '{id}@localhost' and the .format(id=...) be used in the template string?

comment:7 Changed 11 years ago by Peter Suter

Another possibility would be a Genshi template similar to the ticket_email_subject. But that was a bit much for a proof of concept, so I went with something simple similar to the email_subject_prefix instead.

Feel free to tweak as you see fit though. That's the great advantage of the plugin system. :)

comment:8 in reply to:  7 Changed 11 years ago by bas.vandervlies@…

Replying to psuter:

Another possibility would be a Genshi template similar to the ticket_email_subject. But that was a bit much for a proof of concept, so I went with something simple similar to the email_subject_prefix instead.

Feel free to tweak as you see fit though. That's the great advantage of the plugin system. :)

Again thanks for showing the different options. Will this patch be accepted? Then i can make email2trac dependent on announcerplugin for unique reply-to addresses per ticket

comment:9 in reply to:  6 Changed 11 years ago by bas.vandervlies@…

Replying to eu@…:

Nice work. Can I just suggest that a more standard '{id}@localhost' and the .format(id=...) be used in the template string?

Are there advantages when we switch to template strings? we are only interested in the ticket id and email address to use.

comment:10 Changed 11 years ago by eu@…

Are there advantages when we switch to template strings? we are only interested in the ticket id and email address to use.

I thought it would be more standard, perhaps more readable and somewhat more extensible if you want to have something fancier like #{id}: {name} <{id}@{tracdomain}>; but that's a bonus. The downside is that python<=2.5 does not support .format, not sure if that is an issue for someone. The __id__ will work just fine for me. As always, who codes, decides :).

comment:11 Changed 11 years ago by bas.vandervlies@…

ok here is the code for genshi templates:

class ReplytoTicketDecorator(Component):
    """
    Replaces the 'reply-to' header for ticket events with a dynamic email address.
    Uses a new config option 'ticket_email_replyto'.
    """
    implements(IAnnouncementEmailDecorator)
    ticket_email_replyto = Option('announcer', 'ticket_email_replyto', '${ticket.id}@localhost',
                """Each ticket get its own unique reply-to address based on ticket id.  
                Default is to use email_replyto setting. """)

    def decorate_message(self, event, message, decorators):
        if event.realm == 'ticket':
            template = NewTextTemplate( self.ticket_email_replyto.encode('utf8'))

            # Create a fallback for invalid custom Genshi template in option.
            # then we use the default 'email_replyto' setting
            #
            default_template = NewTextTemplate(
                        Option.registry[('announcer', 'email_replyto')
                        ].default.encode('utf8'))
            try:
                reply_to = template.generate(
                            ticket=event.target,
                            event=event,
                            action=event.category
                        ).render('text', encoding=None)

            except TemplateError:
                # Use fallback template.
                reply_to = default_template.generate(
                            ticket=event.target,
                            event=event,
                            action=event.category
                        ).render('text', encoding=None)


            value = self.config.get('announcer', 'ticket_email_replyto')
            if not value in ['', '__default__', '${ticket.id}@localhost']:
                self.log.debug("ticket reply_to template: %s" %(value))
                set_header(message, 'Reply-To', reply_to)

        return next_decorator(event, message, decorators)

Changed 11 years ago by bas.vandervlies@…

Attachment: ticket_email_replyto.patch added

ticket_email_replyto patch

comment:12 Changed 9 years ago by Bas van der Vlies

Is there any news on this patch?

comment:13 Changed 9 years ago by Ryan J Ollos

The plugin isn't currently being maintained. I'll test out the patch and commit the change. I'm thinking it should go in announcerplugin/trunk/announcer/email_decorators.

The API for AnnouncerPlugin has been integrated into Trac for the 1.2 release. When Trac 1.2 is released you might consider including the decorator in email2trac.

comment:14 Changed 9 years ago by Ryan J Ollos

Description: modified (diff)
Note: See TracTickets for help on using tickets.