Nerd @ Work

When Salesforce is life!

[Salesforce / API] Bulk API 2.0 quick & dirty!

I introduce you our week’s trailblazer Claudio Marzorati.

Claudio is a Salesforce Developer @ PwC Italy (Milan) with 2 years of experience. He worked with different retails that allowed him to increase his technical background on several aspects.
From analysis, to development, to the direct relationship with the customer, nothing is left to chance.
Other passions are running and travels!

Enjoy his quick & dirty post about Bulk API 2.0.


Since the introduction in the Winter ’18 (API version 41.0), managing bulk transactions became easier (official documentation here).

The flow to manage a job became quicker with less steps to process the set of records. To better understand the main features, here is an overview of the process for creating and managing a job with Bulk API 1.0.

If you work with few records, you won’t have many problems, but with large amount of data…it’s another story!

Working with API 1.0 means that you will follow many steps to achieve the goal.

At first you have to authenticate yourself against Salesforce to obtain a valid session ID, e.g. using SOAP APIs.

Next important thing you have to consider is that you need to pre-process your data to create N separated batches, because in this version you haven’t an automatic process that analyze and slice the data.

Here are the main manual operations:

  1. Divide the data not to reach the batch size limit
  2. In each batch there can’t be concurrent operations that can lock a record
  3. Need to customize the header with compression or PK Chunking

You can spend a lot of time on step 2, but unlikely in Bulk API 1.0, in Bulk API 2.0 all you have to do is to upload your data and Salesforce worries about all pre-processing.

With Bulk API 2.0 you have to specify few simple steps and your job will be processed.

Below I report a simple schema with all the API 2.0 available. (The dashed component are optional and you can skip them)

I’ll provide you a quick example to start learning to use Bulk API 2.0.

We always start with a:

URL:
    https://{instance}.salesforce.com/services/oauth2/token?grant_type=password&client_id={client_id}
    &client_secret={client_secret}&username={user}&password={password+SecurityToken}

METHOD:   
    POST

To get more insights of how to get all the pieces of the call, refer to this blog post (search for OAuth Password Flow).

The response gives you the access_token (known as session id) that you need in all subsequent Bulk API 2.0 calls and the instance_url to call against:

{
  "access_token":"00D6E0000000xxx!ARIAQL7GNMpk...",
  "instance_url": "https://cs85.salesforce.com",
  "id": "https://test.salesforce.com/id/00D6E0000000XXXXXX/0056E000002LXXXXXXX",
  "token_type": "Bearer",
  "issued_at": "1520445583894",
  "signature": "rHVTsVcvZkrogMNNzxH7GpfKFlkGIHGLySS/jsVhhWc=
}

Let’s create a Job:

URL:   
   https://{instance}.salesforce.com/services/data/41.0/jobs/ingest

METHOD:   
   POST

HEADERS:   
   Content-Type: text/csv
   Authorization:Bearer {session_id}

BODY
{

  "columnDelimiter" : "COMMA",  Optional
  "externalIdFieldName": "",  Required for upsert operations
  "lineEnding": "CRLF",  Optional
  "operation": "upsert",  Required
  "object": "Account",  Required
  "contentType": "csv"     Optional
}

The response gives you back the Salesforce ID of the new batch and other configurations details:

{
   "id": "7500Y000009MxxXQAS",
   ...
}

Now put your data inside the job, paying attention to the schema/format previously defined (separator and line ending):

URL:   
   https://{instance}.salesforce.com/services/data/41.0/jobs/ingest/{jobID}/batches

METHOD:  
   PUT

HEADERS:   
   Content-Type: text/csv
   Authorization:Bearer {session_id}

BODY
   your csv input

The response has status code 201 Created if the data is compliant with the specified job configuration.

When your data is fully uploaded you can finally close your job:

URL:   
   https://{instance}.salesforce.com/services/data/41.0/jobs/ingest/{jobID}

METHOD:  
   PATCH

HEADERS:   
   Content-Type: text/csv
   Authorization:Bearer {session_id}

BODY
   {
      "state" : "UploadComplete"
   }

From now on your job will be processed, depending on your org’s queue.

If you want to check succesfull, failed or unprocessed records you can use this call:

URL:  
    https://{instance}.salesforce.com/services/async/41.0/job/{job_id}/{successfulResults|failedResults|unprocessedRecords}/

METHOD:  
   GET

HEADERS:   
   Authorization:Bearer {session_id}

The response will show the record of the csv in the requested state.

As shown Bulk API 2.0 highly simplifies the creation of bulk jobs…now it’s your turn to experiment these new APIs!

[Salesforce / Apex] Forceea data factory framework: a new approach to an old problem

This week’s guest post is a cool technical post about Apex Tests by Nikos Mitrakis.

Apex Tests are perceived as the hated necessity by most Salesforce developers: they are really important to keep high code quality levels but they are not the most fun part of coding with Salesforce.

I casually discovered Nikos through his GitHub page: I had a read at this Forceea Apex Test Framework, and I asked him to write a post to describe this cool piece of Salesforce tech.

Nikos has started his Salesforce journey in 2014. He started with Salesforce as a hobby (which still remains) and his wife continously threatens him with divorce if he doesn’t stop playing with his various Orgs all the time.
He has a Physics degree, a Microsoft SQL Server BI certification and a few Salesforce certifications. He likes writing code and discoverig how huge the Salesforce ecosystem is. He adores talking about his personal projects, he likes good sci-fi films, he’s been working with a Mac for more than a year, and he started the Salesforce Developer Group in Greece in 2016 (admittedly without much success).
Nikos is working as a Salesforce Developer at the Johnson & Johnson EMEA Development Center in Ireland. If he wasn’t a Salesforce Developer, he’d like to be a Developer in Salesforce.


What is a Data Factory?

Generally speaking, a Data Factory is a set of tools that generate and insert data. It’s very important when you develop a test method in an Apex Test Class, since you usually have to insert records to complete the testing. Using a Data Factory you make your life easier and your work more productive!

A Data Factory is also required when you want to test a report, a trigger/class or another process under Large Data Volumes (e.g. how fast is our report when there are 1 million records?), for User Acceptance testing (UAT), and for training – when you don’t want to create a Full Sandbox or when you want to create data which don’t exist in the production system yet.

What is Forceea and how I can install it?

Forceea (forˈsēa) is a data factory framework for Salesforce and an open source project (https://github.com/nmitrakis/Forceea) in GitHub. It’s a framework, because it gives the programmatic tools for a developer (or administrator, why not?) to easily generate, insert and delete SObject records.

“Yet another data factory?” you may say. Well, not at all!

But first let’s see how you install it.

When you download the files, your installation depends on your preference: classic metadata or DX? For the first option, you may want use the Ant (the build files are included) or the CLI, for example with

sfdx force:mdapi:deploy -u <OrgAlias> -d <folder> -w 5).

For DX, I suggest the CLI, using the command

 sfdx force:source:push -u <OrgAlias>

How can I generate the data I want?

OK, you have installed the framework. Now what?

I think the better way to understand how it works is by example: suppose you want to insert 100 Opportunity records and in your Org the Opportunity object has the additional required custom field MyField__c (which is a lookup to the custom object MyObject__c). Of course the Opportunity has its own required fields (like Stage).

The first step is to create an FObject:

FObject myObj = new FObject(Opportunity, 100);

Next, you declare the field definitions. A field definition uses a descriptive “language” to define what kind of data you want to create for this particular field. This language is called SDDL (Sample Data Definition Language). Don’t be afraid! It’s not a new programming language and it’s very easy to learn.

Let’s start with the first field you want to define, which is the Record Type (API name: RecordTypeId). Do you want your records to have a specific record type (let’s say BigDeal)? Then give this field definition:

myObj.setDefinition('RecordTypeId', 'static value(BigDeal)');

static here is the command and value is the parameter. The static command creates (what else?) static values, that is values which are the same in every record you create.

Do you want a random record type? Then you need the following definition:

obj.setDefinition('RecordTypeId', 'random type(picklist)');

The random command does exactly what you understood, it’s a really powerful command and you can even decide that every time you get the same (but random) data!

But wait! I hear you saying that the Record Type field is not a picklist field, and of course you’re right (it’s a Lookup)! Forceea handles this “special” field as a picklist field, making things easier for you. Say “Thank you 4ca”..

So, we move to our next field, which is the Close Date (API name CloseDate). This has a Date type, and let’s suppose you want it to have random Date values from this year:

myObj.setDefinition('CloseDate', 'random type(date) from(2018-01-01) to(2018-12-31)');

The type parameter is the boss here – it defines what kind of data you get. Give type(Boolean) and you get random True/False values. Give type(phone) and you have random phone numbers, etc

The Amount is a currency, so you decide to take random values from 100,000 to 1,000,000 and round these values to the nearest thousand. Difficult? No, it’s very easy!

myObj.setDefinition('Amount', 'random type(number) from(100000) to(1000000) scale(-3)');

Every opportunity that respect’s itself should have an Account, so you decide that the AccountId field will take an ID from any random Account, but you’ll get accounts without two specific Industry values. You asked for it, you get it:

myObj.setDefinition('AccountId', 'random lookup(Account) field(Industry) except(Banking,Chemicals) source(forceea)

I think the above definition needs some clarifications. The lookup(Account) instructs the framework to fetch records from the Account object and the field(Industry) except(…) to get only records for which the Industry field has any value except “Banking” and “Chemicals”.

But what is source(forceea)? This parameter defines the “source” of the lookup object’s records:

  • If it’s source(salesforce), the framework will query the Salesforce database and get the lookup records.
  • If it’s source(forceea) and the lookup object has been previously created (in the same context/transaction), it gets the records from there (which of course is much faster).
  • If it’s source(forceea) and the lookup object hasn’t been created (or the records have been inserted and deleted), it inserts some records of this lookup object.

Now that you have the opportunity account, don’t forget the opportunity Name (API name Name). Let’ say you want it to have the format <AccountName> – Opportunity for <Random text (with words) from 15 to 30 chars>

So, what is our definition? Well, we don’t have one, but 3 definitions to deliver this:

myObj.setDefinition('Name', 'copy field(AccountId) from(Account.Name)');

This definition gets the Name of the related account.

myObj.setDefinition('Name', 'static value(" – Opportunity for ")');

As you see, this is just a simple text value.

myObj.setDefinition('Name', 'random type(text) minlength(15) maxlength(30)');

And finally, we get our random text with “Latinoid” random words, like “Partem inermis ius impedit eam”

Keep in mind that with the random type(text) definition, the first character of the text is always a capital and the same word is never repeated twice in a row.

Your next field is Lead Source (which is a picklist field with the API name LeadSource), and here you want to have any declared picklist value except from “Partner” and “Other”:

myObj.setDefinition('LeadSource', 'random type(picklist) except(Partner, Other)');

If you wanted these two values only, you could give the definition:

myObj.setDefinition('LeadSource', 'random type(list) value(Partner, Other)');

or if you needed just a specific picklist value:

myObj.setDefinition('LeadSource', 'static value(Partner)');

Now you’ve finished with your field definitions, but remember that we haven’t defined all required fields (like Stage or myField__c). Of course you don’t have to worry about that, because the framework automatically identifies and defines all required fields. There are specific rules for setting the suitable field definition, but (without going to many details) we could briefly say that the field definition for a required field depends on the field data type, the SObject and the field name. So, after defining your fields, Forceea will define all required fields you didn’t define, like Stage or myField__c.

If you need to make some changes in the created records (for example to update a field with some complex calculations), you can get the opportunities with:

List<Opportunity> myRecords = (List<Opportunity>) myObj.getRecords();

Then do your changes, e.g.

for (Opportunity objRecord : myRecords) {
 objRecord.Amount = … // your changes here
}

and just insert the amended records with

myObj.insertRecords(true);

Forceea has many other field definitions, to create random real first and last names (with male and female names), real postal addresses (address, city, postal code, state, country), URLs, email addresses, phone numbers, Boolean values and Datetime values. And don’t forget that it supports BLOBs (e.g. to create email attachments).

It also provides definitions with the serial command (e.g. serial type(number) from(1) step(1.5) scale(2)) to create serial integer, decimal, currency, percentage, date and datetime values.

As you understand, there are many methods to

  • get or delete field definitions
  • create records from a specific serial number (very useful when you insert records with the serial command in different transactions)
  • insert records in groups (a valuable tool for your test methods)
  • define the Verbose mode (how many debug logs you get)
  • get the errors (yes, there is a detailed error system)

The framework handles field dependencies (dependent picklists) and it protects you from doing errors like defining the wrong definition for a specific field data type or defining multiple definitions for a field (e.g. Date) which can have only one.

How can I see the framework’s messages?

Forceea doesn’t have a UI (for the moment). The framework uses Debug Log to post its messages, which show

  • The errors during the process
  • The process milestones completed
  • The data of the first created records

Here is a sample output, just to get an idea of what this looks like (please note that the field definitions in this sample are not the field definitions you used previously).Keep in mind that you have many options to reduce the quantity of logs, for example to get almost nothing on a production system (which by the way is accomplished using a Custom Metadata type).

What’s next?

When you use Forceea in a test method, you really don’t need to create many records, so the 10,000ms CPU limit isn’t an actual problem. Of course you can use the framework to insert records in a sandbox or developer Org when you execute an Apex script in the Anonymous Windows, which of course has the same 10,000ms limit. But when you want to populate a sandbox with 1,000,000 of Accounts, this is another story..

This story is a major part of the next upcoming release (v1.3). The functionality is called Async, it can insert or delete many objects in one transaction, and when you insert objects or delete 1 object it’s surprisingly fast! I have inserted 500,000 of a custom object (without any validation rules, triggers, processes, etc) in 40s! Of course its speed mainly depends on the triggers, etc you have in your actual Org, which may slow down the process significantly (that’s life..)

Anything else?

Yes! I invite everyone to have a look at the detailed User Guide (http://bit.ly/Forceea12_UserGuide) and try the framework.

And I’d like to say a big THANKS to Enrico for hosting this post.

[AppExchange series / Salesforce] Field Dumper – Extract Data Model to Excel

 
This week’s guest post has been written by the guys from P0P, who just made a simple yet really usefull app to extract your org’s metadata.

P0P is a new Scottish software house focused on delivering admin focused Salesforce Apps that make working with Salesforce that a bit easier.  Field Dumper is their first AppExchange offering and was released in November 2017.


Thanks to Enrico for allowing us to introduce to you our ‘Field Dumper‘ application.
Available for free on the AppExchange, it’s a simple and quick tool that allows you to easily extract your Salesforce data model into an Excel workbook.

Background

Simple really – Schema information is available within Salesforce but it is scattered over multiple different pages and it can be time consuming  to navigate, collate and analyse.

That information can be much easier to work with once extracted to Excel.

Sure, for the developer and administrator there are other tools that can access this metadata (workbench, IDE plugins etc) but having a single document can be handy.
It is a great reference for a whole range of different tasks – getting the field api names when writing SOQL, for spell checking help text or for helping with problem analysis for example.

Frequently either non-Salesforce or less technical Salesforce users require visibility of the data model – integrators, business analysts, auditors, reviewers, documentors – and this is a great way of providing a quick offline snap-shot document for them.

Information is simple to access with each object displayed on a separate Excel Sheet within the workbook.   Multiple standard and custom objects can be extracted into one workbook.  Field API names, field labels, help text and field types are just a scroll or search away and Excel is already a tool these users are comfortable using.

Challenges

A simple concept, but we hope that we executed it well – some thought had to be put into the implementation and design.

A single Workbook:

Outputting multiple separate excel files for each object would just complicate and confuse things so coding effort was put into outputting a single multisheet excel workbook, having a separate sheet / tab for each object.  The solution required visualforce renderAs outputting a xml formatted document rather than the more well known contentType="application/vnd.ms-excel#SalesForceExport.xls"

Large Orgs and Salesforce Limits:

Effort needed to be spent to ensure the app worked for the largest of Salesforce orgs.  An Unlimited edition org can have 2000 custom objects, each with 800 custom field.  There are also over 400 standard object in an org.  The volume of text in help and formula fields can vary.  The app is not artificially restricted to the number of objects that can be exported but we do have to work within Salesforce limits.

It is intensive to collect metadata and produce an output document.  Schema describe calls are used for each object and then looped to list out each field.
The fields output include Name, API Name, Type (text, datetime, lookup etc), Formula Text, Help Text, Size and optionally Picklist values.

With potentially high volumes of meta data, it is impossible, even following best practices, to extract everything to one massive spreadsheet without breaching various Salesforce limits (and the spreadsheet would be unwieldy too).
In benchmark testing we were able to use the app to extract upto 150 objects to a single file but you mileage may vary.

A input interface was built featuring a multi-picklist interface to allow the user to select the specific custom or standard objects they require to export.
If limits are hit, a smaller set of objects can be selected.  If a user has a really big schema they could chunk it to produce multiple extracts.

We thought the focus would be on exporting the common standard objects you could add custom fields to and your custom objects, but after some early feedback, we added an option on the UI to allow object selection from all of the standard objects too.

Reception

We were not sure what the uptake or reception of the application when we launched at the end of 2017 would be, but we have been pleasantly surprised.    We have had several really nice 5 star reviews and great feedback and we are glad that we have been able to supply a tool that has been useful to a wide variety of Salesforce end users.  Thanks to all our downloaders and reviewers.

Please check it out for Free Data Dumper on the AppExchange and let us know what you think!  Thanks for you support.

 

 

 

[Salesforce / Ohana Community Italia] Part 1: Salesforce Community on Slack workspace

For those of you who has no idea of what the Ohana Community Italia is, please refer to this post I wrote in the late December 2017.

Long story short, we are building our own nation wide Salesforce community…

This is a handy GitHub repository with all the code needed to follow this article.

I want to document the build of this community, in terms of all the actions we’ll take to create all the little pieces.

Hopefully, we’ll create a public repository with all the code and stuff, so anyone could create what we are doing!

The Community

The idea is to build a Salesforce Community inside a dedicated ORG in order to easy communication and sharing of ideas between italian trailblazers.

Thanks to Nino Guarnacci, our amazing sponsor from Salesforce Italy, we have a dedicated Salesforce DE ORG with all the necessary licenses.

This requires to:

  • choose the best Salesforce Community for our needs
  • configure all the features of the community
  • create a registration page
  • cover of the base topics for the start up

This is not a simple task, I don’t mean technically, but in terms of time.

That’s why we decided at first to freeze the building of the community in a Salesforce ORG (that is actually been built on the background) and speed up the process of putting together people using a more common and well known tool, configuring a Slack workspace.

At the time of writing the Ohana Community Italia is live at italia.ohana.community and its topics are publicly available, although it’s been constantly improved day by day (let’s say we are on Beta).

ohana-community-italy.slack.com

Slack is a great tool for collaboration and it seemed a cool way to start.

That’s why we created the Ohana Community Italy Slack workspace.

The configuration of the workspace is quite simple, we have administrators and users, with different powers (it depends on how much power you want to give to your users):

But how do you get on the Slack community?

We decided to leave the invitation private at first.

Invitation happens in 2 ways:

  • Direct invitation by an admin
  • Form compilation of an invitation request

Web-To-Case invitation form

The idea is to create a new Case when a new trailblazer wants to join, using the web-to-lead feature (a pretty standard feature), that automatically generates a Case from a web form, exposed pubblicly on a Force.com site.

We took the auto-generated HTML form from the Salesforce setup and customized it based on our needs:

There is no need to enter in the details of this configuration, as there is plenty of stuff out there (Salesforce docs enter in enough details to get started).

Refer to the Subscribe.page on the repository.

Send invitation to Slack

And now?

Someone must send an email to invite the person who succesfully created a new Case on the ORG.

For the first times of the life of the Slack community we are handling this by hand, but we should soon automate this in a Case trigger (TO DO).

To send invitation links to specific email addresses we need:

      A Slack app linked to your slack workspace
      A page in the Case layout with a button to make the call
      The right REST commands to trigger the invitation email

Create a Slack App

Jump to https://api.slack.com/apps:

Create a new app and link it to a workspace (in this example I’m using my own personal Slack instance):

Espand Add features and functionality section and hit Permissions. Scroll down and add the Admin scope:

Now that you have at least one scope, you can install the app on your workspace:

Last thing to do, is generate a quick and dirty legacy token with full super powers on https://api.slack.com/custom-integrations/legacy-tokens:

Copy this token for next configuration.

A button to invite them all

A new VF page will be put inside the Case using the layout editor.
Refer to the OhanaCommunityInvitation.page on the repository.

This page simply takes a case (of a certain Record Type, Community_Management), and by pressing the Invite to Slack button makes a call to Slack to actually send the invitation email.

Take the SlackUtils class and update the oauthToken property placing the OAuth Slack legacy token generated in the previous section:

public class SlackUtils {
    /*
     * OAuth token for admin tasks took from https://api.slack.com/custom-integrations/legacy-tokens
     * TODO: replace with Custom Setting or Oauth Call
     */
    public static String oauthToken{
        get{
            return 'xoxp-XXXXXXX-XXXXXXXXXXXXX-XXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXX';
        }
    }

This class contains the main actions will be using for communicate with Slack.

You also need to enable the Slack API endpoint, you can easily do it using a Named Credential:

The invitation email is not a documented REST method, but I found a solution in Stack Overflow thread.

If the invitation is sent sucessfully, the case is automatically closed.
If the case is closed you still have a chance to re-send the email, using the resend=true parameter to the call.

Slack bot says: “Hey there’s a Case awaiting for an invitation!”

Invitation are not currently sent automatically, so we need a way to notify the administrators of the community so they can push the button (before you say a word…I know this is not the most comfortable flow).

We’ve built a scheduled Apex process that sends a notification every morning in a specific Slack channel: although this is not so comfortable, I admit I wanted to do this to write something with a bot from Salesforce to Slack!

The code is in the NotifyNewUsersOnSlackSch class and you should update the ohanaServiceChannel property to change the channel name.
In the SlackUtils class you can also change the Bot name and icon (the URL must be available pubblicly).

What’s next

Next steps are enable automatic Slack invitations on Case creation (the job is needed in case of errors or connection problems) and finally publish the Salesforce Community…but it is another story!

Remember to star the GitHub repository with all the code needed to follow this article.

Join the Ohana Community Italia, but you should at least say Hello in Italian!

New year, new style (⌐■_■)

Welcome to the new Nerd at Work!


It took me 5 years but finally this blog has been completely rebranded and moved to WordPress.

I thank Davide D’Annibale for helping me customizing this theme and drawing the funny graphics (with my BIG face).

Yes, that’s so…my face is supposed to be the main logo of the blog

My Big Face

Funny, uh?

Uncomfortable? Quite, I know…

I can’t wait to read your opinions about this and any suggestion to make this blog awesomer!

I also want to thank the great trailblazers who help me by writing amazing and original guest posts: hope this page will contains tens of people!

Do you want to be a guest blogger for Nerd at Work?

Contact me!

Last, the sponsors page will contain the sponsors of this blog, who will help me to keep this blog up and running!

Do you want to be a sponsor of Nerd at Work?

Contact me to see your awesome company/app on the main page!

Remember to subscribe from the sidebar form!

New posts on the next weeks! Keep enjoying!

[Salesforce / AppExchange Series] Streamline Project Management with Cloud Coach Milestones

This week’s AppExchange hero is Brandi Johson, marketing consultant at Cloud Coach, who is going to present us Cloud Coach Milestones, the ideal tool for simple task and project management on the Salesforce platform.

Brandi Johnson is a marketing consultant and certified Salesforce admin. She focuses on helping clients create effective marketing strategies and leverage the right marketing technology to meet their unique business needs.

Cloud Coach specializes in enterprise-class project, PSA & PPM software built for businesses that want to make strategic investments in their success. With our unique four-tier approach to project management solutions, as your business grows, Cloud Coach can grow with you. Learn more at CloudCoach.com.

Wouldn’t it be nice if everything you had to do at work was easy?
Then they may not have to call it work!
As businesses grow, the challenges they face get more complex – especially when it comes to working with your team to accomplish your goals.

One critical example of this is new customer onboarding.
Whether you’re in SaaS, professional services, or manufacturing, having a streamlined customer onboarding program is vital to your success.
A strong customer onboarding program helps you increase customer satisfaction and reduce churn. Plus, it reduces the stress on your team as they’re moving through the process.

Let’s take a look at Serenity Software – a B2B SaaS company. They’ve nailed their sales process leveraging Salesforce. But once a new customer signs on, the wheels start to come off the process. Emails fly back and forth between the account executive and customer support team trying to track down the details needed and sharing status updates.

The customer success manager keeps shared spreadsheets for each of the clients that they’re working with.

Unfortunately, the team isn’t great about keeping them up-to-date with status updates – leading, of course – to more emails.
They also tried using Trello to keep track of their projects, but they had the same problems: nobody wanted to log into yet another system to see what they needed to work on or post status updates.

Finally, the customer success manager discovered Cloud Coach Milestones in the Salesforce AppExchange. In minutes, she was able to start organizing her customer onboarding projects and increasing collaboration with her team.

She started by creating a template from the spreadsheet she had been using. It was easy to add additional details to each task using subtasks, and assign the work out to her team. Plus, Cloud Coach Milestones put everything into an easy-to-use Gantt chart so she can see at a glance how long everything each tasks takes, and when things are running behind.

Serenity Software took streamlining their projects a step further, and leveraged Salesforce Process Builder to automate their project creation.

Now, whenever an opportunity is marked as Closed-Won, a new project is automatically created leveraging the template the Customer Success Manager created.

Those new projects are automatically connected to the account, so everyone has a 360° view of the customer and the project while its in-progress.

With Cloud Coach Milestones, Serenity Software streamlined their project management processes.

They have happier clients, faster onboarding, and better team communication.

Since all of their projects are in Salesforce where they’re already managing the rest of their business, they can see all of their important business KPIs on centralized dashboards.

No data imports, no APIs.

Could Cloud Coach Milestones work for your business?

If you run projects, then yes, it could.

Plus, you can get started in less than 10 minutes.

Step 1: Install Cloud Coach Milestones from the Salesforce AppExchange. Of course, we recommend installing into your Sandbox, not your production org.

Step 2: Check out the getting started videos. When you visit the Cloud Coach Milestones App, you’ll see a tab for “Getting Started.” These videos give you a great overview of Cloud Coach Milestones in action, and help you answer a ton of questions before they get asked.

Step 3: Create a project. Before you start sharing Cloud Coach Milestones with your team or customizing, I recommend that you build your own simple project. This helps you see how Cloud Coach Milestones works out of the box so you can make better choices about integration and customization.

Step 4: Customize your projects. Since Cloud Coach Milestones is built on the Salesforce platform, you can do a lot of customization on your projects to meet your business needs. For example, you may want a field to identify what type of project your team is doing for a client. Choices would be onboarding, maintenance, or special request. By adding a field on the project object, you can add this customization in minutes.

Step 5: Integrate with your existing objects and processes. Out of the box, Cloud Coach Milestones has lookup relationships to Opportunities, Accounts, Cases, and Campaigns. To associate projects with another object (custom or standard), create a new custom lookup field that points to the Cloud Coach Milestones object. Then, add the Milestones related list the page layout, and any projects you launch from that list will be visible on the project.

With Process Builder, you can automatically create projects from your business best-practice templates. The Cloud Coach Milestones Knowledge Base has details on how to autocreate projects with Cloud Coach Milestones and lots more.

Step 6: Assign permission sets to the users that need access to Cloud Coach Milestones. There is no limit to the number of users within your org who can use Milestones. Just like everything else about Cloud Coach Milestones, security was designed with simplicity in mind. There are only two permission sets you need to work with:

  • CCMI | Minimum User Permissions – grants a user access to all standard Milestones functionality and views. A user with this permission set assigned can create their own projects, view projects that aren’t their own, and manage their tasks and projects.
  • CCMI | Admin Permissions – permits exactly the same functionality but also includes the ability to load sample data. This is useful for Partners or Users who need to demo or test the product but do not want to spend time creating sample projects.

You’re never alone when you’re working with Cloud Coach Milestones. In addition to the extensive knowledge base that’s growing every week, we offer a free 30-minute onboarding consultation for new installs, and weekly open forum webinars to answer your questions.

Ready to get started with Cloud Coach Milestones? Just head over to the Salesforce AppExchange and click “Get It Now” to get started!

And it’s available on Salesforce Lightning and Classic!

[Salesforce / Amazon Echo] AlexForce 2.0: integrate Salesforce and Alexa (the ultimate Apex library)

More than 2 years ago I wrote about a library I made up for integrating Salesforce and Amazon Echo, using its REST APIs and Apex: this is the original post.

I supported the library for a while hoping that the Ohana could took ownership of it but unfortunately this didn’t happened.

With great surprise I met the next guest blogger, Harm Korten, who was developing his own version of the AlexaForce library.

I’m more than happy to give him place to his amazing library and hope that the time is now ripe to bring this library to the big audience!

Harm Korten is a Force.com fan from The Netherlands. His professional career in IT started in 2001 as a developer, but his interest in computers started well before that. He got introduced to Salesforce in 2005, working at one of the
first Dutch Salesforce.com partners, Vivens. He has been a Salesforce fan and advocate ever since.
Over the years, he has worked on countless Salesforce projects, at dozens of Salesforce end-user customers. Currently he is active at Appsolutely, a Dutch Salesforce partner, founded in 2017.
Find him on LinkedIn or follow his Salesforce (and other) adventures on his blog at harmkorten.nl.

Introduction

In the first week of 2018, I ran into some of Enrico Murru’s work. Google offered his AlexaForce Git Repo (https://github.com/enreeco/alexa-force) as a suggestion to one of my many questions about integrating Amazon Alexa (https://developer.amazon.com/alexa) with Salesforce. It turned out Enrico had been working on this same thing, using the same technology stack, as I was at this moment.

An Alexa Skill SDK in APEX, only 2 years earlier!

Nerd reference
Up until this moment, besides Enrico’s proof of concept version of such an SDK, the only available technology stacks that would allow integration between Salesforce and Alexa were the Node.js and Java SDK’s. These could be hosted on Heroku and use Salesforce API’s to integrate.

Like Enrico, I wanted to build an on-platform (Force.com) Alexa Skill SDK. This common interest put us in contact. One of the results is this guest blog, not surprisingly, about AlexaForce. Not Enrico’s AlexaForce, but Harm’s AlexaForce. We apparently both came up with this very special name for the SDK (surprise, surprise) 😉

AlexaForce

The basic idea about this Force.com SDK for Alexa, is to remove the necessity to work with Salesforce data through the Salesforce API. The Java or Node.js approach would have Amazon send requests to Heroku and from therefore require API communication with Salesforce.

With the AlexaForce SDK, Amazon will send the Alexa requests straight to Salesforce, allowing a developer to have full access to the Salesforce data, using SOQL, SOSL and APEX. The resulting architecture is depicted on the image below.

For more information about AlexaForce and how to use it, please visit https://github.com/HKOLWD/AlexaForce. You will find code samples and a detailed instruction there. For this article, I will elaborate on a specific Alexa Skill design approach, which is still in beta at Amazon: Dialogs.

Dialogs

Generally spoken, the most important part of an Alexa Skill, is its Interaction Model. The Interaction Model is defined in the Amazon Developer Portal when creating a new skill. The model will determine how comprehensive your skill will be as well as its user-friendliness, among other things.

An Alexa Skill model generally consists of Intents and Slots. The Intent holds what the user is trying to achieve, the Slots contain details about the specifics of the user’s intention. For example, the Intent could be ordering a pizza, the Slots could be the name and size of the pizza, the delivery location and desired delivery time.

One could build a model that just defines Intents, Slots, Slot Types and some sample utterances. This type of model would put a lot of the handling of the conversation between Alexa and the user in your (APEX) code. Prompting for information, checking and validating user input etc. would all be up to your code.

Here’s where Dialogs come in handy. With a Dialog (which is still in beta at the time of this writing) you put some of the conversation handling inside the Interaction Model. In other words, besides defining Intents, Slots and Utterances, you also define Alexa’s responses to the user. For example, the phrase Alexa would use to ask for a specific piece of information or how to confirm information given by the user.

From an AlexaForce perspective, you could simply tell Alexa to handle the next response using this Dialog definition inside the Interaction Model. This is done by having AlexaForce send a Dialog.Delegate directive to Alexa.

Example

Imagine an Alexa Skill that takes support requests from the user and creates a Case in Salesforce based on the user’s request, a ServiceRequest (Intent) in this example.

Two important data points (Slots) need to be provided by the user:

  1. The topic of the request. Represented by ServiceTopic in this example.
  2. The description of the issue. Represented by IssueDescription in this example

A Dialog allows you to have Alexa collect the data points and have them confirmed autonomously. The APEX keeps delegating conversation handling to Alexa until all required Slots have been filled.

A Dialog has 3 states, STARTED, IN_PROGRESS and COMPLETED. When COMPLETED, you can be sure that Alexa has fully fulfilled the Intent as defined in your model, including all its required Slots. Below is a code sample that would implement this, returning true on Dialog completion.

if(req.dialogState == 'STARTED') {
    alexaforce.Model.AlexaDirective dir = new alexaforce.Model.AlexaDirective();
    dir.type = 'Dialog.Delegate';
    dirManager.setDirective(dir);
    return false;
} else if(req.dialogState != 'COMPLETED') {
    alexaforce.Model.AlexaDirective dir = new alexaforce.Model.AlexaDirective();
    dir.type = 'Dialog.Delegate';
    dirManager.setDirective(dir);
    return false;
            
} else {
    return true;
}

The APEX takes over again when Alexa sends the dialog state ‘COMPLETED’. Once this happens, both the ServiceTopic and IssueDescription will be available (and confirmed by Alexa) to your APEX to create the Case.

This example would be even more powerful if you set up account linking. This would allow users to first log in to Salesforce (e.g. a Community) and therefore providing the developer with information about the Salesforce User while creating the Case.

All of the code for this example, including the model and full APEX can be found here: https://github.com/HKOLWD/AlexaForce/tree/master/samples/Dialog.Delegate.

[Salesforce / AppExchange Series] RingsTrue: Smarter phone numbers in Salesforce

This week’s new post is dedicated to a new AppExchange app, meant to help us in one of the most difficult and annoying tasks on every CRM: phone number validation.

Thanks to our week’s guest blogger Iain Clements.

Iain runs Cloud Ursa Ltd, a registered Salesforce partner based in the UK. In addition to helping customers configure Salesforce, we also make RingsTrue.

XConnect is a world renowned telecommunications routing specialist that provides the world’s leading global telephone number data and phone intelligence services. XConnect combines trusted information from hundreds of disparate global data sets and enables our customers to build the best communication services and applications using our unified data via simple, secure, scalable and real-time interfaces.

Managing data quality in Salesforce can be time-consuming.

Making sure that your customer records have correct telephone numbers is an endless task. However, authentic numbers lead to less failed call backs and lower contact centre costs. If that phone number belongs to a new potential customer, getting the right data also improves your business.

Can’t I just fix them with regular expressions?

Not easily! Unlike other global numbering schemes (eg IP addressing), Telephone Numbers have evolved organically, (and not necessarily logically). Using Regular Expressions (REGEX) means creating a set of rules, to take a string of information and ‘reformat’ that information into something else.

But what are these rules for Telephone Numbers?

  • Is the number in national or international format?
  • Does it include the national dialling code (eg 0)?
  • Does it include a country code ? How many digits is that country code?
  • Is the country code valid?
  • Does the remaining number have the correct number of digits for that country code ?
  • Is the National number prefix valid for that country?

So what’s the answer?

Well, we’re biased of course but we think our app RingsTrue is a huge time saver for this work.

RingsTrue powered by Xconnect brings a wide range of number checking functionality to your Salesforce environment and tells you if your telephone numbers are authentic or not. It’ll do the heavy lifting of formatting, validating, and actively testing the telephone number for every contact in your database.

Using RingsTrue, powered by XConnect, you will be able to:

  • Identify which telephone numbers in your CRM are Authentic and whether an authentic telephone number is a mobile number, fixed line number, or some other telephone number type.
  • Check which of the authentic telephone numbers is known to be In-Service with telecommunications provider.
  • Discover additional information about the capabilities and services supported by the end-uses devices, as well additional data made available by the mobile service provider.

How do I install it?

  1. Go to the Appexchange
  2. Click on Get It Now
  3. Choose to install in your test environment or your live environment
  4. When installed, go to the RingsTrue homepage and either click ‘Run’ or choose a schedule of phone checking to suit your company
  5. When RingsTrue has checked all of your records you will see clearly what the current status of that number is

Where can I try it out?

Try it for free for 5 days with no obligation, click here to start now!

[Javascript / Chrome / EasyPeasy] Blocking form autocomplete after Chrome Canary (version 65)

Recent Google Chrome update (65) brought something that developers are not liking too much: the autocomplete=”off” attribute on forms and inputs is no more considered.

Read in depth this Stack Overflow thread.

The solution (not so clear) is to give a random autocomplete value to the autocomplete attribute of each input of the form:

$('form input').each( function(){
   $(this).attr('autocomplete','no-autocomplete-'+(Math.random()*Math.random()));
});

Also apparently Chrome uses the name attribute (at least for email and password values), in my use case the name attribute was not necessary in the form so this script worked like a charm.

[Salesforce / Apex Test] Code coverage and logical tests in Apex Test Classes

This article is actually a repost from a buddy I came across online.

I read his articles on LinkedIn by chance and I really appreciated the easy way he writes and how he delivers important Salesforce concepts.

I choose an article about Apex Test Coverage… but before going on the article…
…please take a moment to hail our beloved lord the deployment fish!

The guest blogger

Vladimir Egikyan is a SFDC developer since 2010. Most of his career he worked for technical services providing company in Israel. During that time he helped to implement business of various companies, among which are ZIM Integrated Shipping Services, Bank Leumi.
In the latest three years he works as in-house developer and sharpen his architect skills. Though he is officially certified only as Developer… yet 😉

Writing good Apex Tests is a key to successful developing. There is a huge list of best practices and recommendations, that you can find in Salesforce documentation. Following them all, is what every developer should aim to do. Over years of developing on Salesforce, I learnt that code coverage is not what really matters…

How can that be?

Well, your coverage will raise by itself if you mind checking what your class or trigger has to do and what results you expect. Having said that, the most important thing that your test class has to do is to use System.assert methods to prove that code behaves properly. This will keep you on the safe side from any unintentional mistakes, changes in business requirements and eventually will save time and money on development process.

Okay, let’s take a look at the example:

TVRemoteControl class describes remote controls that can increase and decrease volume in scale 0-50 and have simple menu text.

Corresponding test class would contain call for each of class’ function:

TVRemoteControlTest covers the TVRemoteControl by 86% which is more than allowed minimum of 75% and these classes will deploy to production.

First and obvious defect of the test class is that it does not test if code will properly handle changing the volume beyond limits. The most important is we have to test that we get expected results in any possible use case. Our applications are almost never finished: business requirements constantly change. Besides that, we are all human and we always can make mistakes and test class is a tool that can help us to correct possible mistakes in time and that happens quite a lot.

Let’s see the better version of the test class.

This version of test class contains checking for going out of boundaries and also in each test method implements different use case and uses System.assert methods to make sure that class is performing the expected logic.

The given example is simple, but do not underestimate the importance of using assertion methods. Business logic in real life is way more complex then tv remote control, keep using these methods and you will be surprised how much time it saves for future technical support.

Page 1 of 14

enree.co & Enrico Murru