Using the send email feature of SalesForce it allows file attachment. I am looking a way to store this attachment in the salesforce to the object from which the email is sent.
I know this limitation form salesforce
"Attachments aren't stored on emails sent from Salesforce. To be saved with the email, attachments must be either associated with the email later or sent to Salesforce using using Email-to-Case, Email-to-Salesforce, On-Demand Email-to-Case, orSalesforce for Outlook."
is there any work around?
One option can be to use Apex code for uploading the same in Attachment object of Object and then sending e-mail.
//Code for attaching a file from Local Machine
//VF Page
<apex:page controller="AttachmentUploadController">
<apex:sectionHeader title="Visualforce Example" subtitle="Attachment Upload Example"/>
<apex:form enctype="multipart/form-data">
<apex:pageMessages />
<apex:pageBlock title="Upload a Attachment">
<apex:pageBlockSection showHeader="false" columns="2" id="block1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="File" for="file"/>
<apex:inputFile value="{!attachment.body}" filename="{!attachment.name}" id="file"/>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:commandButton action="{!upload}" value="Upload and send an Email"/>
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:form>
</apex:page>
//Controller
public with sharing class AttachmentUploadController
{
public Attachment attachment
{
get
{
if (attachment == null)
attachment = new Attachment();
return attachment;
}
set;
}
public PageReference upload()
{
String parentId = System.currentPagereference().getParameters().get('pid');
attachment.OwnerId = UserInfo.getUserId();
attachment.ParentId = parentId;
attachment.IsPrivate = true;
try
{
insert attachment;
//Start: Send Email with Attachment
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[]{<<email IDs>>};
mail.setToAddresses(toAddresses);
//Set email file attachments
List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
// Add to attachment file list
Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
efa.setFileName(attachment.Name);
efa.setBody(attachment.Body);
fileAttachments.add(efa);
//create attachment for object
Attachment att = new Attachment(name = attachment.name, body = attachment.body, parentid = Trigger.new[0].id);
insertAttList.add(att);
mail.setFileAttachments(fileAttachments);
//Send email
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
//END : Send Email with Attachment
PageReference page = new PageReference('/' + parentId);
return page;
}
catch (DMLException e)
{
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,system.Label.Error_uploading_attachment));
return null;
}
finally
{
attachment = new Attachment();
}
}
}
Points to note :
I have only hardcoded ToAddress in apex code but you can add the same thing in VF page. Infact you can give UI experience same as Send an Email.
I have not tried or executed the code given above; please refer this as a reference to get an idea about the Algo/flow.
Have you looked into Salesforce For Outlook? It is an add-on for Outlook where it syncs with Salesforce for Tasks, Meetings, Events, ECT. It also allows you to save the email and attachments to an Account in Salesforce with 1 click of a button. I'm the sole Admin for over 700 users and the whole field uses this and loves it.
In order to store any kind of email attachments in Salesforce, Salesforce org needs to be connected with some outlook mailbox. And as mentioned the salesforce functionality like Email-to-Case/On-Demand email-to-case services helps to store all the attachments which are sent through email.
In this case, if an attachment is sent with the mail, the attachment should be available under the "Case Attachment" tab.
That quote you included is from a comment thread that's over a DECADE old.
You need to enable Enhanced Emails. Here is Salesforce's response from 4 years ago on what you need to do: https://ideas.salesforce.com/s/idea/a0B8W00000GdhVxUAJ/email-attachments-should-be-saved-to-salesforce?sfdcIFrameOrigin=null
Related
I am trying to approve feedItem/feedcomment using Apex but I am not able to create an Approval Process for them. So an idea of how we can submit feed records for Approval.
FeedItem has a status field with two values PendingReview and Published. Change status to Published to approve them.
Example:
List<FeedItem> feedItems = new List<FeedItem>();
for(String feedId : feeds){
if(doApprove){
feedItems.add(new FeedItem(Id=feedId,Status='Published'));
}
}
Database.SaveResult[] srList = Database.update(feedItems, false);
I created a VF page and RemoteAction there is no system.debug or console.log anywhere in apex class or vf page respectively, as a result of which in Chrome developer tools -> console log there is not output but surprisingly in Network tab if you select apexremote you get to see the data returned from the query even the encrypted fields in the object.
If you see the code below, credit_card__c field is encrypted, and I am not even exposing it in my VF, still in chrome developer tools network tab I see the entire data.
How can I stop any log in my network tab of chrome developer tools ?
global class AccountRemoteService {
public String accountName { get; set; }
public static Account account { get; set; }
global AccountRemoteService(){}
#RemoteAction
global static Account getAccount(String accountName)
{
account = [SELECT id, name, credit_card__c FROM Account WHERE name = :accountName ];
return account;
}
}
VF Page
<apex:page controller="AccountRemoteService">
<script type="text/javascript">
function getRemoteAccount()
{
//get the values of input text and place into the variable.
var paramAccountName = document.getElementById('accName').value;
AccountRemoteService.getAccount( paramAccountName,
function(result, event)
{
alert('event.status==>'+event.status);
alert('event.type === '+event.type);
alert('event.message ==>'+event.message);
if (event.status)
{
// demonstrates how to get ID for HTML and Visualforce tags
document.getElementById("{!$Component.theBlock.thePageBlockSection.accountId.Id}").innerHTML = result.Id;
document.getElementById("{!$Component.theBlock.thePageBlockSection.accountName.Nam}").innerHTML = result.Name;
}
else if (event.type === 'exception')
{
document.getElementById("errors-js").innerHTML = event.message;
} else
{
document.getElementById("errors-js").innerHTML = 'No Records Found..';
}
}, {escape:true});
}
</script>
Account Name :<input id="accName" type="text" />
<button onclick="getRemoteAccount()">Get Account</button>
<div id="errors-js"> </div>
<apex:pageBlock id="theBlock">
<apex:pageBlockSection id="thePageBlockSection" columns="2">
<apex:pageBlockSectionItem id="accountId">
<apex:outputText id="Id"/>
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem id="accountName" >
<apex:outputText id="Nam" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
</apex:pageBlock>
There are a lot of things here that you are doing that should probably be done a different way, that I would just mention as an aside.
You are querying account by name not by a unique value which can lead to possibly more than one account in the result or no results and you are returning to a single Account record. In either of those cases an exception would be thrown. Use a List instead.
If you are going to use remote action you should perform an access to ensure the user has access to the field you are returning so as not to expose data unintentionally
I would recommend that you use the platform safeguards in visualforce to enforce field encryption. Use the to reference the object from your controller, you already have the account accessible to the visualforce page it's public with get; set;
In short there are certain situation where encrypted fields are not masked, I would recommend using the platform feature that helps make this easier. See here for more details.
You can achieve the same or a similar effect using actionRegion commandButtons and partial page re-rendering.
i am trying to develop visualforce page. i want to make a call. iwrite a code
public class SampleClass{
String account = 'XXXXXXXXXXXXXXXXXXX';
String token = 'YYYYYYYYYYYYYYYYYY';
public PageReference hello(){
TwilioRestClient client = new TwilioRestClient(account, token);
Map<String,String> params = new Map<String,String> {
'To' => '+919953938584',
'From' => '+919910728457',
'Url' => 'http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient'
};
TwilioCall call = client.getAccount().getCalls().create(params);
return null ;
}
}
and visualforce page
<apex:page controller="SampleClass">
<apex:form >
<apex:commandButton action="{!hello}" value="Make a Call"/>
</apex:form>
</apex:page>
both the numbers are verified so call is going and a music is playing.now i want that when the user click make a call button then he can talk to the dialled phone number.means his voice went to the number which is dialled and he can hear that voice.in other way that user can dial a phone number and talk to a person using only browser .is this possible .Please guideline.
I think you want to have one leg of you call from the Browser? So Browser to Phone handset? If this is the case you can use Twilio Client.
There are some quick starts on the Twilio site that should get you started.
Hope this helps!
I am calling an API of FluidSurvey. when i make a POST request ... it post the request on the fluidSurvey but i didnt get the JSON response. rather it returns nothing. any suggestion??
my controller code
public class fluidSurvey{
public String tst{set;get;}
public String result{get;set;}
public PageReference chk() {
getData();
return null;
}
public void getData(){
String apiKey = 'xxxxxx';
String pwd = 'xxxxxx';
String u = 'https://app.fluidsurveys.com/api/v2/surveys/survey_id/responses/';
HttpRequest req = new HttpRequest();
Http http = new Http();
HTTPResponse res;
try{
req.setEndPoint(u);
req.setTimeout(2000);
req.setMethod('POST');
Blob headerValue = Blob.valueOf(apikey + ':' + pwd);
String authorizationHeader = 'Basic '+ EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authorizationHeader);
req.setHeader('Content-Type', 'application/json');
req.setHeader('Content-Length','31999');
res = http.send(req);
tst= res.toString();
catch(Exception e){
System.debug('Callout error: '+ e);
System.debug(tst+'--------'+res);
}
}
}
and the Apex page code is
<apex:page controller="fluidSurvey">
<apex:form >
<apex:pageBlock title="New Fluid Surveys API">
<apex:outputText value="{!tst}"></apex:outputText><br/>
<apex:pageBlockButtons location="bottom">
<apex:commandButton value="Submit" action="{!chk}"/>
</apex:pageBlockButtons>
</apex:pageBlock>
</apex:form>
and api documentation link is http://docs.fluidsurveys.com/api/surveys.html#getting-a-list-of-surveys..
FluidSurveys Dev here.
Looks like you're doing a POST request, which according to the docs is for creating a new response. But your function is named getData, so I'm assuming you want to get a list of responses?
Change the request type from GET to POST and it should start to work.
Also, the response type will be application/json, but you shouldn't be setting the request type to that encoding.
If I'm mistaken and you're looking to submit a new response, then this code wouldnt work because you're not actually passing any content.
As you can see by http://docs.fluidsurveys.com/api/surveys.html#submitting-a-new-response you need to actually pass a dictionary of question ids and answers. The best way to figure out what the ids are or what the format is, is to first look at the response returned from a GET request.
The problem with my code was that i setting a content-length header, but not setting any body,the server is diligently waiting for the 3199 byte body. so after using the setBody method my code properly returns a json response
I wanted to add to this answer in that I found that some messages from Apex being posted to external endpoints were getting dropped by firewalls on the other end due to intrusion detection rules.
Apparently, there are conditions where on the Apex end, outbound messages do not conform to certain construction rules that prevent man-in-the-middle attacks and some firewalls or IDS are blocking them. This will appear on the Apex side as a "Read Time Out".
The specific IDS rule is CVE-2009-3555 (http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555).
If you are experiencing read timeouts in Apex to external endpoints and can't isolate them to apex programming, you might do some logging on the destination firewall to see if this is the issue, and if it is, create an exception in that firewall for this type of case.
I am developing a site in Visualforce and would like to offer user a simple form to send me feedback via email. There would be 3-4 fields like name, user's email, reason and feedback and "send" button. Clicking the send button should automatically send that message to my email address.
I do not want to store the form data in salesforce at least for now...All the stuff I found online about visualforce/apex and email is about saving that data to salesforce too.
Can I just make use of apex's email capabilities and send out email without storing that data anywhere in salesforce?
Thanks,
Calvin
It's not required to insert/update/delete any records in the database when executing an action on a VisualForce page. You can leverage the Outbound Email functionality to send out your notification. For something like this, you will probably want to familiarize yourself with the SingleEmailMessage methods.
A simple example to get you going:
public PageReference actionSend() {
String[] recipients = new String[]{'myemailaddress#somedomain.com'};
Messaging.reserveSingleEmailCapacity(recipients.size());
Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
msg.setToAddresses(recipients);
msg.setSubject('Test Email Subject');
msg.setHtmlBody('Test body including HTML markup');
msg.setPlainTextBody('Test body excluding HTML markup');
msg.setSaveAsActivity(false);
msg.setUseSignature(false);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {msg}, false);
return null;
}
If you are interested in sending these outbound messages from a dedicated email address (something like noreply#somecompany.com), you can set these up through the Setup -> Administration Setup -> Email Administration -> Organization-Wide Addresses menu. Once you have created an org-wide address, grab the Id from the URL and use the setOrgWideEmailAddressId(Id) method on your instance of Messaging.SingleEmailMessage.