Salesforce CRM Content – Brief Description about CRM Content and How can Developer and Admin Use CRM Content

Salesforce CRM Content Organize, share, search, and manage content within your organization .Content includes all file types, from traditional business documents such as Microsoft PowerPoint presentations to audio files, video files, Web pages, and Google docs.

It Simplifies content management by incorporating user-friendly features into the following :

  • Organizing
  • Searching
  • Subscribing
  • Contributing

Most of the People Think Why should I Use Salesforce CRM Content? what is the Benefits of using CRM Content ?

Why-is-Thinking-so-important-300x300

I Suggest to those People Please Refer the Below amazing Articles.

http://cloud4good.com/announcements/why-should-you-use-salesforce-content-why-not/

https://www.linkedin.com/pulse/what-benefits-professionals-can-leverage-from-crm-content-systems/

So After Understanding the concept let’s Move to the other Step

How to enable CRM Content in your Organization?

Refer Below Link and Enable CRM Content in your Organization Step by Step.

https://support.cloudhq.net/how-to-enable-document-libraries-in-salesforce/

What Salesforce Admin Should Know about CRM Content?

  • Publish Files to Libraries –

Go to the Libraries Tab and click on Contribute .

2nd

Choose File from your Local system and Enter Description , Select Library in which you want to Publish the file and Click on Save .

3rd

4th

You can Share File with your Standard OR Custom Object But you need to make Lookup field of that Object with Standard Object (Content Version) of CRM Content .

  • Create a New Library –

Click on New Button and enter Name, Description and Unique Name of the Library.

5th

  • Update Content Version –

Select any file Uploaded in CRM Content  From the Top Content Section  Or you can View file from Library and Click on Edit and Select Update Content Version and Choose file and Update the Version of that Content.

Using this you can publish a new Version of the file and update file Properties.

6th

8th

  • CRM Content Permissions ,Custom fields ,Customization of content Page Layouts

Search Salesforce Files in the left side Search Bar.

9th

You would These Options After clicking on Salesforce Files

10th

So These are the all customization which you can do regarding Library Permissions for Users, Create, modify and Delete Fields on Content Version, Manage Validation Rules etc..

Create, modify and delete custom fields is the option where you can make Standard or custom objects Lookup with Content Version So that you can upload file with the object from libraries tab.

As you see in Below Picture I can Upload File with Lead Or Account Object.

11th

What about Developers ?

11_md_confab_380

What Developer should Know about CRM content for working with Apex ?

Below is the CRM Content Object Hierarchy or you can say Data Model . This is thing which Developer must know for working with CRM Content.

 

12th

ContentWorkspace – ContentWorkspace is a Library which you can use for publish File . You can use Workspace(Library) Id while making Instance of Content Version so the File publish in that Workspace.

13th

ContentWorkspaceDoc – ContentWorkspaceDoc  Represents a link between a document and a public library in Salesforce CRM Content . It allows a document to be shared with multiple libraries.

In the ContentWorkspaceDoc there are two lookup Fields that is ContentWorkspaceId and ContentDocumentId.

14th

ContentDocument – ContentDocument is a document that has been uploaded in library in CRM Content.

For upload file as Content Document you have to Make Instance of Content Version Because Create() call not supported in Content Document.

15th

ContentVersion – This is a Specific Version of a Content Document(File) in CRM Content.

16th

So these are some things Developer or Admin should Know.

Please Refer the Below Links for Complete Details of Content Object.

https://help.salesforce.com/articleView?id=content_parent.htm&type=0

https://resources.docs.salesforce.com/210/latest/en-us/sfdc/pdf/salesforce_content_implementation_guide.pdf

https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_erd_content.htm#sforce_api_erd_content

Hope you find this helpful, in case of any queries/concerns, please post a reply or drop an email to me at sfdcsagarsindhi@gmail.com .

How to Tackle View State Issue During Upload file as a Attachment through Visualforce Page

In Previous Post, We Saw How to Upload File in Salesforce Through Visualforce .

So This Post is just to Handle the View State Error Occurred During Uploading File through Visualforce.

1st

For Complete Detail of View State Refer Link .

If you look into the Previous Post there were many Variables in Apex Controller which were use for getting file Body, Name, Description .

2nd

3rd

So If User Upload Large File Then file Body, Name and Description Come in these variables and It would Easily Increase the Heap Size Limit and View State Issue would arise.

4thSo For Avoiding this Issue Directly Make a Attachment Object Instance in Apex Controller and Get Body, Name of File From Visualforce Using that Instance .

5th

6th

Instead of Storing file body, Name, Description in these variables in apex controller it would Store directly in SObject Attachment So Heap Size Limit will not exceed.

Please Refer the Visualforce Page and Apex Controller for More Details.

<apex:page standardStylesheets="false" sidebar="false" showHeader="false" controller="AttachmentUploadController">

<html>
<body>
<c:UploadFile_Component />
<!-- Main Section -->
<main class="main-section">

<!-- Header Section -->
<header class="header-section">
<div class="headersection-tagline">
<div class="container">
<div class="tagline-left">Upload File as Attachment</div>
</div>
</div>
</header>
<!-- /Header Section -->

<!-- Form Section -->
<section class="inner-section">
<div class="container">
<div class="formbg-section">
<apex:form styleclass="form-horizontal" id="frm" enctype="multipart/form-data">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-4">File Name :</label>
<div class="col-md-8">
<apex:inputText value="{!attachment.name}" styleClass="form-control"/>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="col-md-12">
<label class="control-label col-md-2">File: </label>
<label class="btn btn-primary" > Browse File
<apex:inputFile value="{!attachment.body}" filename="{!attachment.name}" styleclass="form-control" style="display:none" onchange="filechange(event)"/>
</label>
<span class="uploaded-file" style="overflow: hidden; display: -moz-grid;" ></span>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-md-2">Description :</label>
<div class="col-md-10">
<apex:inputTextarea styleClass="form-control" value="{!attachment.Description}"/>
</div>
</div>
</div>
<div class="col-md-12">
<apex:messages />
<div class="form-group form-action-toolbar">
<div class="col-md-8 text-left">
<apex:commandButton id="btnsave" action="{!Upload}" styleClass="btn btn-primary" value="Save File as Attachment" />
</div>
</div>
</div>
</div>
</apex:form>
</div>
</div>
</section>
<!-- /.Form Section -->

</main>
<!-- /.Main Section-->
<script>
 
 function filechange(e)
 {
 var fileName = e.target.files[0].name;
 $('.uploaded-file').html(fileName);
 } 
 
</script>
</body>
</html>
</apex:page>

public with sharing class AttachmentUploadController {
public Id PageId ;
public Attachment attachment {
get {
if (attachment == null)
attachment = new Attachment();
return attachment;
}
set;
}

public AttachmentUploadController(){
PageId = ApexPages.currentPage().getParameters().get('id');
}

public PageReference upload() {
attachment.ParentId = PageId ;
attachment.IsPrivate = true;
try {
insert attachment;
} catch (DMLException e) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
return null;
} finally {
attachment = new Attachment();
}
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Attachment uploaded successfully'));
return null;
}

}

Hope you find this helpful, in case of any queries/concerns, please post a reply or drop an email to me at sfdcsagarsindhi@gmail.com .

 

 

Apex Rest API – Salesforce Integration with Twilio(Get a Call on your Mobile Number from Salesforce Through Twilio Voice API)

First of all, you need to Create an account on Twilio. If you do not a have an account on Twilio please refer to the link.

If you have Already then just Log in to your Twilio account. After Log in Your Twilio Account, you will See ACCOUNTSID and AUTH TOKEN as shown in the screenshot below.

1st

Copy this ACCOUNTSID and AUTH TOKEN we will use it later.

After this Click on Left Side Icon in Twilio Account and click on # Phone Numbers

3rd

4th

You would see your Twilio number (you would receive calls from this number on your connected Mobile number)

5th

After this Move on to the Verified Caller IDs on Left Side Bar and Enter Your Mobile Number on which you want to receive Call and Verify by Twilio.

6th

Now Login into your Salesforce Account and create a Remote Site Setting of Twilio End Point URL as given in the Twilio API Documentation

2nd

For Beginners Here is the Explanation of Remote Site Setting.

“When you want to access the external sites in your Salesforce application using callouts, web services, etc… You need to add that in the Remote Site Settings. This is just a security that force.com platform is going to check.
Before any Visualforce page, Apex callout, or JavaScript code using XmlHttpRequest in an s-control or custom button can call an external site, that site must be registered in the Remote Site Settings page, or the call will fail”

Now moving on to the Integration part, according to the Twilio voice API . We Need DEFAULT VERSION , ACCOUNTSIDAUTH TOKEN , Twilio Phone Number(From Phone Number) , Twilio Verified Phone Number(To Phone Number), Voice API End Point for Doing this Integration From Salesforce .

7th

 

8th

 

Here is Apex Controller with Apex REST API and Visualforce Page


public with sharing class TwilioVoiceCallExt 
{
 public String mobileNumber {get;set;}
 public String responseBody {get;set;}
 public CallResponse callRes{get;set;}
 public String DEFAULT_VERSION = '2010-04-01';
 public String AccountSID = 'YOUR ACCOUNTSID';
 public String Authtoken = 'YOUR AUTH TOKEN';
 public String FromPhoneNumber = 'YOUR Twilio Phone Number';
 public String VoiceAPIEndPoint = 'https://demo.twilio.com/welcome/voice/';

 public String Body = '';

 public Void VoiceAPI()
 { 
 String Crediential = EncodingUtil.base64Encode(Blob.valueOf(AccountSID + ':' + Authtoken));
 String EndPoint = 'https://api.twilio.com/'+DEFAULT_VERSION+'/Accounts/'+AccountSID+'/Calls.json';

 if(mobileNumber != '')
 {
 Body = 'To='+mobileNumber+'&amp;amp;'+
 'From='+FromPhoneNumber+'&amp;amp;'+
 'Url='+VoiceAPIEndPoint;
 }
 else
 { 
 ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,'Mobile Number is required.'); 
 ApexPages.addMessage(myMsg); 
 return;
 }

 Http h = new Http();
 HttpRequest request = new HttpRequest();
 request.setHeader('Content-Type', 'application/x-www-form-urlencoded');
 request.setHeader('Authorization', 'Basic '+Crediential);
 request.setEndpoint(EndPoint);
 request.setMethod('POST');
 request.setBody(Body);
 HttpResponse res = h.send(request);
 responseBody = res.getBody();

 //------------Deserialize the Reponse in different Class------------------//
 callRes = (CallResponse)JSON.deserialize(responseBody, CallResponse.class);

 if(callRes.Status == 'queued')
 {
 ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.CONFIRM,'Call successfully sent..!! Please Check Entered Mobile Number'); 
 ApexPages.addMessage(myMsg); 
 }
 else if(callRes.status == '400'){
 ApexPages.Message myMsg = new ApexPages.Message(ApexPages.Severity.ERROR,'Mobile number is not valid'); 
 ApexPages.addMessage(myMsg); 
 } 

 }// End of function

 //-----class for get Response---------//
 public class CallResponse 
 {
 public String Status; 
 }
}

<apex:page sidebar="false" controller="TwilioVoiceCallExt">

<apex:sectionHeader title="Voice Call"/>
<apex:form >

<!-- message -->
<apex:pageMessages />

<apex:pageBlock >
In Case of Trail Twilio Account You can Call Only <b>One Mobile Number</b> which is <b>Verified</b> by Your Twilio Account !!
</apex:pageBlock>
<!-- Page block Start-->
<apex:pageBlock >

<!-- Page block Button-->
<apex:pageblockButtons >
<apex:commandButton action="{!VoiceAPI}" value="Click to Call"/>
</apex:pageblockButtons>

<apex:pageblockSection >
<apex:pageBlockSectionItem >
Mobile Number
<apex:inputText value="{!mobileNumber}" />
</apex:pageBlockSectionItem>
</apex:pageblockSection>

</apex:pageBlock>
<!-- Page block End-->
</apex:form>
</apex:page>

Refer Below Links for Complete Details of APEX REST API.

http://www.salesforcetutorial.com/salesforce-integration-rest-api-basics/

http://www.jitendrazaa.com/blog/salesforce/call-salesforce-rest-api-from-apex/

https://trailhead.salesforce.com/en/modules/apex_integration_services/units/apex_integration_rest_callouts

Hope you find this helpful, in case of any queries/concerns, please post a reply or drop an email to me at sfdcsagarsindhi@gmail.com .

 

Upload File – Upload file as an Attachment OR as a Salesforce File Related to Particular Object using Visualforce Page

Visualforce Page for Upload File as an Attachment OR in Chatter.

2ndTo Upload file as an attachment or as a file using Visualforce,one must have Record Id so that the Uploaded file links with that Record.

In Order to use Bootstrap, JQuery or CSS for Designing purpose you can refer to the following link to access Script files

https://drive.google.com/open?id=0B55QW3bpdoFPYkpyWXZJOE1rZFU

Upload this Zip file as a static Resource in your Salesforce Org and use it in Visualforce Component.

1st


<apex:component>

<apex:stylesheet value="{!URLFOR($Resource.Jquery_ToolKit,'css/vendor/bootstrap.min.css')}"/>

<apex:stylesheet value="{!URLFOR($Resource.Jquery_ToolKit,'css/app.css')}"/>

<apex:includeScript value="{!URLFOR($Resource.Jquery_ToolKit,'js/vendor/jquery.min.js')}"/>

</apex:component>

Now Use this Component in your Visualforce Page and use some Apex Input and Output Tags.

  1. <apex:inputText>to get File title and<apex:inputTextarea> to get File Description as Input from User .
  2. <apex:Input file> for choose attachment file.
  3. <apex:commandButton>to Save Attachment .
  4. Jquery function to show to name of file.

<apex:page standardStylesheets="false" sidebar="false" showHeader="false" controller="UploadFileController">

<html>
<body>

<c:UploadFile_Component />
<!-- Main Section -->
<main class="main-section">

<!-- Header Section -->
<header class="header-section">
<div class="headersection-tagline">
<div class="container">
<div class="tagline-left">Upload File as Attachment</div>
</div>
</div>
</header>
<!-- /Header Section -->

<!-- Form Section -->
<section class="inner-section">
<div class="container">
<div class="formbg-section">
<apex:form styleclass="form-horizontal" id="frm">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label col-md-4">File Name :</label>
<div class="col-md-8">
<apex:inputText value="{!AttchName}" styleClass="form-control"/>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<div class="col-md-12">
<label class="control-label col-md-2">File: </label>
<label class="btn btn-primary" > Browse File
<apex:inputFile value="{!AttchBody}" fileName="{!AttchName}" styleclass="form-control" style="display:none" onchange="filechange(event)"/>
</label>
<span class="uploaded-file" style="overflow: hidden; display: -moz-grid;" ></span>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<label class="control-label col-md-2">Description :</label>
<div class="col-md-10">
<apex:inputTextarea styleClass="form-control" value="{!AttchDesc}"/>
</div>
</div>
</div>
<apex:messages />
<div class="col-md-12">
<div class="form-group form-action-toolbar">
<div class="col-md-8 text-left">
<apex:commandButton id="btnsave" action="{!Upload}" styleClass="btn btn-primary" value="Save File as Attachment" />
<apex:commandButton id="btnsave1" action="{!UploadChatterFile}" styleClass="btn btn-primary" value="Save File in Chatter" />
</div>
</div>
</div>
</div>
</apex:form>
</div>
</div>
</section>
<!-- /.Form Section -->

</main>
<!-- /.Main Section-->
<script>
 
 function filechange(e)
 {
 var fileName = e.target.files[0].name;
 $('.uploaded-file').html(fileName);
 } 
 
</script>
</body>

</html>
</apex:page>

In order to Insert file as an Attachment Related to Record Just make the instance of Attachment Object and put the Values Like File Title, File Description, Body, Related Record Id.

In Order to Insert file as Salesforce File, first of all we need to make the Lookup field for particular Object with related list in which we want to insert file in Content Version. Please refer to the steps I have performed “I have created 2 Lookup fields in Lead and Account Objects”.

To create Lookup fields in Content Version

Salesforce Files -> Create, Modify, Delete custom fields –> New Field

3rd

4th

5th

After creating this Lookup Field Make Instance of Content Version and put Required Fields as we did for Attachment.

Please refer to the controller for more details.


public with sharing class UploadFileController {

Public Id PageId {get;set;}
public Blob AttchBody {get;set;}
public String AttchDesc {get;set;}
public String AttchName {get;set;}
Public Attachment attch {get;set;}

public UploadFileController(){

PageId = ApexPages.CurrentPage().getParameters().get('Id');

}

public PageReference Upload(){

attch = new Attachment(ParentId=PageId,Description=AttchDesc,Name=AttchName,Body=AttchBody);

try{
insert attch;
AttchBody = null;
AttchDesc = null;
AttchName = null;
}
catch(Exception ex){
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,ex.getlineNumber()+' '+ex.getMessage()));
return null;

}
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Attachment uploaded successfully'));
return null;
}

public PageReference UploadChatterFile() {


ContentWorkspace cw =[SELECT Id FROM ContentWorkspace WHERE DeveloperName = 'Test_Workspace'];

ContentVersion v = new ContentVersion();
v.versionData = AttchBody;
v.title = AttchName;
v.FirstPublishLocationId = cw.Id;
v.pathOnClient = AttchName;

If(PageId.getSObjectType() == Account.sObjectType){
v.Account__c = PageId;
}
If(PageId.getSObjectType() == Lead.sObjectType){
v.Lead__c = PageId;
}

v.Description = AttchDesc;

try{
insert v;
AttchBody = null;
AttchDesc = null;
AttchName = null;
}
catch(Exception ex){
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,ex.getlineNumber()+' '+ex.getMessage()));
return null;
}

ApexPages.addMessage(new ApexPages.message(ApexPages.severity.INFO,'Attachment uploaded successfully in Chatter'));
return null;
}
}

Hope you find this helpful, in case of any queries/concerns, please post a reply or drop an email to me at sfdcsagarsindhi@gmail.com .