Roundup Tracker

Confidential Email Replies

This is a part of a set of modifications to use Roundup as CRM (customer relationship management) software in a small software development company. This HowTo assumes the Roundup tracker instance is based on the classic template.

Use case and motivation

After a customer has submitted an issue, sometimes a rather technical discussion thread amongst developers starts. Within these threads there are often technical details mentioned. Developers didn't want to have these messages go out to the customers, because they contain either confidential technical details or the wording is not appropriate for official company emails or the company internal personal email addresses of certain staff members shouldn't go out to customers.

So by default Email replies shouldn't go to all users on the nosy list but only to those users, which are members of the company staff.

How to do this

Changes to schema.py

To distinguish the company staff users from ordinary (say external) users a new role is added to schema.py:

db.security.addRole(name='OurCompany',
                    description='A person working @ OurCompany')

This role has to be assigned to all users, which are members of the "OurCompany" staff.

Next also in schema.py the message class is extended with a new boolean property called company_extern:

msg = FileClass(db, "msg",
              author=Link("user", do_journal='no'),
...
              company_extern=Boolean(),)

Changes to html/issue.item.html

First a checkbox above the Change note enter box (look for the textarea in html/issue.item.html) is needed by the customer support staff to send out official messages out to users on nosy list which are not employees of the company:

<tr tal:condition="context/is_edit_ok">
 <th i18n:translate="">Official</th>
 <td colspan=3>
   <input type="checkbox" name="msg-1@company_extern" value="yes">
   <span i18n:translate="">(Should this change also be mailed to external people?)</span>
 </td>
</tr>

Whether some change note message was a company official email in the message thread should be displayed. So at the very bottom of html/issue.item.html there are the following two table rows to be inserted just above the row containing the <tr><td colspan="4" class="content">:

<tr tal:condition="msg/company_extern">
  <th class="msgexternal" colspan="3" i18n:translate="">
     This was also send out to external members of the nosy list.
  </th>
</tr>
<tr tal:condition="not:msg/company_extern">
  <th class="msginternal" colspan="3" i18n:translate="">
     This messge was only send to Company internal members of the nosy list.
  </th>
</tr>

Changes to html/style.css

The following could be added to the file html/style.css:

table.messages th.msgexternal {
  font-weight: normal;
  color: red;
  border-top: 0;
}

table.messages th.msginternal {
  font-weight: normal;
  border-top: 0;
}

The most difficult change: detectors/nosyreaction.py

This subsection describes, where the real action takes place. Unfortunately this requires a rather heavy change. In the default classic template there is a file detectors/nosyreaction.py which used to contain the following function:

def nosyreaction(db, cl, nodeid, oldvalues):
...
    # send a copy of all new messages to the nosy list
    for msgid in determineNewMessages(cl, nodeid, oldvalues):
        try:
            cl.nosymessage(nodeid, msgid, oldvalues)
        except roundupdb.MessageSendError, message:
            raise roundupdb.DetectorError, message

Remove this for loop containing the call to cl.nosymessage() and a replace it with copy of the code taken from the Roundup source code method nosymessage() from the IssueClass in roundup/roundupdb.py. In this code find the following section:

# If we have new recipients, update the message's recipients
# and send the mail.
if sendto or bcc_sendto:
    if msgid is not None:
        self.db.msg.set(msgid, recipients=recipients)
    self.send_message(nodeid, msgid, note, sendto, from_address,
        bcc_sendto)

and change it as follows (note: at the time of this writing this was only tested with Roundup 0.8. The patches are now, January 2016, still working fine with Roundup 1.5.1)

...
     # If we have new recipients, update the message's recipients
     # and send the mail.
     if sendto or bcc_sendto:
         if not messages.get(msgid, 'company_extern'):
             # filter out the people not having the OurCompany role:
             sendto = [i for i in sendto
                          if "OurCompany" in users.get(i,
                                         'roles', "").split(',')]

         # Now (see above) we know the new recepients, that will
         # really receive the message:
         recipients = recipients + sendto

         # map userids to addresses
         sendto = [users.get(i, 'address') for i in sendto]

         # still someone to send this to?
         if sendto or bcc_sendto:
             # update the message's recipients list
             messages.set(msgid, recipients=recipients)

             # send the message
             cl.send_message(nodeid, msgid, note, sendto)

...


CategorySchema CategoryDetectors