This is the standard aggregate-query-update pattern, but with a twist: the relationship is polymorphic, so we need to do dynamic queries. Here's what the trigger would look like:
trigger MakeEmailsPublic on EmailMessage (after insert) {
// Aggregate //
Map<sObjectType, Set<id>> recordIdsByType = new Map<sObjectType, Set<Id>>();
for(EmailMessage message: Trigger.new) {
if(message.RelatedToId != null) {
sObjectType key = message.RelatedToId.getSObjectType();
Set<Id> recordIds = recordIdsByType.get(key);
if(recordIds == null) {
recordIdsByType.put(key, recordIds = new Set<Id>());
}
recordIds.add(message.RelatedToId);
}
}
// Query //
Map<Id, sObject> records = new Map<Id, sObject>();
for(sOBjectType sType: recordIdsByType.keySet()) {
if(sType.getDescribe().fields.getMap().containsKey('RecordTypeId')) {
Set<Id> ids = recordIdsByType.get(sType);
records.putAll(
Database.query('SELECT RecordTypeId FROM '+sType+' WHERE Id = :ids')
);
}
}
// Update //
for(EmailMessage message: Trigger.new) {
sObject record = records.get(message.RelatedToId);
if(record != null) {
Id recordTypeId = (Id)record.get('RecordTypeId');
if(recordTypeId == 'rectype1' || recordTypeId == 'rectype2') {
message.IsExternallyVisible = true;
}
}
}
}