Browse Category:

Sending a VF Page as Attachment in Mail through Apex Class

Following code can be used for sending a vf page as an attachment with an email:

public class Gene_PDF{ 
public PageReference sendPdf(){                
     PageReference pdf = Page.mail_pdf;//mail_pdf is the name of vf page
     // goToNextPage('email');
     Blob body;                
        body = pdf.getContent();
     }catch(VisualforceException e){
            body=Blob.valueOf('Some text');
      Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
      attach.Body = body;
      Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
      mail.setToAddresses(new String[] { email });
      mail.setSubject('PDF Email Demo');
      mail.setHtmlBody('Here is the email you requested! Check the attachment!');
      mail.setFileAttachments(new Messaging.EmailFileAttachment[] { attach }); 
      // Send the email    
      Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
      ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.INFO, 'Email with PDF sent to '+email));
      return null;

Here 1) mail_pdf is the visualforce page that we want to use as attachment and

2) email is a pre-acquired Email-ID from user to which the email will be sent.

Using @future method in salesforce

Using @future method in salesforce and its limitations

Salesforce provides different ways to run your code asynchronously like Batch apex, @future method. In this post we will see how to use @future method, its advantages, limitations and the precautions that we need to follow while using it.
We can use the @future methods in cases where methods are long running. In such cases we can prevent governers limits by making it as asynchronous transaction. @ future methods also help in preventing mixed dml errors by isolating multiple dmls.
In order to mark a method as future we have to simply mark it with the ‘@future’ keyword as shown in below snippet.
Public static void futureMethod(){
//Your Code Here

Points to remember while creating @future methods:

1. future methods must always be static methods.
2. @future methods cannot return anything and its return type should always be void.
3. The input parameters to such methods can only be primitive types, arrays of primitive type or collections of primitive types.
4. Input parameters cannot be sobjects or collection of sobjects.
@future methods can also be used to make callouts to external services. To use this we must mark callout=true specifically. If it is not specified then the default value is taken as false.
public static void myfuturecalloutmethid(){
//code to call external services

Why are sObjects not allowed as parameters in case of @future methods?

It is because the sobjects may change by the time the method is executed, in such cases the @future method may overwrite the already saved values of the sObject record.
What is the workaround for above sobject case?
We can pass the object Id as parameter and then query the record within the @future method and then work on the latest data.
Limitations of @future method:
1. You cant call a future method from another future method.
2. You can call up to 50 @future methods per transaction.
3. You can call up to 250000 future methods per 24 hours. This is in conjunction with all types of asynchronous methods like batch apex.
4. @future methods are not executed during salesforce downtime and any already running jobs during the start of downtime are halted and restarted after the downtime.
Please go through Future Methods with Higher Limits (Pilot)
Precautions that we need to follow while using future methods:
1. Make sure you dont put too much in a future method as this will increase the execution time and may lead to delaying of other requests after the organisation limit of 2000 unprocessed future jobs is hit.
2. Opt for batch apex when you are processing large no of records.
3. Test your future methods with maximum possible data as this will give you an idea of how much the job may take during real time.


Platform Cache varient 2 – Org Cache

Continuing with Platform Cache….

2. Org Cache : The second variant of Platform Cache is the Org Cache. Org Cache does the same thing of storing the data in session, but the data stored is accessible through out the org, irrespective of  user, which is not the case with Session Cache.
If user1 is storing a  value1 in org cache, it is accessible by user2 also.

We can have different partitions to store values. We use the Cache.Org and Cache.OrgPartition classes to manage values in the org cache. To manage values in any partition, use the methods in the Cache.Org class. If we are managing cache values in one partition, use the Cache.OrgPartition methods instead.

This example stores a DateTime cache value with the key orderDate. Next, the snippet checks if the orderDate key is in the cache, and if so, retrieves the value from the cache.

// Add a value to the cache//
DateTime dt = DateTime.parse(’06/16/2015 11:46 AM’);  Cache.Org.put(‘ns1.partition1.orderDate’, dt);
if (Cache.Org.contains(‘ns1.partition1.orderDate’)) {
       DateTime cachedDt = (DateTime)Cache.Org.get(‘ns1.partition1.orderDate’);


To refer to the default partition and the namespace of the invoking class, omit the namespace.partition prefix and specify the key name.

Cache.Org.put(‘orderDate’, dt);
if (Cache.Org.contains(‘orderDate’)) {
DateTime cachedDt = (DateTime)Cache.Org.get(‘orderDate’);

The local prefix refers to the namespace of the current org where the code is running. The local prefix refers to the namespace of the current org where the code is running, regardless of whether the org has a namespace defined. If the org has a namespace defined as ns1, the following two statements are equivalent.

Cache.Org.put(‘local.myPartition.orderDate’, dt);
Cache.Org.put(‘ns1.myPartition.orderDate’, dt);

This is all about the Org Cache in apex.  There is another interesting thing about Platform Cache!

We can access cached values stored in the session or org cache from a Visualforce page with global variables.We can use either the $Cache.Session or $Cache.Org global variable. Include the global variable’s fully qualified key name with the namespace and partition name.

This output text component retrieves a session cache value using the global variable’s namespace, partition, and key.

<apex:outputText value=”{!$Cache.Session.myNamespace.myPartition.key1}”/>

This example is similar but uses the $Cache.Org global variable to retrieve a value from the org cache.


Now the Platform Cache concept seems more useful! We can directly use it in Vf page!!

Salesforce is Awesome!

Bundles in Steelbrick CPQ

Steelbrick CPQ allows users to define bundles to be added to Quote. This proves very helpful as it saves time of adding every product individually.

For achieving this there are two objects in CPQ.

The first is Features. Features is basically definition of the bundle. Features can be added from related lists of Products. The product that has a feature becomes the master. So whenever the Master is added, the feature can be added.

Feature is just the name of the bundle, but actual contents of the bundle are stored in Options object.

Options can be added from related list of the Features record. Options are references to the products to be included in the bundle.

Apart from just adding the products in the Bundles, various configurations can be added like predefining the quantity and whether the Quantity can be edited while adding the products in the Quote or it has to be fixed, whether the Product is mandatory or not, whether the product has to be selected by default in the bundle etc.

Bundle proves to be one of the most useful feature of the CPQ.

Rest API Call for GET and POST

global with sharing class MyRestResource {

global static Account doGet() {
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
String accountId = req.requestURI.substring(req.requestURI.lastIndexOf(‘/’)+1);
Account result = [SELECT Id, Name, Phone, Website FROM Account WHERE Id = :accountId];
return result;

global static String doPost(String name,
String phone, String website) {
Account account = new Account();
account.Name = name; = phone; = website;
insert account;
return account.Id;


  1. GET – call following URL in workbench rest explorer””
  2. POST -“”

    JSON Format-

“name” : “Wingo Ducks”,
“phone” : “707-555-1234”,
“website” : “”



What are Salesforce ID’s composed of?

The Id Field Type is a base-62 encoded string.

Each character can be one of 62 possible values:

  • a lowercase letter (a-z) – 26 values
  • an uppercase letter (A-Z) – 26 values
  • a numeric digit (0-9) – 10 values

As there is a combination of lower and upper case letters the casing of the 15 character Id has significance. E.g. 50130000000014 c is a different ID from 50130000000014C.

Within a 15 character Id the breakdown is:

  • First 3 characters – Key Prefix As per Jon’s answer, the first 3 characters are the key prefix that identify the object type. There are a few exceptions to this where multiple objects all share the same key prefix! There are a number of fixed key prefixes that are common across all of Salesforce. Custom objects get a unique key prefix per Org. Custom objects in managed packages can have a different key prefix in each installed org.
  • The 4th Character – instance/pod identifier
  • 5th Character – instance/pod identifier – extended
  • 6th character – Reserved. Will be 0 until such time that Salesforce has a need for it.
  • Remaining 9 characters – basically a really big number. Like 62^9 big or 238,328! That’s a lot of servers!

To this you can add an optional 3 character suffix that will make the Id unique case-insensitive. This is useful when working with programs that can’t maintain the case of the ID (E.g. Excel VLookup).

Create Short URLs with Bitly

This post is related to how to integrate Salesforce and Bitly to create short urls to include in communication Messages.

Step 1. Sign-up for Bitly

To use the Bitly API you will need to register. You can sign-up using Twitter, Facebook, or create a new login with their service. I chose to create a Bitly specific login using below url.

Step 2. Create Bitly Apex Classes

I developed below class, that encapsulates the Bitly http callouts.

global class bitly
Public String mode;
Public String sUrl;

public string getbitly ()
String shorten;
XmlStreamReader reader;
HttpResponse res;

//First, build the http request
Http h = new Http();
HttpRequest req = buildWebServiceRequest(sURL);

//Second, invoke web service call
if (mode==’live’) { res = invokeWebService(h, req); }

if (mode==’live’) { reader = res.getXmlStreamReader(); }
String str = ‘Foo bar’;
reader = new XmlStreamReader(str);
return readXMLResponse(reader,’shortUrl’);

public static HttpRequest buildWebServiceRequest(String purl)
String endpoint;
HttpRequest req = new HttpRequest();
endpoint = ‘’+purl +’&history=1&login=BitlyAPPName&apiKey=R_42d58b4eda1c412b8ef30577442428e4’;
return req;

public static HttpResponse invokeWebService(Http h, HttpRequest req)
{ //Invoke Web Service
HttpResponse res = h.send(req);
return res;

public static String readXMLResponse(XmlStreamReader reader, String sxmltag)
{ string retValue;
// Read through the XML
if (reader.getEventType() == XmlTag.START_ELEMENT)
if (reader.getLocalName() == sxmltag)
if (reader.getEventType() == XmlTag.characters)
retValue = reader.getText();
return retValue;

Whenever you implement it you just need to change BitlyAPPName and apikey from endpoint.


For calling bitly class use below lines

bitly b = new bitly();

b.mode = ‘live’;

b.sUrl = ‘’;

system.debug(‘Check BitLy short url – ‘ + b.getbitly() );


You will output as “Check BitLy short url –

15 Digit Vs 18 Digit Salesforce Record ID

ID fields in the user interface contain 15-character, case-sensitive strings. Each of the 15 characters can be a numeric digit (0-9), a lowercase letter (a-z), or an uppercase letter (A-Z).Two unique IDs may only be different by a change in case.

Because there are applications like Access or Excel which do not recognize that 50130000000014c is a different ID from 50130000000014C, an 18-digit, case-safe version of the ID is returned by all API calls. The 18 character IDs have been formed by adding a suffix to each ID in the API. 18-character IDs can be safely compared for uniqueness by case-insensitive applications, and can be used in all API calls when creating, editing, or deleting data.

To convert 18-character ID to a 15-character version, truncate the last three characters. recommends that you use the 18-character ID.

  • 15 digit case-sensitive version which is referenced in the UI ( at Database level).
  • 18 digit case-insensitive version which is referenced through the API.


Editing Records of Standard Objects from Salesforce site

Salesforce Sites or Sites lets you create web sites that run natively on It allows external users to access and modify records from Salesforce without the need of authentication or license.

But it does not allow Edit access to most of the standard objects. If there is a need to allow editing records of standard objects, one cannot directly edit them using fields directly on the Visualforce page (except for Orders and Contracts).

There is a simple yet effective work around for that which works just fine.

Instead of using fields reference on the Visualforce page, create variables in the controller and use them to get the input from the Visualforce page. Once the value is in those variables, assign them to the respective fields of the standard object in the controller.

Below is the part of the code that explains how this works.

<apex:inputtext value="{!value1}" label="Field1" />
<apex:inputtext value="{!value2}" label="Field2"/>
public String value1{get;set;}
public String value2{get;set;}
public pageReference updates(){

    update case_record; 

Platform Cache

Hi All,

I would like to share one of the challenges that I faced recently. My requirement was to get a value from  first page to the third page in sequence.
I thought of storing the value in custom setting, but there can be more than one user using the functionality at the same time. So not Done.
Cookies did not work for me. I tried several other concepts and ended up using Platform Cache.

Platform Cache will let us to store and retrieve data associated with salesforce session or throughout org. It has two varients:

1. Session Cache: Stores data for the user session only. Before we proceed with example lets know about the Plaform Cache Partition.

We use Platform Cache partitions to improve the performance of your applications. Partitions allow you to distribute cache space in the way that works best for your applications. Caching data to designated partitions ensures that it’s not overwritten by other applications or less-critical data.
To use Platform Cache, first set up partitions using the Platform Cache Partition tool in Setup. Once you’ve set up partitions, you can add, access, and remove data from them using the Platform Cache Apex API.
To know more on Partitions visit here

Method of using Session Cache:

To store data using default partition.
Cache.Session.put(‘wholeAndSoleKey’,’data’ );

To check if key exists:

To fetch data:

To remove data:

Example 1 involving two different users:
Here suppose for user1 started the process and session cache has saved data under key ‘wholeandsolekey’.

User2 is now started process and session cache stores value under same key ‘wholeandsolekey’.

Now user1 is trying to fetch data from session cache:

User 1will get data as ‘dataUser1’. That means, when user2 saved its data it did not override user1’s data even though they are both using the same key to fetch data.

Example 2 involving only one user:
Here suppose there is a button on Contact object. class having session cache is being executed on click of the click.
User1 clicked button on contact1, session cache stored the value in cache:

User1 clicked the button on record 2:

User1 is now fetching data from session cache and she gets value as contId2. contId1 is overridden by contId2 since same user is using same key to store data.

This is how session cache works.

Will come up with the second varient of Platform cache soon.

Thank you,
Swathi Melkundi