Nerd @ Work

When Salesforce is life!

[-3 to #TCO14] – An evening talk with Samatha Ready, salesforce.com Evangelist

6 Days to Top Coder Open and 6 blog post for each day!

The following is a blog post I wrote for the Top Code Open 2014 blog. Enjoy!

The main reason I started competing in topcoder is because of salesforce.com contests.

In 2009, (casually), I became a salesforce.com developer, and from that time, I started working with this fast growing platform.

In the last 6 years I had the honor to see the platform getting bigger and bigger with new features, powerful tools, a stable cloud platform, and an expanding set of possibilities (Heroku is my favorite one) that really makes my job worth getting done.

But I think that the most valuable “feature” of this technology is the immense amount of docs, blog posts, forums, and repositories, all for free and ready to be consumed in your projects.

The salesforce.com community is really amazing and you always can find an expert ready to help you. If to this awesomeness you add a BIG event, DreamForce, and hundreds of evangelists that “spread the word”, you get why salesforce.com is one of the fastest growing companies in the world.

The 2014 Topcoder Open will see a great line up of speakers with its first Developer Conference Unplugged.

For all these reasons, I decided to ask Samantha Ready, Senior Developer Evangelist at Salesforce.com, and speaker for the event a few questions.

Hi Samantha, it is a pleasure to chat with you.

How does it feel to be a central part of this awesome community?

I am overtaken with gratitude and excitement all the time to be able to be at the hub for technology surrounded by some of the smartest minds in the business. Absolutely love the fact that I get to mingle with developers from all over the industry to hear about the cool things they are cooking up for their companies, and love when I can help with those innovations.

What does really mean to be an evangelist? I mean, the main reason is that your job is to spread the “Salesforce word”, but is there some sort of feeling of responsibility in front of the dev community?

I think being a developer evangelist is partially spreading the “word” aka the whys and how to’s of Salesforce. In addition to that, its also a matter of inciting imagination and possibility with devs helping them envision what they can build for their company and empowering them to use the building blocks they need to do those things. Documentation doesn’t always give that kind of context, and so I try to do it through stickier ways like a Udacity course, developer guides, Project Trailhead for learning paths, webinars, and talks to name a few.

You’ve been a girl that used to talk with robots (you have a background in computer engineering with a concentration in robotics), how and when did you chose to follow the web development and the Salesforce Evangelist path?

So don’t get me wrong, I loved robotics. It was a challenging beast and it was extremely satisfying seeing your robot compete or shipping a product. Truthfully though, most of the programming I did for my last job as an software engineer was low-level embedded C and Perl scripting which plays tricks on your psyche after a while. I lived out of the command line and didn’t really talk to any of the engineers I worked with because we were so heads down. I found Salesforce through a friend and while I had no idea what Salesforce was at the time, the company seemed extremely innovative and I thought it sounded like a good opportunity for growth. I jumped over to an internal development role and felt the atmosphere and company was a fit from day 1. Rapid development, tons of new languages and frameworks, competitive, and collaborative…my favorite things! I immediately loved the “instant gratification” aspect of web development rather than the 10-week push for an inch of progress at my former company, and haven’t really looked back. Both disciplines are great for sure, and they each have their own set of challenges, but I think I prefer the fast iteration of web development and the infinite learning possibilities for new tech.

Has the robotic passion ended or do you plan to reach that path again?

The robotics passion has definitely not ended, and I’m so happy that the internet of things trend is making its way into the enterprise!

How has this passion helped you in your evangelist career?

I think that my passion for robots has helped me geek out more times than I can count. I love to tinker, and I love to talk to people about their pet projects as well. In addition to that, I think it made me more confident in trying other things because it laid a foundation for my own self confidence which was “even if this seems impossible and you have no idea…google it, and figure it out.”

It is not usual to see a woman that loves to code, but recently (and luckily) the number is increasing. In my experience I always felt it was a matter of lack in interest. How do you, as an expert and successful woman, see this?

I think the best analogy I heard was from a colleague of mine (Mary Scotton) who said,”Just like some time ago when being a doctor was seen as a job only men do, that’s how some people see programming right now. But now, being a doctor is seen as a job for both men and women, and that’s where it’s going with programming.” I see the increasing number as a good sign and a definite trend, but I think for this to grow there still needs to be more proactive efforts. I think we need more awareness overall in schools, families, friends about motivating young men and women at a young age to take an interest in STEM education. There are already efforts in this direction: GoldieBlox, Girls Who Code, Hour of Code, Made with Code to name a few, but I think it needs to be even more prominent in both school programs and extracurricular activities to catalyze exponential change. I think if high schoolers have more of an opportunity to learn how to code or get a taste of computer engineering or computer science, we’ll see a big shift in the gender balance.

Were you attracted to the “nerd” world of coders or simply had a secret passion for computers and robotics or the random nature of life is the only explanation?

I fell in love with coding for the exact reason above–my school had a C++ class, and I had no idea what it was but I took it as an elective and had a blast. I took more programming courses after that, and eventually started tinkering on PCB layouts. I’m a polyglot nerd though, because besides coding I’m obsessed with physics, space, and marine science. I’ll nerd out over space or the ocean any day of the week.

You’ve actively worked on Salesforce1 recently. This is an important step for Salesforce and, as far as I worked on it, it actually is a great and important piece for the whole Force.com platform. Which is the feature you love most of Salesforce1?

So up until DreamForce my answer would have been the ability to implement custom Visualforce within Salesforce1 to be able to build dynamic mobile pages instantly deployed. I’ve made a few different iterations of a “Find Nearby” page that will locate restuarants, accounts, people, etc near where you are completely in JavaScript, Visualforce, and Apex in a little under an hour and displayed in an interactive google map.

Can you anticipate any future (and top secret) features?

Now that DreamForce is over, I can tell you about my not-so-secret new feature Lightning Components. Salesforce1 is a Lightning App that is built using Lightning Components, and as such the places where Salesforce1 uses Lightning Components will become extension points for developers. The Salesforce1 UI will not only be customizable to the point where you can not only build completely custom features from scratch but you will also be able to develop on top of the standard UI and still utilize all of the built in functionality the platform provides.

How do you see Salesforce1 in the next future?

Salesforce1 right now is a mobile app and a platform. This mobile app will eventually become the full experience for Salesforce–a new UI and unified desktop across all devices. This means build once and deploy everywhere, which will be huge.

Have you been working on side projects besides your evangelist job that you want to share with us?

I had started tinkering on an integration between the FitBit and Salesforce to store information over time to get more in depth and filterable analytics. I was hoping to build that out even further utilizing your Salesforce network on Chatter and turning it into a competition with colleagues.

What do you plan/want to say at the TCO14 developer talk? Any particular subject?

This is still TBD… Top Secret 🙂

Your bio in the TCO14 site states that you love “scuba diving, scaling mountains searching for the world’s best hot sauce while listening to good music”: did you find the world’s best sauce?

If you like pasta I can give you wise advice 🙂 World’s best is the search for the holy grail…and as such I think is equally futile. The “best” hot sauce is subjective depending on what you’re eating! So here are a couple: Fall foods (butternut squash, roasted veggies, chili) – Yucatan Sunset Picante Sauce, Chicken/Grilled foods – Nando’s HOT Peri Peri, Eggs or Beef – Yucatero XXXtra Hot Habanero, Veggies – Marie Sharp’s. Old faithfuls are Cholula and Sriracha 🙂

[-4 to #TCO14] – An evening chat with Gayle Laakmann McDowell

6 Days to Top Coder Open and 6 blog post for each day!

The following is a blog post I wrote for the Top Code Open 2014 blog. Enjoy!

When I first was invited to TCO13 I was both afraid and excited about competing with worldwide champions.
Moreover with such a BIG sponsor like Google it seemed to me incredible to have a chance to be part of it as a main character in this awesome event.

I have to admit I also became shy when I spent 2 words with the Google guys at the event: this is not because I thought of them as the most important developers in the world (and I suppose they actually were not developers at all) but because they had a big “G” on their shirts (but also cool gadgets…I barely managed to travel with my luggage back to Italy).
Thinking back to those 2 shy words I said to them, I smile, but I understand that this was caused by the fact I think of Google (and Apple, Facebook, Microsoft, Amazon…) as an unreachable nerd heaven where only the choosen ones can be allowed to enter.

Gayle Laakmann McDowell, speaker at TCO14, embodies what I thought was not really possible in life, that is to say working with the most known and desired tech companies.

And besides this she tries constantly to help people to focus their skills to reach what she has managed to do.

In her book Cracking the Tech Career Gayle presents the good and evil of big (new & old) tech companies, stating which is their recruiting model and how you can thus focus on their model to possibly get a chance to be a choosen one, or how you can understand if you simply could be that chosen one.

The original interview has a slightly different set of questions: I wanted to ask smart questions but I overestimated my English skills; thus Gayle helped me to re-organize them (thank you very much!).


Hi Gayle and thanks for this chance to chat with you.
Do you feel like you chose your career, or that it chose you?

I think luck and choice/skill play together. Luck opens doors a crack. Choice/skill is what enables you to walk through it and actually leverage the luck.

Many of the major turning points in my life were preceded by luck. For example, a friend from college introducing me to someone at Microsoft. However, it’s only because I had done a lot of coding projects that I was able to land a job there, despite being only a freshman. We all have a lot of doors opening, but sometimes it’s so small that we don’t even notice it. We have to be observant, confident, and skilled to walk through it though and actually capture the opportunity.

You’ve spent a lot of time both writing books and writing software. Do you feel that those are related skills or independent skills?
They overlap. Writing books isn’t a skill by itself. It’s a thing you do because you possess multiple skills. Same thing with writing software. Some of those sub skills overlap. Writing books and writing software both require focus, logical thinking, hard work, and initiative. And in my case, both require coding skills.

Do you think the perception of programming as a man’s field discourages women from pursuing the field?
It’s not the only thing, but it’s certainly an important factor. Both men and women are influenced by society. Just as people often follow in their parents’ footsteps, they often follow in the footsteps of other people around them.

When a man doesn’t see many men in nursing, it doesn’t really occur to him as a good fit for him. This doesn’t mean it’s not though. Likewise, when a woman doesn’t see many women in engineering, this doesn’t really jump out as a great career option. There are so many options and this one doesn’t seem especially ideal.

Role models and society influence people.

Unfortunately, the causality also operates in the opposite direction: when few women enter engineering, it continues to be perceived as man’s field. This is part of why efforts to encourage more women to enter engineering are important. Society subtly influences women not to. These efforts exist to counteract those.

Is there something in your career that you regret (bad choices, lost opportunities)? On the other side which have been your “luckiest” circumstances?
Regret is difficult for me. I love what I’m doing and where I am in life. What if changing some part of my background would set off a chain reaction and radically change where my life is?
However, if I could give myself career advice, unaware of the future would hold, I’d say this: Go check out a startup while you’re in college. You’ve had several summers at big companies. Go get some diversity in your experience.

For luckiest, I think becoming a teaching assistant (TA) in college. I was asked to be a TA for one of the most challenging computer science classes. My grades were okay in the class, but not great. One of the current TAs recommended me because she observed me teaching some concepts to a friend. She was confident that I could learn the material well enough and would be a great teacher. (I could and I was.)
This gave me a ton of experience with both explaining concepts and with public speaking. Developing those skills have been incredibly valuable for what I’m doing now.

In the hiring process, can love and passion overcome real and quantifiable knowledge?
They won’t necessarily overcome large knowledge gaps, but they will eliminate them over time. Developers who are passionate about programmer aggressively learn what they need to know. They take on the challenging projects and, pretty soon, the knowledge gap goes away.

With new technologies coming out all the time, how do you keep up to date on them when at a big company who might not adopt them?
The best thing to do is to make programming your hobby too. You should spend at least a bit of time outside of work coding. Use that to stay up to date with technologies.

You don’t need to know all of the latest technologies – that’s too much. You should know at least some of the modern tools though.

Do you have some final advice for all TCO14 participants?
Recognize the opportunities in front of you and seize them. Know when that door has opened just a little bit for you. Don’t let that little voice that says “I’m not good enough for this” get in the way. Almost everyone has that little voice. If you do too, remember that having that voice doesn’t mean the voice is right.

[-5 to #TCO14] – TCO14 Rockstars: pt 2

6 Days to Top Coder Open and 6 blog post for each day!
The following is a blog post I wrote for the Top Code Open 2014 blog. Enjoy!

You know what? You are the guy that almost destroied my TopCoder dreams! Yes that’s true, I’m talking honestly! After the Cloudspokes experience (in which I felt really comfortable, really high % of wins, considered by someone a rockstar) and after the beautiful TCO13 experience, I finally started competing into TopCoder…and what happens? You were the one that made me feel a noob! Why? Because the first challenge I did which I thought I’d won, was won by you with an impressive 100% score.

They say “face your demons”, that’s why after seeing you winning the TCO14 Development final and after beeing honored to be asked to write some posts for TCO14, I thought that writing of you would have been a good subject (you are not my demon, I’m just kidding!).

Dear audience, I’m actually talking to TCO14 Development champion Sky_.

So let’s start with some noob questions: what do u do in your life and how did u start coding? How did u get to the TopCoder’s community? How TopCoder changed your professional life and your productivity?

I started coding in High School. My first programming language was Pascal and I was solving only algorithmic problems. I believe all programmers start their career in the same way. I heard about TopCoder in High School, because tomek had won TopCoder Open, but I hadn’t heard about Development Track until I went to the University. I remember when 5-6 years ago I was reading about Development Component track (it was very popular those days, but now it’s dead at the moment) and I was trying to compete in few contests. Unfortunately my codings skills were very low and I was unable to do anything so. I gave up TopCoder for 4 years. During these 4 years I’ve been studying and working as a .NET developer and I came back to TopCoder 2 years ago. I was looking for a better job, so I’ve decided to quit my current one and do full time TopCoder contests.

In a scale from “I’m not a nerd, shut up and give me your lunch’s money!” to “Beam me up, Scotty” how much do you feel nerd? If your are dangerously near the Star Trek limit, how does this helped you in your coding carreer? In your professional experiece, did you find “geekyness” a common “language” that goes across countries and cultures?

I am not a nerd and I don’t like Star Trek 🙂 I’ve never met geeks or nerds in my job. “Geekyness” might be a common “language”, but only for World of Warcraft players or anime fans.

Personally I feel awkward when I say to other “common people” that programming is not only my job but also one of my strongest passions. What do you think about it? Same feeling? Do you have any other hobby? How does them helped you in your professional life? If you could choose, what did you wanted to be / do in your life?

I agree. You won’t be a good programmer if programming is not your passion. People who choose this job only because of money will never be successful. I hate people saying “Will I earn good money as a programmer if I learn xxx book or finish yyy course?”. If you don’t have passion you might be a coder, but never a top coder.(This is the quote of the day!!) I don’t have any special hobbies. I used to play poker and it’s changed my attitude towards money, so now I am not scared about of losing or winning any money. I am also happy about my current life.

If you have to leave for TCO14 with only 3 objects in your luggage, what would you choose? (and BTW will you actually bring them to San Francisco?)

Laptop and my mobile phone, because the flight will be very long. Nothing else special.

Will you be the next TCO15 champion?

Hard to say, because TCO15 will be different than TCO14. TC Admins are going to do the onsite tournament and they haven’t announced any information about the finals yet. I hope the onsite event will be different than current F2F finals.

[-6 to #TCO14] – TCO14 Rockstars: pt 1

6 Days to Top Coder Open and 6 blog post for each day!
The following is a blog post I wrote for the Top Code Open 2014 blog. Enjoy!

I was a rockstar at Cloudspokes (in the sense that I won almost every challenge I participated in), so it’s been really painful since the Cloudspokes and topcoder communities join together….I felt like I was not that special anymore!

And I have to secretly admit that I feared mostly 2 handles: albertwang and Sky_.

You may ask (I hope you’ll do…please…do it for my interview) “Why?”

The reason is simple:

  1. Can you figure out who won the first contest I entered in topcoder (and the first I lost)? Sky_
  2. Can you figure out who won the last challenge I lost the last month (even with a good 90% score)? Albertwang
  3. In both cases they both get an impressive 100% score!

And seeing both of them as winners of Design and Developer tracks made me feel a little mouse in front of big tigers but also gave me relief about my past losses!

That’s why I decided to get a chance to say a word or two to Albertwang, one of topcoder greatest rockstars!

So the first question is: how do you get those incredible scores? Magic? Super powers? You sold your soul to the devil? And if it is not magic (I really hope it is), how long you’ve been practicing programming? How your love for programming began? Excluding your family time, which is the % of time you dedicate to coding (reading, thinking and speaking included)? Is it enough or you would like more?

I’d attribute my achievements to commitment, hardworking and passion to learn new technologies.

I have been primarily focused on software architecture challenges, and for each project I usually spend a lot of time thinking and trying out various design ideas to approach the problem, and revise the designs in iterations. I’m particularly excited about projects involving emerging technologies/ideas or something I’m not familiar with, although usually they take much more time and effort to finish – I think curiosity and eagerness to learn new stuff keep me productive.

Which aspects of programming / designing software do you like more? Which of them helps you in the “common” life? If you had to convince me to start learning programming what would be your arguments? Technically speaking, which platform would you suggest me if I were a noob (or “noober”)? Or which aspect of programming do you suggest to improve?

I put elegance in an important position when either coding or designing a software system, and that’s probably the most enjoyable aspect for me in technical sense. Also making something useful, cool and awesome is always exciting and interesting to me, and coding an app is the easiest way for me to do so. I’m fascinated by the endless possibilities and innovations in mobile and wearables, that’s my current adventure and I’d definitely suggest to others.

Do you have a contest in your topcoder career that you love particularly? E.g. You learned something new? You got a really huge price? You felt like the best requirements in the world? You found your solution really elegant and effective? you particularly enjoyed coding? all of them?

NASA – ISS Food Intake Tracker iPad App is my favorite in terms of genre, knowing that the app will be used by astronauts on daily basis at the International Space Station 🙂

The most challenging and interesting one is the Healthcare Fraud Prevention series (Java and Python), which aims to develop a full set of secure and efficient data exchange protocol for healthcare service providers, and implement a scalable data exchange network infrastructure. It involved many technologies and presented quite a lot tough technical problems. I spent more than 100 hours and dropped three different failed attempts, yet I truly enjoyed the experience, I really liked the solution I proposed and I had great sense of achievement 🙂

How did you get to topcoder’s community? In which ways it has changed (and is changing) your life (at least the professional one)?

I started my topcoder adventure a decade ago, when I was in college. I’d say topcoder changed my life significantly, it opens great flexibility for my work and life, I have learned so much from the challenges and from the community.

I wanted to finish my interview with a “Will you be the next TCO15 winner?” but I got this answer back:

Well, since there won’t be software design track in the next TCO15, I could be the last TCO Software Design champion, and I probably won’t be at the next TCO finals at all. It’s really a shame that software design tracks are underrated these days.

All I can say is: Dear albertwang, there couldn’t be a TCO15 Design track next year but you certainly have the skills to win other tracks as well, so just move on and rock!

[Salesforce / Apex] Queueable interfaces – Unleash the async power!

The next Winter ’15 release came with the new Queueable interface.

I wanted to go deep on this, and tried to apply its features to a real case.

If you are (like me) in a TLDR; state of mind, click here.

The main difference between future methods (remember the @future annotation? ) and queueable jobs are:

  • When you enqueue a new job you get a job id (that you can actually monitor)…you got it, like batch jobs or scheduled jobs!
  • You can enqueue a queueable job inside a queueable job (you cannot call a future method inside a future method!)
  • You can have complex Objects (such as SObjects or Apex Objects) in the job context (@future only supports primitive data types)

I wanted to show a pratical use case for this new feature.

Imagine you have a business flow in which you have to send a callout whenever a Case is closed.
Let’s assume the callout will be a REST POST method that accepts a json body with all the non-null Case fields that are filled exactly when the Case is closed (the endpoint of the service will be a simple RequestBin).

Using a future method we would pass the case ID to the job and so make a subsequent SOQL query: this is against the requirement to pass the fields we have in the case at the exact time of the update.
This may seem an exageration, but with big Orgs and hundreds of future methods in execution (due to system overload) future methods can be triggered after minutes and so the ticket state can be different from when the future was actually triggered.

For this implementation we will use a Callout__c Sobject with the following fields:

  • Case__c: master/detail on Case
  • Job_ID__c: external ID / unique / case sensitive, stores the job id
  • Send_on__c: date/time, when the callout has taken place
  • Duration__c: integer, milliseconds for the callout to be completed
  • Status__c: picklist, valued are Queued (default), OK (response 200), KO (response != 200) or Failed (exception)
  • Response__c: long text, stores the server response

Let’s start with the trigger:

    trigger CaseQueueableTrigger on Case (after insert, after update) {

    List calloutsScheduled = new List();
    for(Integer i = 0; i < Trigger.new.size(); i++){
        if((Trigger.isInsert || 
           Trigger.new[i].Status != Trigger.old[i].Status)
            && Trigger.new[i].Status == 'Closed' )
        {
            ID jobID = System.enqueueJob(new CaseQueuebleJob(Trigger.new[i]));
            calloutsScheduled.add(new Callout__c(Job_ID__c = jobID, 
                                                 Case__c = Trigger.new[i].Id,
                                                Status__c = 'Queued'));
        }
    }
    if(calloutsScheduled.size()>0){
        insert calloutsScheduled;
    }
}

The code iterates through the trigger cases and if they are created as “Closed” or the Status field changes to “Closed” a new job is enqueued and a Callout__c object is created.

This way we always have evidence on the system that the callout has been fired.

Let’s watch the job code

    public class CaseQueuebleJob implements Queueable, Database.AllowsCallouts {
    . . .
    }

The Database.AllowsCallouts allow to send a callout in the job.

Next thing is a simple constructor:

    /*
     * Case passed on class creation (the actual ticket from the Trigger)
     */
    private Case ticket{get;Set;}
    
    /*
     * Constructor
     */
    public CaseQueuebleJob(Case ticket){
        this.ticket = ticket;
    }

And this is the content of the interface’s execute method:

    
     // Interface method. 
     // Creates the map of non-null Case fields, gets the Callout__c object
     // depending on current context JobID.
     // In case of failure, the job is queued again.
     
    public void execute(QueueableContext context) {
        //1 - creates the callout payload
        String reqBody = JSON.serialize(createFromCase(this.ticket));
        
        //2 - gets the already created Callout__c object
        Callout__c currentCallout = [Select Id, Status__c, Sent_on__c, Response__c, Case__c,
                                     Job_ID__c From Callout__c Where Job_ID__c = :context.getJobId()];
        
        //3 - starting time (to get Duration__c)
        Long start = System.now().getTime();
        
        //4 - tries to make the REST call
        try{
            Http h = new Http();
            HttpRequest request = new HttpRequest();
            request.setMethod('POST');
            //change this to another bin @ http://requestb.in
            request.setEndpoint('http://requestb.in/nigam7ni');
            request.setTimeout(60000);
            request.setBody(reqBody);
            HttpResponse response = h.send(request);
            
            //4a - Response OK
            if(response.getStatusCode() == 200){
                currentCallout.status__c = 'OK';
            //4b - Reponse KO
            }else{
                currentCallout.status__c = 'KO';
            }
            //4c - saves the response body
            currentCallout.Response__c = response.getBody();
        }catch(Exception e){
            //5 - callout failed (e.g. timeout)
            currentCallout.status__c = 'Failed';
            currentCallout.Response__c = e.getStackTraceString().replace('n',' / ')+' - '+e.getMessage();
            
            //6 - it would have been cool to reschedule the job again :(
            /*
             * Apprently this cannot be done due to "Maximum callout depth has been reached." exception
            ID jobID = System.enqueueJob(new CaseQueuebleJob(this.ticket));
            Callout__c retry = new Callout__c(Job_ID__c = jobID, 
                                                 Case__c = this.ticket.Id,
                                                Status__c = 'Queued');
            insert retry;
            */
        }
        //7 - sets various info about the job
        currentCallout.Sent_on__c = System.now();
        currentCallout.Duration__c = system.now().getTime()-start;
        update currentCallout;
        
        //8 - created an Attachment with the request sent (it could be used to manually send it again with a bonification tool)
        Attachment att = new Attachment(Name = 'request.json', 
                                        Body = Blob.valueOf(reqBody), 
                                        ContentType='application/json',
                                       ParentId = currentCallout.Id);
        insert att;
    }

These are the steps:

  1. Creates the callout JSON payload to be sent (watch the method in the provided github repo) for more details (nothing more than a describe and a map)
  2. Gets the Callout__c object created by the trigger (and using the context’s Job ID)
  3. Gets the starting time of the callout being executed (to calculate the duration)
  4. Tries to make the rest call

    1. Server responded with a 200 OK
    2. Server responded with a non OK status (e.g. 400, 500)
    3. Saves the response body in the Response__c field
  5. Callout failed, so fills the Respose__c field with the stacktrace of the exception (believe me this is super usefull when trying to get what happened, expecially when you have other triggers / code in the OK branch of the code)
  6. Unfortunately if you try to enqueue another job after a callout is done you get the following error Maximum callout depth has been reached., this is apparently not documented, but it should be related by the fact that you can have only 2 jobs in the queue chain, so apparently if you queue the same job you get this error.
    This way the job would have tried to enqueue another equal job for future execution.
  7. Sets time fields on the Callout__c object
  8. Finally creates an Attachment object with the JSON request done: this way it can be expected, knowing the precise state of the Case object sent and can be re-submitted using a re-submission tool that uses the same code (Batch job?).

This is a simple Callout__c object on CRM:

And this is an example request:

{
    "values": {
        "lastmodifiedbyid": "005w0000003fj35AAA",
        "businesshoursid": "01mw00000009wh7AAA",
        "engineeringreqnumber": "767145",
        "casenumber": "00001001",
        "product": "GC1060",
        "planid": "a05w000000Gpig7AAB",
        "ownerid": "005w0000003fj35AAA",
        "createddate": "2014-08-09T09:54:17.000Z",
        "origin": "Phone",
        "isescalated": false,
        "status": "Closed",
        "slaviolation": "Yes",
        "accountid": "001w0000019wqEIAAY",
        "systemmodstamp": "2014-11-03T19:33:31.000Z",
        "isdeleted": false,
        "priority": "High",
        "id": "500w000000fqNRaAAM",
        "lastmodifieddate": "2014-11-03T19:33:31.000Z",
        "isclosedoncreate": true,
        "createdbyid": "005w0000003fj35AAA",
        "contactid": "003w000001EetwEAAR",
        "type": "Electrical",
        "closeddate": "2013-06-20T18:59:51.000Z",
        "subject": "Performance inadequate for second consecutive week",
        "reason": "Performance",
        "potentialliability": "Yes",
        "isclosed": true
    }
}

The code and the related metadata is available on this GitHub repo.

[Salesforce / Lightning] Loading scripts

a{ color: red !important;}

UPDATE

Due to the introduction of the ltng:require, this post is no more a valid solution. Refer to the official Lightning documentation.

This post has been more like a request for help, rather than a technical blog post, but it came to be an awesome way to see Salesforce community in action and ready to help!In the last Dreamforce 14 big Mark presented the Lightning framework for fast development of reusable components (see details here and the awesome Topcoder’s track).Click here for the “Lightning Components Developer’s Guide”, well written and clear.I’ve noticed a strange behavior regarding external javascript libraries loading.These are the requirements regarding external script loading:

  • You can only load external libraries got from a static resource
  • You cannot use the {!$Resource.resourceName} expression because we are not inside a VisualForce page, so you have to simply refer to “/resource/[resourceName]” in your <script> tags
  • From page 100: “If you want to use a library, such as jQuery, to access the DOM, use it in afterRender().

Apparently the last sentence is not true.The problem arose because I loaded jQuery + Bootstrap and sometimes (and randomly) the Bootstrap plugin did not load because of jQuery was not yet loaded: the cause was certanly the fact that libraries were not loaded sequentially!TLDR; click here for the solution!This is what I’m trying to do:

BlogScriptApp.app

<aura:application>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:handler event="aura:doneRendering" action="{!c.doneRendering}"/>
    <script src="/resource/BlogScripts/jquery.min.js" ></script>    
    <div id="afterLoad">Old value</div>
</aura:application>

BlogScriptAppController.js

({
 doInit : function(component, event, helper) {
        try{
   $("#afterLoad").html("VALUE CHANGED!!!");
            console.log('doInit: Success');
        }catch(Ex){
            console.log('doInit: '+Ex);
        }
 },
    doneRendering : function(component, event, helper) {
        try{
   $("#afterLoad").html("VALUE CHANGED!!!");
            console.log('doneRendering: Success');
        }catch(Ex){
            console.log('doneRendering: '+Ex);
            
            setTimeout(function(){
                try{
                    $("#afterLoad").html("VALUE CHANGED!!!");
                    console.log('doneRendering-Timeout: Success');
                }catch(Ex){
                    console.log('doneRendering-Timeout: '+Ex);
                }
            }, 100);
        }
 }
})

BlogScriptAppRenderer.js

({
 afterRender : function(){
        this.superAfterRender();
  try{
   $("#afterLoad").html("VALUE CHANGED!!!");
            console.log('afterRender: Success');
        }catch(Ex){
            console.log('afterRender: '+Ex);
        }
  
    }
})

This is what I get in the console

doInit: ReferenceError: $ is not defined
afterRender: ReferenceError: $ is not defined
doneRendering: ReferenceError: $ is not defined
doneRendering-Timeout: Success 

This means that in the last app event (aura:doneRendering) we don’t have the libraries loaded, and that the only way to do it is to detach from the current execution and use the “setTimeout” method to call asynchronously the needed code.No surprise that this could not work if the jQuery library took too long to loadOne of the suggestions was to use RequireJS on the app, but the problem is the same: if the external scripts are not loaded, the “require” method does not exists and you cannot load its configuration.In this case RequireJS would allow to load in the correct order all the libraries (for instance jQuery, than bootstrap, then another lib …), like in this example:

BlogRequireJSApp.app

<aura:application>
    <aura:handler event="aura:doneRendering" action="{!c.doneRendering}"/>
    <script src="/resource/RequireJS" ></script>    
    <div id="afterLoad">Old value</div>
</aura:application>

BlogRequireJSAppController.js

({
 doneRendering : function(component, event, helper) {
        try{
            helper.loadRequire(component);
            console.log('doneRendering: Success');
        }catch(ex){
            console.log('doneRendering: '+ex);
            setTimeout(function(){
                try{
                    helper.loadRequire(component);
                    console.log('doneRendering-Timeout: Success');
                }catch(ex){
                 console.log('doneRendering-Timeout: '+ex);
                }
            }, 100);
        }
 }
})

BlogRequireJSAppHelper.js

({
    loadRequire : function(component) {
        require.config({
            paths: {
                "jquery": "/resource/BlogScripts/jquery.min.js?",
                "bootstrap": "/resource/BlogScripts/boostrap.min.js?"
            }
        });
        
        require(["jquery"], function($) {
            require(["bootstrap"], function(bootstrap, chartJS) {
                $("#afterLoad").html("VALUE CHANGED!!!");
            });
        });
    }
})

This is what I get in the console

doneRendering: ReferenceError: require is not defined
doneRendering-Timeout: Success 

This way you’ll have the scripts loaded in the correct order usign the RequireJS library: anyway if the RequireJS library is not yet loaded (it depends by your data connection) you’ll see another exception at the end of the log

Here comes the Salesforce community!

I posted a question on the SF developer forums and got a super cool response.From that response I came up with a simple solution that uses dynamic script loading and one event fired: this solution is a simpler reinterpretation of the forum’s one to make it easier to understand.

BlogRequireJSDinamic.app

<aura:application>
        <aura:handler event="forcelogic2:BlogRequireJSEvent" action="{!c.initJS}"/>
        <aura:registerEvent type="forcelogic2:BlogRequireJSEvent" name="requireJSEvent"/>
        <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
        <div id="afterLoad">Old value</div>
    </aura:application>

BlogRequireJSDinamicController.app

({
    /*
        Sets up the RequireJS library (async load)
    */
    doInit : function(component, event, helper){
        
        if (typeof require !== "undefined") {
            var evt = $A.get("e.forcelogic2:BlogRequireJSEvent");
            evt.fire();
        } else {
            var head = document.getElementsByTagName('head')[0];
            var script = document.createElement('script');
            
            script.src = "/resource/RequireJS"; 
            script.type = 'text/javascript';
            script.key = "/resource/RequireJS"; 
            script.helper = this;
            script.id = "script_" + component.getGlobalId();
            var hlp = helper;
            script.onload = function scriptLoaded(){
                var evt = $A.get("e.forcelogic2:BlogRequireJSEvent");
                evt.fire();
            };
            head.appendChild(script);
        }
    },
    
    initJS : function(component, event, helper){
        require.config({
            paths: {
                "jquery": "/resource/BlogScripts/jquery.min.js?",
                "bootstrap": "/resource/BlogScripts/boostrap.min.js?"
            }
        });
        console.log("RequiresJS has been loaded? "+(require !== "undefined"));
        //loading libraries sequentially
        require(["jquery"], function($) {
            console.log("jQuery has been loaded? "+($ !== "undefined"));
            require(["bootstrap"], function(bootstrap) {
                console.log("bootstrap has been loaded? "+(bootstrap !== "undefined"));
                $("#afterLoad").html("VALUE CHANGED!!!");
            });//require end
        });//require end
    }
})

This is what I get in the console

RequiresJS has been loaded? true
jQuery has been loaded? true
bootstrap has been loaded? true 

What has happened?When the app loads (init event) the doInit function tries to understand if the RequireJS library has been loaded. If so fires a BlogRequireJSEvent event. If not yet loaded, dynamically creates a <script> tag with the path to RequireJS, attaching an onload handler, which in fact will inform that the library has been loaded with the same event.The same app is also an handler for the BlogRequireJSEvent event trhough the initJS function: it will load sequentially jQuery and Bootstrap libraries: this way you are pretty sure libraries will be loaded in the correct order.The next step in the solution given in the forums is to make a component that does all the work and fires an event that can be handled from anywhere in your app / components set.All the code above has been packaged into a GitHub repository.Enjoy!

[Salesforce] Practical guide to setup a LiveAgent

I’ve created a simple guide to set up a Live Agent on an ORG with a custom console app.
This is the link: Live_Agent_base_configuration.pdf .
This is a really simple guide believe me and no further explaination is given, beucase the only aim is to make Live Agent working.

Let me know what you think!

May The Force.com be with you!

System.debug(‘TCO13’); //The event log

Day 1 – The arrival

I arrived in Washington D.C. at 5 p.m., after 10 hours and a half of plane and more than 1 hour on line at the customs: no need to say I was really tired.
That’s why the first day in Washington hasn’t been that good or exciting, no meeting with anyone, no TCO13 clues (except for the guys that got me at the airport), 6 hours of jet lag that apparently got me down (don’t ask me why, I survived to 11 hours jet lag in Polinesia without problems, even 9 hours in San Francisco, but with Washington as well as New York I needed 1 day to make the journey comfortable).
The only weird thing to note is what happened at the customs.
Officer: “Why are you staying in D.C.?”
Me: “For a nerd convention?”
Officer: “What??”
Me: “A convention of nerds about computer programming…I’m a computer programmer (and so I’m a nerd n.d.r.)”
Officer: [small laugh]
Me: [small laugh]
Officer: [checking my passport]
Officer: [bigger laugh]
Me: “What?”
Officer: “HAHA that’s weird!”
Me: “But that’s what it is!”
End of the story: I think the officer was a kind of bully when he was young, that’s why he was laughing repetedly…fonrtunately he let me pass!

Day 2 – The wheel we will spin

Nothing seemed to happend until I met @eucuepo on the street back to the hotel (I recognized him at first site, despite my difficulty to remember faces!).
Finally I met the great Tim Hicks (as I said in previous post, he’s my Cloudspokes bro).
It’s been love at first sight…we see eachother from distance and we run each other in time lapse…jokes apart, has been really cool to meet him after one year of emails, hangouts, blog posts and whatever happened!
At noon the jet lag seemed to gain power again, so I decided to take a sleep, but at about 4 p.m. I received a series of email/tweets that actually woke me up! It was @logonkartik who asks if we can meet downstairs at the hotel bar. That’s where I met him with @chok68, and finally the Cloudspokes crew started to grow up!

This is some nerd swag I got:

After few chats (trying to speak English better than I could) the crew added more guys: Kyle Bower, Cory McIlroy, Dave Messinger, Chris DeLaurentis, Mike Cardillo, @CloudBytes and George Acker for the Cloudspokes mith part, and @callmecatootie, @jan3594, @wcheung, @soe, @aproxcacs …I know I’m forgetting the majority!

I also had the pleasure to met Narinder Singh, the CEO/CIO of Cloudspokes.

At 7.30 pm TCO13 opens for the starting party (NASA, Google, Facebook among sponsors!!) and I finally had to spin the wheel. I got:

  • FinancialForce API
  • Amazon Webservices
  • Docusign

But still I have no hint of what I’m gonna do!

Day 3 – The infinite sleep

I know I’m on vacation, I’m in the US, I’m nerding like there won’t be a tomorrow, but today I’m really tired.
The only notable thing was that I met (finally) Jeff Douglas.

After a 2h city walk, I felt I need more concentration because of the lack of sleep, so I decided to close myself in the hotel room and start coding there, and that’s gone pretty cool.
I’ve coded from 12 pm to 7 pm and finally, together with the other guys, I went to the Faceook party at their Washington Offices: a big open space, with some nerdy things (Nintendo 64, Nerf guns for example), a big wall (I left my sign on it ) and cool Facebook guys that exaplined to us some things about their work and office (like why a room is called beofre “Al Gore”…just because one day the vice president went in their office and entered in that room and a guy said “Yay!” to greet him…”and that’s why this is the Al Gore room!”).
After that some other lines of code (messing with DocuSign), and I’m ready to dive in the bed (hopefully I’ll dream an entire night).

Day 4 – The coding day

Nothing notable today…coding from 5 am to 4 am (yes about 23 hours…just lunch and dinner time of break).
This is what I came up with: Sheherazade – The crowdsourcing story teller.

I tried to apply crowsourcing development in a less technical field that is the story telling. What I wanted to achieve was a sort of ideas generator (for plots, song lyrics, books made of pictures) for editors, rewarding users by money prices and comunity glory.

For a complete overview of the app see these demo videos:

  1. http://www.screencast.com/t/jzKwI389rfDJ
  2. http://www.screencast.com/t/nlIoJtgDmS
  3. http://www.screencast.com/t/hwNeUuR2pG8
  4. http://www.screencast.com/t/m7JJrwZ21a2n
  5. http://www.screencast.com/t/hUaaft0WK4qu

And these are the slides of the presentation.
I chose to code alone in my hotel room because of concentration and because in the main hall of the event I had to sit in pouf chairs not that comfortable, and what I wanted to do was a bit complicate and need the most of the time I could have.

Day 5 – Judgment and winner announcement

I slept about 3 hours to get the app ready, and made a funny presentation of my wedding day using the app, to show how a plot can be easily constructed using the comunity as a source of ideas.
This was the scaring jury:

This is the story: “…And they lived happily ever after…” .

This is me presenting the app (I think I was saying something really stupid…this is my “What did I say?!?” face ):

Than, after a 1 hour sleep, came the second presentation, to a bigger audience:

In a flash of an eye we were about to know the winners….and I got 4th place! Not bad! I think the main reason of the missed first place is that my APIs were hidden while the other solutions actually created “something new” with theier APIs (and in a really smart way…so congrats to my Cloudspokes buddies!!)…you can read in the following Jeff Douglas’s post the results and the video demo of the winner apps: The TCO13 Cloud Mashathon – Building Killer Apps with the API “Wheel of Fortune”.

I think this pic summarizes the coolness and amazingness and awesomeness of the whole TCO13:

This has been the most valuable professional expirience I’ve ever had, I could meet a lot of smart people from all over the world and compete with them in a friedly way (you know money makes people fighting each other), and I can say I was happy for my Cloudspokes buddy win, I recognize their value and great skills!
I really hope to be part of the TCO14, and I know I have to work hard to achieve this!
Lastly I want to thank all Cloudspokes and Topcoder staff for the opportunity they gave me and to make me feel a bit special!

This is the final video event:

[NodeJS + Salesforce SOAP WS] How to consume a Salesforce SOAP WSDL

I was wondering how to consume Salesforce WSDLs with nodejs.
I found Node Soap package (see npm) and I tried to consume a Partner WSDL.
Then I saved the WSDL in the “sf-partner.wsdl” file and played with the methods to get nodeJS speak SOAP with Salesforce.

var soap = require('soap');
var url = './sf-partner.wsdl';
soap.createClient(url, function(err, client) {
   console.log('Client created');
   console.log(client.SforceService.Soap); //all methods usable in the stub
});

If you try to console.log(client) you will see too much data

This is the output:

{ login: [Function],
  describeSObject: [Function],
  describeSObjects: [Function],
  describeGlobal: [Function],
  describeDataCategoryGroups: [Function],
  describeDataCategoryGroupStructures: [Function],
  describeFlexiPages: [Function],
  describeAppMenu: [Function],
  describeGlobalTheme: [Function],
  describeTheme: [Function],
  describeLayout: [Function],
  describeSoftphoneLayout: [Function],
  describeSearchLayouts: [Function],
  describeSearchScopeOrder: [Function],
  describeCompactLayouts: [Function],
  describeTabs: [Function],
  create: [Function],
  update: [Function],
  upsert: [Function],
  merge: [Function],
  delete: [Function],
  undelete: [Function],
  emptyRecycleBin: [Function],
  retrieve: [Function],
  process: [Function],
  convertLead: [Function],
  logout: [Function],
  invalidateSessions: [Function],
  getDeleted: [Function],
  getUpdated: [Function],
  query: [Function],
  queryAll: [Function],
  queryMore: [Function],
  search: [Function],
  getServerTimestamp: [Function],
  setPassword: [Function],
  resetPassword: [Function],
  getUserInfo: [Function],
  sendEmailMessage: [Function],
  sendEmail: [Function],
  performQuickActions: [Function],
  describeQuickActions: [Function],
  describeAvailableQuickActions: [Function] }

There is a quicker way to obtain this using the console.log(client.describe()) function, but this seems not to work with big WSDL like Salesforce ones (Maximum stack error)
The first move was to login to obtain a valid session id (using SOAP login action):

soap.createClient(url, function(err, client) {
    client.login({username: '[email protected]',password: 'FreakPasswordWithTkenIfNeeded'},function(err,result,raw){
      if(err)console.log(err);
      if(result){
          console.log(result.result);
    });
});

And this is the result

{ metadataServerUrl: 'https://na15.salesforce.com/services/Soap/m/29.0/00Di0000000Hxxx',
  passwordExpired: false,
  sandbox: false,
  serverUrl: 'https://na15.salesforce.com/services/Soap/u/29.0/00Di0000000Hxxx',
  sessionId: 'XXXXXXXXXX',
  userId: '005i0000000MXXXAAC',
  userInfo: 
   { accessibilityMode: false,
     currencySymbol: '€',
     orgAttachmentFileSizeLimit: 5242880,
     orgDefaultCurrencyIsoCode: 'EUR',
     orgDisallowHtmlAttachments: false,
     orgHasPersonAccounts: false,
     organizationId: '00Di0000000HxxxXXX',
     organizationMultiCurrency: false,
     organizationName: 'Challenges Co.',
     profileId: '00ei0000000UM6PAAW',
     roleId: {},
     sessionSecondsValid: 7200,
     userDefaultCurrencyIsoCode: {},
     userEmail: '[email protected]',
     userFullName: 'Admin',
     userId: '005i0000000MxxxXXX',
     userLanguage: 'en_US',
     userLocale: 'en_US',
     userName: '[email protected]',
     userTimeZone: 'Europe/Rome',
     userType: 'Standard',
     userUiSkin: 'Theme3' } }

Now the problem was to put the new endpoint and the session id or the next call, and this is the solution:

  //sets new soap endpoint and session id
  client.setEndpoint(result.result.serverUrl);
  var sheader = {SessionHeader:{sessionId: result.result.sessionId}};
  client.addSoapHeader(sheader,"","tns","");

And after that you can make wathever call you want:

      client.query({queryString:"Select Id,CaseNumber From Case"},function(err,result,raw){
          if(err){
            //console.log(err);
            console.log(err);
          }
          if(!err && result){
            console.log(result);
          }
      });

The result var will have all the data you expect from the SOAP response:

{ result: 
   { done: true,
     queryLocator: {},
     records: 
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ],
     size: 26 } }

The fact that you cannot call the client.describe() force us to read the WSDL to know which parameters send to the call.

[Salesforce / Canvas / NodeJS] Set up a minimum Canvas App (NodeJS style)

Following the old post [Salesforce / Canvas] Set up a minimum Canvas App (Java style) I’ve decided to put togheter the code I’ve used to talk to a Force.com Canvas App in NodeJS.

For those who can’t wait the whole article, this is the repo (CanvasApp-NodeJS-Base).

Follow this steps to configure an App (something is changed in the last SF releases):

  • Setup -> Create -> Apps -> (Connected Apps) New
  • Fill Conntected App Name, API Name and Contact Email
  • Check the Enable OAuth Settings in the API (Enable OAuth Settings) section
    • Callback URL: put a valid URL (you don’t need it for the scope of this example)
    • Selected OAuth Scopes: select the scopes you want for the NodeJS app acess token to grant
  • In the section Canvas App Settings type:
  • Canvas App URL: the url of the POST action to be called by Salesforce when injecting the session data (e.g. https://my-canvas-app.herokuapp.com/canvas/callback)
  • Access Method: use Signed Request (POST)
  • Locations: choose Chatter Tab (the app will be shown in the Chatter page)

Than you need to enable this app:

  • Setup -> Manage Apps -> Connected Apps -> Your App Name
  • In the OAuth policies select Admin approved users are pre-authorized for the Permitted Users field
  • In the Profiles related list select your profile (all user of that profile are automatically allowed to consume this app)

There are more ways to configure the Canvas App usage, this is the quicker.
Now clone this github repo CanvasApp-NodeJS-Base and create your own app:

$ cd [your test folder]
$ git clone https://github.com/enreeco/CanvasApp-NodeJS-Base
$ heroku create my-canvas-app
$ git push heroku master

The app will be pushed to Heroku (if you are using Heroku 🙂 ) and you will find it listening @ https://my-canvas-app.herokuapp.com.
Remember to use the “https” protocol in the callback URL setting, otherwise the canvas app won’t work correctly when called from Salesforce (using iframes with different protocols makes the browser go creazy).

To make it work you have to set the secret as an Environmental variable (the secret is the Consumer secret field in the App settings).
On Heroku simply type:

$ heroku config:set SF_CANVASAPP_CLIENT_SECRET=XXXXXXXXX

If you access the app outside the canvas this is what you see:

This is what happens in case of error:

This is what happens if all goes well:

The core of this app is the sf-tools/index.js file which handles the decoding of the POST request that contains all the canvas info (such as token, urls, …): have a look at the verifyAndDecode(input, secret) function.
You can then use this token and urls to make whatever call you want to your instance (as long as your user has access to it), but its outside of this post!

I leave you with a picture of a cute cat, this sould bring here a lot more readers.

Page 25 of 26

Powered by WordPress & Theme by Anders Norén