Skip to content

Commit

Permalink
Sender match matches on Sender, from, reply_to.
Browse files Browse the repository at this point in the history
Currently Sender only matches on 'from'. This resolves Issue ranmocy#35
by making Sender match:
 - reply_to
 - from
 - sender
 - X-Original-Sender

This is similar to the functionality we have in `receiver`,
which matches 'to', 'cc', 'bcc', and 'list'.

We also speed up analysis by switching from getRawContent to
getHeader.

The MessageData.list now also includes the header 'List-ID' if it cannot
find a 'Mailing-list' header. This has been seen in a small sample of emails.
  • Loading branch information
Matt Diehl committed Aug 19, 2022
1 parent e01bfc7 commit fff8295
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export default class Condition {
return this.matchAddress(message_data.list);
}
case ConditionType.SENDER: {
return this.matchAddress(message_data.from);
return this.matchAddress(...message_data.sender);
}
case ConditionType.RECEIVER: {
return this.matchAddress(...message_data.receivers);
Expand Down
67 changes: 39 additions & 28 deletions ThreadData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,47 @@ export class MessageData {
return str.toLowerCase().split(',').map(address => address.trim());
}

private static parseListId(raw: string): string {
// Parsing would be limited to headers only
const raw_header_str = raw.split('\r\n\r\n')[0];
// const match = raw_header_str.match(/^\s*list-id:[^<]*<([^>]*)>\s*$/im);
// if (match == null || !match[1]) {
// return '';
// }
// const raw_list_id = match[1];
// const raw_list_id_at_index = raw_list_id.lastIndexOf('.', raw_list_id.lastIndexOf('.') - 1);
// const listId = raw_list_id.substr(0, raw_list_id_at_index) + '@' + raw_list_id.substr(raw_list_id_at_index + 1, raw_list_id.length);
// return listId.toLowerCase().replace(/[^a-z0-9@\.\/+]+/g, '-');

// E.x. Mailing-list: list [email protected]; contact [email protected]
const match = raw_header_str.match(/^\s*mailing-list:(.*)$/im);
if (match == null || !match[1]) {
return '';
}
const parts = match[1].trim().split(';');
if (parts.length === 0) {
return '';
private static parseMailingList(message: GoogleAppsScript.Gmail.GmailMessage): string {
const mailing_list = message.getHeader('Mailing-list').trim();
if (!!mailing_list) {
// E.x. "list [email protected]; contact [email protected]"
const parts = mailing_list.split(';');
for (const part of parts) {
const [type, address] = part.trim().split(/\s+/);
Utils.assert(typeof address !== 'undefined', `Unexpected mailing list: ${mailing_list}`);
if (type.trim() === 'list') {
return address;
}
}
}
for (const part of parts) {
const [type, address] = part.trim().split(/\s+/);
Utils.assert(typeof address !== 'undefined', `Unexpected mailing list: ${match[1].trim()}`);
if (type.trim() === 'list') {
return address;
const list_id = message.getHeader('List-ID').trim();
if (!!list_id) {
// E.x. "<mygroup.gmail.com>"
let address = list_id;
if (address.length > 0 && address.charAt(0) == '<') {
address = address.substring(1);
}
if (address.length > 0 && address.charAt(-1)) {
address = address.slice(0, -1);
}
return address;
}
return '';
}

private static parseSenders(message: GoogleAppsScript.Gmail.GmailMessage): string[] {
const original_sender = message.getHeader('X-Original-Sender').trim();
const sender = message.getHeader('Sender').trim();
const senders: string[] = [];
if (!!original_sender) {
senders.push(original_sender);
}
if (!!sender) {
senders.push(sender);
}
return senders;
}

public readonly from: string;
public readonly to: string[];
public readonly cc: string[];
Expand All @@ -84,9 +94,10 @@ export class MessageData {
this.to = MessageData.parseAddresses(message.getTo());
this.cc = MessageData.parseAddresses(message.getCc());
this.bcc = MessageData.parseAddresses(message.getBcc());
this.list = MessageData.parseListId(message.getRawContent());
this.list = MessageData.parseMailingList(message);
this.reply_to = MessageData.parseAddresses(message.getReplyTo());
this.sender = ([] as string[]).concat(this.from, this.reply_to);
this.sender = ([] as string[]).concat(
this.from, this.reply_to, ...MessageData.parseSenders(message));
this.receivers = ([] as string[]).concat(this.to, this.cc, this.bcc, this.list);
this.subject = message.getSubject();
this.headers = new Map<string, string>();
Expand All @@ -111,7 +122,7 @@ export class MessageData {
// Truncate and log long messages.
if (body.length > MAX_BODY_PROCESSING_LENGTH) {
Logger.log(`Ignoring the end of long message with subject "${this.subject}"`);
body = body.substr(0, MAX_BODY_PROCESSING_LENGTH);
body = body.substring(0, MAX_BODY_PROCESSING_LENGTH);
}
this.body = body;
}
Expand Down

0 comments on commit fff8295

Please sign in to comment.