My opportunity has some attachments.
I would like to send them via email.
If I hit on “Attach File” button of “Send an Email” page, then File Location lookup filter window, dialog appears, however I am not able to find any of the attachments.
Any idea? Why I don’t see the attachments in the file location lookup filter?
Any help really appreciated!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
There are a number of places where files can be stored in an org. Files, Documents, Content, Attachments, Static Resource, and more each are slightly different.
There is a help topic that goes through the difference between these.
In the case of attaching a file to an email, Attachment is not something you can use. Why you can’t send an attachment that is already related to that record? I don’t have a good explanation for that, other than, no one has thought of building that feature.
But the simple answer to you question is, that’s not how email attachments work.
So what would it make this happen? You would need to create some custom functionality using Visualforce and Apex. But this would be a complex enough task that this is not suited to a Stack Exchange answer.
There is an idea on Idea exchange that you can vote up to get Salesforce to add this feature.
https://success.salesforce.com/ideaView?id=08730000000BplZ
Method 2
I found a solution. I created a custom “Send an Email” apex page there a user can choose any of opportunity attachment and send it via email, for this functionality I have created an apex controller that can send an email with the attachments.
Here is my solution, note the code is not refactored but functionality is doing what I need exactly,
Apex page:
<apex:page controller="EmailOpportunityAttachment"> <script type="text/javascript"> var delim = ";"; function lookupPick2(editPage, p2_lkid, p2, contactId, contactName, cas4, accountName, cas4_lkid, accountId, h){ document.getElementsByClassName('p2')[0].value = contactName; document.getElementById('p2_lkid').value = contactId; closePopup(); } function pickupValue(additionalToValue, ccValue, bccValue) { //var editPage = document.getElementsByClassName('editPage')[0]; var p24 = document.getElementsByClassName('p24')[0]; var p4 = document.getElementsByClassName('p4')[0]; var p5 = document.getElementsByClassName('p5')[0]; if(additionalToValue != '') { if (p24.value != '') { p24.value += delim; } p24.value += additionalToValue; } if(ccValue != '') { if (p4.value != '') { p4.value += delim; } p4.value += ccValue; } if(bccValue != '') { if (p5.value != '') { p5.value += delim; } p5.value += bccValue; } closePopup(); } function openDocumentUpload(e) { setLastMousePosition(e); openPopup('/widg/filepicker_fs.jsp?lktp=015&mode=1&eid=00Yg0000000aN7g&utype=00P&omode=1&otype=2', 'doc', 450, 450, 'width=450,height=450,scrollbars=yes,toolbar=no,status=no,directories=no,menubar=no,resizable=1', true); } function attachPhxAttachment(e){ var selector = document.getElementById('attS'); var splt = selector.value.split('##'); var id = splt[0]; var size = splt[1]; var tr = document.getElementById('tr_' + id); var fileStr = document.getElementById('fileStr'); fileStr.innerHTML += tr.outerHTML; populateAttIds(); } function populateAttIds(){ var hiddenDv = document.getElementsByClassName('attDvBlock')[0]; var hiddenAttIds = hiddenDv.getElementsByClassName('hiddenAttIds'); var inps = document.getElementsByClassName('attIds')[0]; inps.value = ''; if(hiddenAttIds && hiddenAttIds.length > 0){ for(var i=0; i < hiddenAttIds.length; i++){ inps.value += hiddenAttIds[i].value + delim; } } } function submitFormNoSave() { var nosave = document.getElementById('nosave'); var save = document.getElementById('save'); nosave.value = '1'; save.value = 'nosave'; submitForm(); } function submitForm() { var editPage = document.getElementById('editPage'); editPage.submit(); } function deletePhxAttachment(event) { if (window.confirm('Are you sure?')) { var elem = event.target.parentNode.parentNode; elem.parentNode.removeChild(elem); populateAttIds(); } } </script> <apex:sectionHeader title="Task" subtitle="Send an Email"/> <apex:form id="editPage" onsubmit="if (window.ffInAlert) { return false; }" styleClass="editPage"> <input type="hidden" name="cancelURL" id="cancelURL" value="/{!opptyId}" /> <input type="hidden" name="id" id="id" value="00Yg0000000aN7g" /> <input type="hidden" name="docancel" id="docancel" value="0" /> <input type="hidden" name="new_template" id="new_template" value="0" /> <input type="hidden" name="nosave" id="nosave" value="0" /> <input type="hidden" name="save" id="save" value="0" /> <input type="hidden" name="retURL" id="retURL" value="/{!opptyId}" /> <input type="hidden" name="rtype" id="rtype" value="003" /> <input type="hidden" name="p2_lktp" id="p2_lktp" value="003" /> <input type="hidden" name="p2_lkold" id="p2_lkold" value="" /> <input type="hidden" name="p2_lkid" id="p2_lkid" value="" /> <input type="hidden" name="p2_lspf" id="p2_lspf" value="0" /> <input type="hidden" name="p2_lspfsub" id="p2_lspfsub" value="0" /> <input type="hidden" name="p2_mod" id="p2_mod" value="0" /> <input type="hidden" name="template_id" id="template_id" value="000000000000000" /> <apex:pageblock id="mail" mode="edit"> <apex:pageBlockButtons > <apex:commandButton value="Send" action="{!sendEmail}" id="sendEmailBtn" /> <input type="button" class="btn" value="Select Template" id="sendEmailBtn" /> <input value="Attach File" class="btn" title="Attach File (New Window)" name="attach" onclick="openDocumentUpload(event)" type="button" /> <input type="button" class="btn" value="Check Spelling" id="sendEmailBtn" /> <input type="button" class="btn" value="Cancel" id="cancelBtn" /> </apex:pageBlockButtons> <apex:pageblockSection> <apex:outputText styleClass="err" value="{!errorMsg}"/> <apex:outputText styleClass="success" value="{!successMsg}"/> </apex:pageblockSection> <apex:pageblockSection columns="1" title="Edit Email"> <apex:pageBlockSectionItem > <apex:outputLabel value="From" styleClass="bld"/> <apex:outputpanel layout="block" styleClass="requiredInput"> <apex:outputpanel layout="block" styleClass="requiredBlock" /> <apex:selectList id="p26" value="{!ffrom}" size="1"> <apex:selectOptions value="{!contacts}"></apex:selectOptions> </apex:selectList> </apex:outputpanel> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem> <apex:outputLabel value="To:" styleClass="bld"/> <apex:pageBlockSectionItem> <apex:inputText value="{!to}" maxlength="255" onchange="getElementByIdCS('p2_lkid').value='';getElementByIdCS('p2_mod').value='1';" size="20" styleClass="p2" /> <a href="javascript: openLookup('/_ui/common/data/LookupPage?lkfm=editPage&lknm=p2&lktp=' + getElementByIdCS('p2_lktp').value,670,'1','&lksrch=' + escapeUTF(getElementsByClassName('p2')[0].value.substring(0, 80)))" rel="nofollow noreferrer noopener" id="p2_lkwgt" onclick="setLastMousePosition(event)" title="To Lookup (New Window)"> <img src="/s.gif" alt="To Lookup (New Window)" class="lookupIconOn" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="To Lookup (New Window)" /></a> </apex:pageBlockSectionItem> </apex:pageBlockSectionItem> <apex:pageblockSectionItem> <apex:outputLabel value="Related To" styleClass="bld"/> <apex:pageblockSectionItem> <apex:selectList size="1" style="width: 250px"> <apex:selectOptions value="{!relatedTo}"></apex:selectOptions> <apex:selectOptions value="{!relatedTo}"></apex:selectOptions> <apex:selectOptions value="{!relatedTo}"></apex:selectOptions> </apex:selectList> <apex:inputText maxlength="255" style="margin-left: 4px;" value="{!relatedTo}" /> </apex:pageblockSectionItem> </apex:pageblockSectionItem> <apex:pageblockSectionItem > <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p24_lkwgt" onclick="setLastMousePosition(event)" title="Additional To Lookup (New Window)">Aditional To:</apex:outputlink> <apex:pageBlockSectionItem > <apex:inputTextArea value="{!additionalTo}" cols="62" rows="2" styleClass="p24" /> <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p24_lkwgt" onclick="setLastMousePosition(event)" title="Additional To Lookup (New Window)"> <img src="/s.gif" alt="Additional To Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="Additional To Lookup (New Window)" /> </apex:outputlink> </apex:pageBlockSectionItem> </apex:pageblockSectionItem> <apex:pageblockSectionItem > <apex:outputlink value="#" target="_blank">CC:</apex:outputlink> <apex:pageBlockSectionItem > <apex:inputTextArea value="{!cc}" cols="62" id="p4" rows="2" title="CC" styleClass="p4" /> <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p4_lkwgt" onclick="setLastMousePosition(event)" title="CC Lookup (New Window)"> <img src="/s.gif" alt="CC Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="CC Lookup (New Window)" /> </apex:outputlink> </apex:pageBlockSectionItem> </apex:pageblockSectionItem> <apex:pageBlockSectionItem > <apex:outputlink value="#" target="_blank">BCC:</apex:outputlink> <apex:pageBlockSectionItem> <apex:inputTextArea value="{!bcc}" cols="62" id="p5" rows="2" title="BCC" styleClass="p5" /> <apex:outputlink value="javascript: openPopup('/_ui/core/email/author/EmailCCBccLookup?id={!opptyId}', 'CCBCCLookup', 420, 490, 'width=420,height=490,toolbar=no,status=no,directories=no,menubar=no,resizable=yes,scrollable=no', true);" id="p5_lkwgt" onclick="setLastMousePosition(event)" title="BCC Lookup (New Window)"> <img src="/s.gif" alt="BCC Lookup (New Window)" class="lookupIcon" onblur="this.className = 'lookupIcon';" onfocus="this.className = 'lookupIconOn';" onmouseout="this.className = 'lookupIcon';this.className = 'lookupIcon';" onmouseover="this.className = 'lookupIconOn';this.className = 'lookupIconOn';" title="BCC Lookup (New Window)" /> </apex:outputlink> </apex:pageBlockSectionItem> </apex:pageBlockSectionItem> <apex:pageblockSectionItem > <apex:outputLabel value="Subject" styleClass="bld"/> <apex:outputpanel layout="block" styleClass="requiredInput"> <apex:outputpanel layout="block" styleClass="requiredBlock"/> <apex:inputText value="{!subject}" maxlength="100" size="70"/> </apex:outputpanel> </apex:pageblockSectionItem> <apex:pageblockSectionItem > <apex:outputLabel value="Message" styleClass="bld"/> <apex:inputTextArea value="{!message}" rows="15" cols="93" richText="false"/> </apex:pageblockSectionItem> </apex:pageblockSection> <div id="test" style="width: 500px; margin: 20px 0 0 19%;"> <select id="attS" name="attS" style="width: 400px;"> <apex:repeat value="{!attachments}" var="att" id="theRepeat"> <option value="{!att.Id}##{!att.BodyLength}">{!att.Name}</option> </apex:repeat> </select> <input value="Attach File" class="btn" id="attachFile" name="attachFile" onclick="attachPhxAttachment(event)" type="button" /> <div style="margin: 10px 0 0 0;"> <input style="display:none;" value="Attach File" class="btn" title="Attach File (New Window)" id="attach" name="attach" onclick="openDocumentUpload(event)" type="button" /> </div> </div> </apex:pageblock> <div class="bRelatedList"> <!-- Begin ListElement --> <!-- motif: Home --> <!-- WrappingClass --> <div class="listRelatedObject homeBlock"> <div class="bPageBlock brandSecondaryBrd secondaryPalette"> <div class="pbHeader"> <table border="0" cellpadding="0" cellspacing="0"><tbody> <tr> <td class="pbTitle"> <img src="/s.gif" alt="" width="12" height="1" class="minWidth" title="" style="margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;margin-right: 0.25em;" /> <h3>Attachments</h3> </td> <td class="pbButton"> <input value="Attach File" class="btn" name="attach" onclick="openDocumentUpload(event)" title="Attach File (New Window)" type="button" /> </td> <td class="pbHelp"> </td> </tr> </tbody> </table> </div> <div class="pbBody attDvBlock"> <table class="list" border="0" cellspacing="0" cellpadding="0"> <tbody id="fileStr"> <tr class="headerRow"> <th class="actionColumn" scope="col">Action</th> <th scope="col" class=" zen-deemphasize">File</th> <th scope="col" class=" zen-deemphasize">Size</th> </tr> </tbody> </table> </div> <div class="pbFooter secondaryPalette"> <div class="bg"></div> </div> </div> </div> <div class="listElementBottomNav"></div> <!-- End ListElement --> </div> <div class="hiddenDv" style="display:none !important;"> <table class="list" border="0" cellspacing="0" cellpadding="0"> <tbody> <apex:repeat value="{!attachments}" var="att2" id="trFileRepeat"> <tr id="tr_{!att2.Id}" class="dataRow even last first highlight" onblur="if (window.hiOff){hiOff(this);}" onfocus="if (window.hiOn){hiOn(this);}" onmouseout="if (window.hiOff){hiOff(this);}" onmouseover="if (window.hiOn){hiOn(this);}"> <td class="actionColumn"> <a href="javascript:;" rel="nofollow noreferrer noopener" class="actionLink" onclick="deletePhxAttachment(event)">Del</a> </td> <th scope="row" class=" dataCell "> <a href="/servlet/servlet.FileDownload?file={!att2.Id}" rel="nofollow noreferrer noopener" target="_TOP">{!att2.Name}</a> <input type="hidden" value="{!att2.Id}" class="hiddenAttIds" /> </th> <td class=" dataCell ">{!att2.BodyLength} bytes</td> </tr> </apex:repeat> </tbody> </table> </div> <apex:inputText value="{!attachmentIds}" styleClass="attIds" style="" /> </apex:form> </apex:page>
Apex controller:
public class EmailOpportunityAttachment{ public String to {get;set;} public String additionalTo {get;set;} public String relatedTo {get;set;} public String cc {get;set;} public String bcc {get;set;} public String ffrom {get;set;} public String message {get;set;} public String subject {get;set;} public String errorMsg{get;set;} public String successMsg{get;set;} public List<String> addresses {get;set;} public String opptyId {get;set;} public String accountId {get;set;} public String attachmentIds {get;set;} public boolean flagToSendMail; private static final String DEL = ';'; public EmailOpportunityAttachment(){ this.opptyId = ApexPages.currentPage().getParameters().get('opptyId'); this.accountId = ApexPages.currentPage().getParameters().get('accountId'); } public List<SelectOption> contacts { get { List<SelectOption> contacts = new List<SelectOption>(); List<Contact> cnts = [select Id, Name, Email from Contact where Account.Id =: this.accountid]; for (Contact cnt: cnts) { contacts.add(new SelectOption(cnt.Id, '"' + cnt.Name + '" <' + cnt.Email + '>')); } return contacts; } set; } public Attachment[] getAttachments(){ return [select id, Name, BodyLength, Body from Attachment where parent.id =: this.opptyId]; } public List<Attachment> getAttachmentsByIds(final String[] ids){ String sql = ' select Id, Name, Body, ContentType from Attachment where Name='DDDDDDDDDDDDDD' '; boolean found = false; if(null != ids && ids.size() > 0){ for(String id: ids){ sql += ' OR Id='; sql += '''; sql += id; sql += '''; } found = true; } //System.debug(sql); return found ? (List<Attachment>)Database.query(sql) : null; } public String getEmailByUserName(final String userName){ return [select Email from Contact where Name =: userName limit 1].Email; } public PageReference sendEmail() { PageReference pageRef = new PageReference('/'+this.opptyId); if(subject == '' || message == ''){ errorMsg = 'Please enter subject and message.'; return null; } if(to != '' || additionalTo != '' || cc != '' || bcc != ''){ List<String> toAddresses = new List<String>(); List<String> ccAddresses = new List<String>(); List<String> bccAddresses = new List<String>(); List<String> tmpAddr = new List<String>(); if(additionalTo.contains(DEL)){ toAddresses = additionalTo.split(DEL); for(String tmp:toAddresses){ tmpAddr.add(tmp); } }else if(additionalTo != '') { toAddresses.add(additionalTo); tmpAddr.add(additionalTo); } if(to != ''){ final String emailAddr = getEmailByUserName(to); toAddresses.add(emailAddr); tmpAddr.add(emailAddr); } if(cc.contains(DEL)){ ccAddresses = cc.split(DEL); for(String tmp:ccAddresses){ tmpAddr.add(tmp); } }else if(cc != ''){ ccAddresses.add(cc); tmpAddr.add(cc); } if(bcc.contains(DEL)){ bccAddresses = bcc.split(DEL); for(String tmp:bccAddresses){ tmpAddr.add(tmp); } }else if(bcc != ''){ bccAddresses.add(bcc); tmpAddr.add(bcc); } /* Checking whether mail ids are valid */ addresses = tmpAddr; for(String tempStr:addresses){ if(!Pattern.matches('[a-zA-Z0-9._-]<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="684328">[email protected]</a>[a-zA-Z]+.[a-zA-Z]{2,4}', tempStr)){ errorMsg = 'Check To, CC and BCC addresses'; successMsg = ''; flagToSendMail = false; break; }else{ flagToSendMail = true; } } /* Sending Mail */ if(flagToSendMail == true){ Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); if(toAddresses != null){ email.setToAddresses(toAddresses); } if(ccAddresses != null){ email.setccAddresses(ccAddresses); } if(bccAddresses != null){ email.setbccAddresses(bccAddresses); } email.setSubject(subject); email.setHtmlBody(message); List<Messaging.EmailFileAttachment> attachs = null; if('' != attachmentIds){ final String[] attachIds = attachmentIds.split(DEL); if(null != attachIds && attachIds.size() > 0){ final List<Attachment> attechments = getAttachmentsByIds(attachIds); if(null != attechments && attechments.size() > 0){ attachs = new List<Messaging.EmailFileAttachment>(); Messaging.EmailFileAttachment attach = null; for(Attachment att: attechments){ attach = new Messaging.EmailFileAttachment(); attach.setContentType(att.contentType); attach.setFileName(att.Name); attach.setInline(false); attach.setBody(att.Body); attachs.add(attach); attach = null; } } } } if(null != attachs && attachs.size() > 0){ email.setFileAttachments(attachs); } Messaging.sendEmail(new Messaging.SingleEmailMessage[]{email}); errorMsg = ''; successMsg = 'Mail sent successfully to following recipients'; return pageRef; }else{ return null; } }else{ errorMsg = 'Please enter To or CC or BCC address'; return null; } } }
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0