Tuesday 21 July 2015

Salesforce Facebook Twitter Integration Workaround

Have you ever come across a need when you need to listen to a particular handle on Facebook or Twitter? We most of us have come across, let it be while implementing service cloud to hear issues people posting on Social or while doing Sales cloud implementations looking for what people are looking at or new leads.

To implement these on searching web, most people will come across many fancy third party tools and integrations created. I have a simple workaround for simple integrations related to handling one or multiple handles, without spending a single extra penny.

Step One :

Create an email service (Email to Case, Email to Lead or Custom Email Service) To handle your use case, like creating a case while somebody mentions your handle on a social account with some specific key words like "Dispute" , "Not Happy" or any other Hash tags (Would need to parse the email body with a simple "Like" search or a more advance "Regular Expression Search".) and create a simple case using Email to Case. Or create a Lead or data in any other custom record.

Step Two :

Redirect the emails from registered email id of those handles to this account and based on Subject lines like (Somebody mentioned you on Facebook or twitter) you may process the mail further or discard it on the gates.

And just with these few simple steps and workaround you have your own integration created.

While capturing the email you might also want to capture the replyTo in the email service you have written so that from the Salesforce itself you may post your reply on Social network!! Is it not easy and great! 

Saturday 18 July 2015

Salesforce Security Considerations


Storing data in cloud with no control over it makes many people anxious and really worried but Salesforce comes with really secure data storage capabilities which for enterprises at their own is not achievable or even if it is, it will be really expensive. So relax Salesforce has been audited by many international standards and have acquired following certifications 
  • PCI DSS
  • FISMA
  • ISO/IEC 27001:2005
  • SAS 70 Type II
  • SysTrust
  • EU-US



Salesforce prevents your data from any Physical damages by providing safety from 

  • Humidity & Temperature 
  • Power Loss 
  • Network Loss or Congestion
  • Early Fire Detection & Prevention

To secure your data from intrusions salesforce follows following approach

  • SPI at perimeter firewall : Stateful packet inspection is done at all the packets coming in on the outer firewall, stateful helps in letting network know the connections and sessions and with this technology packets are not only invested for their headers but for their payloads too, thus leaving chances to error at very low probability.
  • Bastion Stations : After the outer firewall screened with SPI packets reach bastion stations, which are specially designed computer to defend any attacks, these are defined and designed with highest possible security parameters to in selfs are enough to prevent any attack
  • TLS/SSL : Cryptographic protocols encrypt all network data transmissions.

And To prevent the application, we have all sort of security features like : Profile, Object Level security, Field Level security and Record level security as per requirement orgs can always enable two factor integration or have third party biometrics installed!


So place your data on Salesforce and worry just about building apps and logic, without worrying about anything related to infrastructure. 

Saturday 6 July 2013

ICS File In Salesforce

Have you ever tried sending a meeting Invitation from Salesforce using Apex Code. Below is the code to Achieve the Same.

It creates and sends an email. For any Calendar meeting the universal format for file Accepted is .ICS
and it is nothing but a string containing all the information.

I have used this file as the mail attachment and have set the Content type of email as "text/calendar"

Code Below
--------------------------------------------------------------------------------------------------------------------------

String vCal = 'BEGIN:VCALENDAR' + '\n' + 'PRODID:-//Force.com Labs//iCalendar Export//EN' + '\n' +
'VERSION:2.0' + '\n' + 'CALSCALE:GREGORIAN' + '\n' + 'METHOD:REQUEST'+ '\n'+ 'BEGIN:VEVENT'+ '\n' +
'DTSTART:20131008T103000Z' + '\n' + 'DTEND:20131008T113000Z' + '\n' + 'DTSTAMP:20091008T103839Z' + '\n' +
'ORGANIZER;CN=varun.vatsa@gmail.com:mailto:varun.vatsa@gmail.com' + '\n' + 'UID:varun.vatsa@gmail.com'+ '\n' +
'CREATED:20091008T103839Z' + '\n' + 'DESCRIPTION:something' + '\n' + 'LAST-MODIFIED:20091008T103839Z' + '\n' +
'SEQUENCE:0' + '\n' + 'STATUS:CONFIRMED' + '\n' + 'SUMMARY:Test ICS Mail Format' + + '\n' + 'TRANSP:OPAQUE' + '\n' +
'END:VEVENT'+ '\n' + 'END:VCALENDAR';
List<String> toAddresses = new List<String>();
        toAddresses.add('varun.vatsa@gmail.com');
        Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
        email.setSubject('Test');
        email.setToAddresses(toAddresses);
        email.setHtmlBody('Test');
        email.setPlainTextBody('Test');
        Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
        efa.setFileName('rfc2445.ics');
     
        efa.setBody(blob.valueOf(vCal));
        //attachments.add(efa);
        efa.setContentType('text/calendar');
        email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
         Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});

Friday 11 January 2013

Amazon S3 signature for Apex

Hi,

Please find below the method to return a valid signature generated in Salesforce's Apex language.
This signature is required to make any Rest/Soap call on Amazon's S3 servers.

Arguments to this method are : Current DateTime and the name of Operation that you want to perform for example "Get Object".

 public static String getSignature(DateTime now,String op){
       
        //format should be like 2006-01-01T12:00:00.000Z
        String formattednow = now.formatGmt('yyyy-MM-dd')+'T'+now.formatGmt('HH:mm:ss')+'.'+now.formatGMT('SSS')+'Z';
        System.Debug('Formatted date : '+formattednow);
       
        String canonical = 'AmazonS3'+op+formattednow; //"AmazonS3" + OPERATION + Timestamp
       
        System.debug('CANONICAL = '+canonical);
       
        Blob bsig = Crypto.generateMac('HmacSHA1', Blob.valueOf(canonical), Blob.valueOf(secretAccessKey));
       
       
        String signature = EncodingUtil.base64Encode(bsig);
        return signature;
    }


Monday 24 December 2012

Apex Generation Failed Unable to find element + Amzon S3

Hi,

While generating Apex code from wsdl provided by Amazon (For S3) I got the above mentioned error. Below is a snippet from WSDL file.

 <xsd:schema
     elementFormDefault="qualified"
     targetNamespace="http://s3.amazonaws.com/doc/2006-03-01/">
      <xsd:include schemaLocation="AmazonS3.xsd"/>
    </xsd:schema>


To Resolve the error I downloaded XSD file from Amzon only and replaced the content of tag <xsd:include> with the content of the XSD file, and I was able to generate the Apex code file.

Sunday 23 September 2012

Open Connection SalesForce Rest API

Hi

I have written a sample code in java to make a persistent connection to Salesforce's Rest API, This example uses Oauth Grant_Type ="password" to provide a fresh access_token each time the request is made.

Please find the code below. To make this code work you need to add package <httpcomponents-client> to your classpath. which can easily be downloaded from  http://hc.apache.org/httpcomponents-client-ga/

 


Please find the code :

package connection;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpException;
import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONValue;



public class OauthConnection {

    //Variables to be populated after gaining the Access token.
    private String accessToken = null;
    private Map<String, String> oauthLoginResponse;
   
    //Constants to be used in this class.
    private static final String clientId = <Your Client ID>;  
    private static final String clientSecret = <Your Client Secret>;
    private static final String environment = "<SalesForce Instance>";
    private static final String authUrl = "/services/oauth2/token";
    private static final String restUrl = "/services/data/v25.0/";
    private static final String queryUrl = "/services/data/v25.0/query";
    private static final String username = "<Your SFDC USER NAME>";
    private static final String password = <SFDC PASSWORD WITH SECURITY TOKEN>;
   
   
   
    public static void main(String[] args){
        try{
       
            OauthConnection oc = new OauthConnection();
            oc.oAuthSessionProvider();
           
            oc.executeQuery();
       
        }catch(Exception e){
            e.printStackTrace();
        }
      }
       
    public void oAuthSessionProvider()
            throws HttpException, IOException
    {
        // Set up an HTTP client that makes a connection to REST API.
        DefaultHttpClient client = new DefaultHttpClient();
        HttpParams params = client.getParams();
        params.setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 30000);

        // Set the SID.
        System.out.println("Logging in as " + username + " in environment " + environment);
        String baseUrl = environment + authUrl;
       
        // Send a post request to the OAuth URL.
        HttpPost oauthPost = new HttpPost(baseUrl);
       
        // The request body must contain these 5 values.
        List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>();
        parametersBody.add(new BasicNameValuePair("grant_type", "password"));
        parametersBody.add(new BasicNameValuePair("username", username));
        parametersBody.add(new BasicNameValuePair("password", password));
        parametersBody.add(new BasicNameValuePair("client_id", clientId));
        parametersBody.add(new BasicNameValuePair("client_secret", clientSecret));
        oauthPost.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8));

        // Execute the request.
        System.out.println("POST " + baseUrl + "...\n");
      
        HttpResponse response = client.execute(oauthPost);
        int code = response.getStatusLine().getStatusCode();
      
        System.out.println("Code >> " +code);
       
        //populate Response map to fetch ACCESS TOKEN for any future call.
        this.oauthLoginResponse = (Map<String, String>)JSONValue.parse(EntityUtils.toString(response.getEntity()));
       
        System.out.println("OAuth login response");
       
        for (Map.Entry<String, String> entry : oauthLoginResponse.entrySet())
        {
            System.out.println(String.format("  %s = %s", entry.getKey(), entry.getValue()));
        }
       
        //Populate Access Token 
        this.accessToken = oauthLoginResponse.get("access_token");
        System.out.println("");
    }
   
    public void executeQuery(){
         DefaultHttpClient httpClient = new DefaultHttpClient();
       
        List<BasicNameValuePair> qsList = new ArrayList<BasicNameValuePair>();
        qsList.add(new BasicNameValuePair("q", "Select a.ParentId, a.OwnerId, a.Name, a.IsPrivate,  a.Id, a.Description, a.ContentType, a.BodyLength, a.Body " +
                "                                From Attachment a where  a.ParentId = '00390000006DEGb'"));
       
        String queryString = URLEncodedUtils.format(qsList, HTTP.UTF_8);
        HttpGet get = new HttpGet(environment + queryUrl+"?"+queryString);
        get.setHeader("Authorization", "OAuth " + accessToken);
        try{
            HttpResponse queryResponse = httpClient.execute(get);
           
            System.out.println(queryResponse.getStatusLine().getReasonPhrase());
              Map<String, Object> querynfo = (Map<String, Object>)
                        JSONValue.parse(EntityUtils.toString(queryResponse.getEntity()));
             
              System.out.println("Query response");
                for (Map.Entry<String, Object> entry : querynfo.entrySet())
                {
                    System.out.println(String.format("  %s = %s", entry.getKey(), entry.getValue()));
                }
                System.out.println("");
             
        }catch(Exception e){
            e.printStackTrace();
        }
       
    }
 }

Tuesday 4 September 2012

com.salesforce.ide.api.metadata.types.Metadata$JaxbAccessorF_fullName cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.Accessor

While creating New Force.com project or while adding new resource to your already existing projects, if you are getting the below mentioned error message.

com.salesforce.ide.api.metadata.types.Metadata$JaxbAccessorF_fullName cannot be cast to com.sun.xml.internal.bind.v2.runtime.reflect.Accessor

 Please follow the steps below.

This error is because of the Java 1.7 so till the time this release gets fixed, we need to downgrade our JRE to 1.6, this could be a really tedious task and the simplest way that I found and  I did was, Replaced the contents of floder C:\Program Files\Java\jre7 with that of C:\Program Files\Java\jre6 (i already had java 6 hence i could do so, If you do not have you would need to download Jre6).

Doing above mentioned swapping of files saved me from uninstalling (Java7) and reinstalling (Java6) just by copying files of these two folders i can anytime switch back to java7 or java6 as per my requirement.