Saturday 4 June 2011

Force.com Email Service (Execute apex code through email)



Violent way to start the post......SHOOT !! an Email...This is what we hear frequently ....and Salesforce has the ability to shoot email to itself and do relevant tasks based on the email sent. Isn't that cool...Lets see how this can be achieved..

Salesforce can send email to itself(specific org) and retrieve all the information in the email (like subject,text body,attachment etc) .This is facilitated by creating an apex class that implements Messaging.InboundEmailHandler interface. Simple example of this would be say email subject contains text "Create contact for Chaitanya" .We could read this field from subject (using relevant method)and create a contact for Chaitanya in the code. If the subject contains text "Delete contact for Chaitanya" proper delete action can be processed in the code.
 
Steps to Create an Email service .
1) Create an Apex class that implements Messaging.InboundEmailHandler interface .In this class mention all the processing (preferably call other class for complex operations )that needs to be done based on the subject/textbody/attachments of the email. Salesforce provides relevant methods to retrieve the specific information like
fromAddress :Email address mentioned in the from field
subject :Subject text of the email. 
plainTextBody :Plain text version of email etc 
Complete list is found here Doc

global class testEmailService implements Messaging.InboundEmailHandler
   {
     global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email,Messaging.InboundEnvelope envelope)
       { 
     Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();
    // Do all the processing here based on the information retrieved
    // Go to the following link for all the methods available for this interface    
   // https://na10.salesforce.com/help/doc/en/code_inbound_email.htm 
   return result;
        }
   }




2) Go to  Setup->Develop-> Email Services-> New Email Service
There are multiple fields on the page to fill.Of them some important fields are :
a) Email Service Name : Mention the relevant name for the email service
b) Apex Class: Mention the apex class that implements Messaging.InboundEmailHandler interface (Here in our case  "testEmailService")
c) Accept Email From : If this is filled out,the email service only works if the email is received from the addresses mentioned here.If email service receives a message from an email address or domain not listed out here, then the email service performs the action specified in the Unauthorized Sender Action failure response setting.
d) Active : Now dont ask me why isnt my email service not working .So please make this active  :)
e) Enable Error Routing :Fecilitates sending  email to an alternative email address incase of failure

3) Save the email service .Now the page displays "Email address" section which is the place to generate an automatic email address that will be consumed by our present Email service. Following are the fields on the page
a) Email Address :Its up to the person to give relevant local part of Email address.
b) Active : Do i have to tell this again :)
c) Context User :The email service uses the permissions of the Context User when processing the inbound email
d) Accept Email from : Same functionality as mentioned in the "New Email Service" page.

Click on save and salesforce  will create a unique email address . This is the address you send your email to for further processing .From where to send email entirely depends on the ones own requirement .If sending email from  outside force.com platform just take the unique email address and send email to the address with relevant information(depends on requirement) . If with in Salesforce following code helps 

Say email address is "testEmailService@46hgvb8g1fj0jbjsfj56kngvx.az1foma0.f.apex.salesforce.com"



Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();   
mail.setToAddresses('testEmailService@46hgvb8g1fj0jbjsfj56kngvx.az1foma0.f.apex.salesforce.com');                    
mail.setSubject('Process test Service');                   
mail.setPlainTextBody("Mention the relevant information here");        
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });


Now as per the flow email is recieved by salesforce and email service is triggered which further triggers the code in the "testEmailService" class.


One more use case for using the power of email service is serializing batch apex. At times I know people pulling out their hair and who  literally became "bald" (not literally though :)) thinking on how to instantiate another batch apex call from the present batch apex. Actually its not possible for us to call a batch apex from another batch apex directly. We can instantiate another batch apex call only when the present batch completed its processing .This can be facilitated by using "Email service" . In finish method of batch apex send an email (with the results of the batch in the subject or in plain text body) .Configure respective email service to consume this email. And call another batch apex in the apex class that implements respective interface  



For further reading : 

P:S Image source-Google .I don possess any gun :)


Tuesday 3 May 2011

Wrapper Class in Apex/Visual force page


Wrapper class is a very powerful concept that can be used in multiple scenarios. Putting aside the word "Wrapper" it is nothing but just a class.Just like what we have in a class ,we  have methods,Properties etc in a wrapper class too.Here is an use case for wrapper class

Requirement : A Visual force page has to display all the Contacts available for an Account .Contacts should be listed out in the table row wise(default being column wise) . Only created "date"(Strip the time part) of the contact should be displayed .

Sample page:









Apex Code :



Visual force page :


Result :












Huh!! now please don't catch a bug here that no values are displayed for phone. I admit i missed them..Pretty tired ...accept my apology and take it for granted :) :)

Power of wrapper is seamless .It can be used to process only the records that are selected in vf page.Click on the link for example.

http://wiki.developerforce.com/index.php/Wrapper_Class

Happy Coding!
C ya Soon with another Post

Relationship field not working in Trigger.New/Trigger.Old



While  i was working on a trigger i observed one strange behaviour. Lets say there is one custom object "Test__c" which has a look up to Account and the field being 'Account__c'. I performed update operation on Test__c so here is how my trigger would look like

Here though i was sure Name field of Account contains some value the same is not assigned to the string. I tried it many times but always ended up no where with no value being assigned.So instead of directly getting the value from Trigger.New i got the ids of "Test__c" records and then separately queried them to get respective values and to my surprise it worked..


Though strange i dint understand the underlying concept (Totally Dark!!!) .Can some one beam some light on this !!


H C !! 

Monday 2 May 2011

(Describe Information)How to retrieve all the fields in an Object


Recently i had a requirement of merging two accounts(Say one as "Parent" Account and other as "Child" Account).Following is one of the point listed out in requirement

If a parent Account field doesn’t contain a value and child Account contains that value, then the child Account field's value is populated in the parent field. ( On a lighter note ,how do people get these ideas  Note :This sentence is not a part of requirement though :) :) )

We have nearly 250+ fields(:O ..i dnt even remember 10% of those) in Account and according to the requirement almost all writable fields should be queried and checked for the blank/null value.

Requirement at
1) First we used the describe calls to get the list of fields available for the Object.
2) Looped through the fields available for the object and constructed the soql string for quering the records .
3) Returned the Parent record and child record based on the query constructed
4) Compared Parent and child account fields by using sobject method and updated accordingly


Please find the code snippet for this





Any better solution for this is highly appreciated :)

Date Time filter in Where Clause of Soql Query


"What if all our events in life are stored in database and we can query through the records to know about a specific day's events" -By UNKNOWN

 At times while checking for records in Force.com explorer(or any other tool like brain engine etc) we need to give some specific date time value(as filter) in the where clause of SOQL Query.


Apart from the date literals like Today,Yesterday etc we can give specific date time value. For Example 
26-April-2011 can be given as 2011-04-26T00:00:00Z


Including this in SOQL would look like:


select id,createddate from account where createddate= 2011-04-26T00:00:00Z


Following is the link where all date literals are listed out::
http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_select_dateformats.htm




Happy Coding!! :)
Cheers





List Index Number

Definition of List from Answers.com :keep a record(This is the keyword here); tabulate
Antonyms: forget

Ok ok I understand..Here comes the main post :

Force.com developers use collection type "List" quite often .We use List when the sequence(Index) of elements is important.

Lets take an Example :Assume we have two lists List1 and List2


As we added the Strings at the same time into two different lists we can be sure that respective strings have same Index no.

so  value at List1[i] = value at List2[i]  ..

Lets try to go through an USE CASE FOR THIS



Requirement  :Lets assume we have two objects Source(Custom Object) and  Contact(Standard Object) .Source object is a flat record (Normalized) object which stores contact Information and we need to push this data to Contact Object (De Normalizing)separately ie we need to insert two contacts as separate records.Also we need to track any error during insert operation at the source(custom object) level in a field called "Error Description" .( Note :For Simplicity only contact information is given)

Anatomy of Source Object:

Object Name :Source__c
Fields :
a) ContactName1__c
b) ErrorDescription__c
c)Email__c


Anatomy of Contact Object :
Object Name :Contact
Fields:
LastName
Email

Here in Contact Object Email is of Datatype "Email" .So proper email type value should be present in this field.

Following is the mapping: Assume we have two  records in the source object





In the above image we can observe that email mentioned for the second source record is not a valid one.So this would throw us an exception which is updated in the respective record's Error description field

Code for Insertion :



I executed the code in the system log and following is the Status now:










In the image we can observe Error Description is updated with the respective error.

This would be very useful when we are loading data into different objects from a single object and need to track the errors at the source object level so that the data can be cleansed



Happy Coding :) !!



Sunday 1 May 2011

MAXIMUM DEBUG LOG SIZE REACHED


"I would love to lift the limits up, but salesforce won't give me the source code" :)


At times there could be a situation where Scripts statements are more and we hit the limit of "Debug Log Size" and we get the message "MAXIMUM DEBUG LOG SIZE REACHED" .One way to overcome this is to set filters for the debug logs as mentioned below :



Go to Monitoring-->DebugLogs-->Filters (set all the Filters to None expect for the apex Code)











In this way we restrict the log to show only the error part. But say u still want to get some other Information(Like HeapSize,State of different variables and statistics etc) from the Debug logs irrespective of the log filter.In such cases email messages help ...Just put the Email code at the Line  No where you want to track the code and then put the excepted results in the Subject or Text body of the email and send an Email to some one of your choice(probably in most cases the same person). So now the email tracks everything related to code :Here is an snippet of code which tries to get different values returned for limits .

I was working on batch apex and the size of debug log was tooooooo high...So to keep track of some governor limits and to know the status and state of different variables in the batch i used email concept.






Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();  
String[] toAddresses = new String[] {'chaitanya_cvm@yahoo.com'};         
mail.setToAddresses(toAddresses);                    
mail.setSubject('At Post Process limit queres::'+ limits.getScriptStatements ()+ 'No left::'+limits.getLimitScriptStatements () +'heapsize::'+limits.getHeapSize ()+'left'+limits.getLimitHeapSize());                   
mail.setPlainTextBody("Get Error Message:"+e.getmessage());                 Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });

            
So above mail just sends me the list of limits used and available limits etc



Note :Make sure to send emails to "Internal " users only so as to make sure we don't hit daily email limit. And most importantly remember to remove this code after unit testing is done :)

Happy Debugging!!!