1

Here's the problem:

Every time a contact gets updated,

  1. I need to go to Notes&Attachments of that contact and fetch JUST the first line of the BODY field for every individual entry if it contains "MailChimp Stats for:" string.

  2. Inside that first line, after "MailChimp Stats for:" first string is the first and second is the last name of ANOTHER contact. so:

e.g. Body: Mailchimp Stats for: John Doe
(John = first name of the contact, Doe = second name of the contact).

  1. Now - I need to find that contact (John Doe) and paste the FIRST line of the BODY field from Notes&Attachments into Activity History, field SUBJECT.

I just started working with apex, so I have no idea how to do this. I'm guessing I should use a trigger? If the answer is too complicated, I'd appreciate some pointers, or at least suggestions.

  • Certainly you can't use Workflow Rule or Process Builder to analyze child records. It is unclear why you want this logic to be applied on update to the Contact, it seems like it should be when the Note/Attachment is created? – Adrian Larson Jun 30 '16 at 19:15
  • Agreed with Adrian, you should use an after update trigger on Contact. You can check if the parent Id on the note is a contact using a describe call or a SOQL query. Take a look at the apex string methods for actually parsing the body like you want. – Kyle Jun 30 '16 at 19:57
  • @AdrianLarson - I said contact because I thought contact contains all these fields - as I said, I'm just a beginner, so the structure hierarchy isn't yet clear to me. Kyle - I'll definitely take a look at these methods you're mentioning! – Jurica Dujmović Jun 30 '16 at 20:08
0

You will need an Apex Trigger, I think. Below are some snippets you will find helpful.

Parent Type

You can determine the SObjectType of the ParentId field as follows:

public Boolean isContactRecord(Attachment record)
{
    return record.ParentId != null &&
        record.ParentId.getSObjectType() == Contact.sObjectType;
}

You can filter matching records to get the collection you care about:

public List<Attachment> filterContactRecords(List<Attachment> records)
{
    List<Attachment> contactRecords = new List<Attachment>();
    for (Attachment record : records)
    {
        if (isContactRecord(record)) contactRecords.add(record);
    }
    return contactRecords;
}

Parsing

You will need to use Regular Expressions to get the FirstName and LastName values. The expression I think you should use is:

Mailchimp Stats for:\s+(\w+ \w+)

In Apex, you could use this as follows:

static final Pattern names = Pattern.compile('(Mailchimp Stats for:\\s+(\\w+ \\w+)');
class Parser
{
    final String name;
    final String subject;
    Parser(Attachment record)
    {
        Matcher m = names.matcher(record.Body);
        if (m.find())
        {
            name = m.group(1);
            line = record.Body.substringBefore('\n');
        }
    }
}
public static List<Task> parseNames(List<Attachment> contactRecords)
{
    Map<String, Parser> nameToData = new Map<String, Parser>();
    for (Attachment record : contactRecords)
    {
        Parser data = new Parser(record);
        if (data.Name != null) nameToData.put(data.Name, data);
    }
    List<Task> tasks = new List<Task>();
    for (Contact contact : [SELECT Name FROM Contact WHERE Name IN :nameToData.keySet()])
    {
        tasks.add(new Task(
            ParentId=contact.Id,
            Subject=nameToData.get(contact.Name).subject
            // other fields
        ));
    }
    return tasks;
}

Architecture

How you want to manipulate the relevant Contact records is unclear based on your OP, but the above should at least get you started. If you really want to check all these child records every time a Contact gets updated, you will want a before update trigger. I recommend implementing a handler pattern. You will need to research which pattern you feel works best for you.

However, it doesn't seem like the logical trigger event. My suggestion is that you should just trigger this logic whenever you create a Note or Attachment. In this case, you should use an after insert trigger.

  • I wasn't aware that there was a distinction between Note and Attachment fields - Now that I look at the original records, they are of type Note. So, I won't be needing Attachments - sorry for not mentioning it earlier. Does your code above need to change? Now, to answer your question - I plan to take Note body - first line - and paste it as a new entry into the Activity history field. – Jurica Dujmović Jun 30 '16 at 21:14
  • You can't directly manipulate Activity History, and it's not a field, it's a Related List. Regardless, the above logic should hold just fine for Note. – Adrian Larson Jun 30 '16 at 21:16
  • Not sure I understand - So - I can't do what I wanted - meaning, add value from the body of Note into Subject field of Activity History (as a new entry)? – Jurica Dujmović Jun 30 '16 at 21:17
  • You can create a new Task or Event and have it go into those lists, yes. I'll update my post in a bit. – Adrian Larson Jun 30 '16 at 21:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.