Friday, May 10, 2019

Making Community a Priority: 8 Community Events to Attend this Summer

By Kate Toporski, Educational and Onboarding Program Coordinator

So, I went to a Community-led event.

And I was totally blown away.

In the middle of March, I took the way-too-long plane trip from San Francisco to London to attend a Community-centric event all about Salesforce products and capabilities. This event is known as London's Calling (or on Twitter as #LDNsCall19).


Boasting an agenda filled with seasoned, Salesforce experts and over 600 users, community members, and sponsors, London's Calling is currently the largest community-led event for Salesforce professionals in all of Europe! With an emphasis on knowledge sharing, plenty of Einstein Analytics sessions, and free food (duh), I was ecstatic to be in attendance. My teammates and I came together to build several sessions to help Community members better understand and use all of the amazing capabilities of Einstein Analytics Plus, and we were pleased to see so many others doing the same...and don't worry- you didn't miss all of the magic; all of the sessions at London's Calling were recorded! You can access the talks here.



But, with all of that said, I was hungry for more. I was eager to learn from the Community, hear their stories, and engage with users from around the world. So, in attempt to connect myself (and you) with Trailblazer around the globe, I'd love to share the experience and opportunities that Community-led events provide by giving you the Top 8 Community Events to Attend This Summer! Keep on reading for 8 amazing events happening around the world this summer:

Texas Dreamin'

June 13-14th, Austin, TX


Ready for a Texas-sized Ohana event?! Texas Dreamin' is happening in Austin, TX on June 13 &14. The Salesforce Community has come together to empower and celebrate over 400 users, admins, and developers from Texas and beyond. You can still register to attend here!

Check out Altheas Taite's blog about Texas Dreamin' 2018!

YeurDreamin'

June 14, Amsterdam, Netherlands


NEW EVENT ALERT 👏YeurDreamin' is a new event on the European calendar this year! Centered around Lightning Platform, the Benelux Community will be hosting this educational and networking get-together on June 14. Save your spot here

NorCal Dreamin'

June 27-28, Sacramento, CA


Salesforce + California Sunshine = ☀️😍Another new event on this year's Community Events Calendar! Join the Salesforce Community in the beautiful, Northern California for two days of non-stop learning and fun. Registration is still open- so snag a ticket here.


Truth North Dreamin'

July 11-12, Ottawa, ON


Can anybody say, "Oh, Canada!" The first EVER Canada-wide Community Conference is happening in July. Join the Salesforce Ohana in Ottawa on July 11-12 for everything from building professional connections to rocking out at the Demo Jam. Ready to book? Reserve your spot here.

Big Sky Dreamin'

July 18-19, Bozeman, MT


Big Sky Dreamin' is coming to Montana this summer! Join the Salesforce Community at a destination Dreamin' Event, where the Ohana aims to enable developers, admins, veterans, high school students, and more. With lots of opportunities to learn and engage, get registered for Big Sky here.

Midwest Dreamin'

August 7-9, Chicago, IL


650 people, 3 days, and 7 tracks? COUNT ME IN! The original Community Conference will be taking place in Chicago on August 7-9 for some major learning and networking. And did I mention that there will be a track specifically dedicated to Einstein Analytics?! Get excited and register today! 


Czech Dreamin'

August 16, Prague, Czech Republic


Another first in the books. This summer, the Prague Community will be hosting the first technical conference about Salesforce in the Czech Republic! The organizers say, "Be prepared for a day full of great sessions!" Ready to hop a plane to Prague? Register here for the event on August 16.

Down Under Dreaming: Sydney

August 28, Sydney, Australia


Australia's largest Community Event is back! After last year's first ever (and completely sold out) Dreamin' Event, the Sydney Community is back to deliver a day full of breakout sessions for admins, developers, and business users on topics ranging from technical deep dives to equality at work. Get ready to dream down under by registering here




Now, this list doesn't even cover all of our events. Be sure to check out the Trailhead site for a complete list of events, conferences, meetups, and more. Check it out here. Hope to see you at a Dreamin' Event this summer or beyond!

Interested in being part of the #DataTribe? We can help get you involved. Find me, Rikke Hovgaard, or Ziad Fayad on Twitter, and send us a DM.

Friday, March 1, 2019

Top 6 Reasons to Attend an EA+ Academy in 2019

Your analytics journey is about to begin, and I know the perfect place to start.

When I first started exploring Einstein Analytics+ (otherwise known as EA+), I wasn't really sure where to start. From navigating Analytics Studio to shaping my data, I felt like I was lost in a world of dashboards! That's when I decided to attend one of our Einstein Analytics+ Academies.

An EA+ Academy is a free, hands-on, learning experience for Analytics customers. We send our seasoned EA+ experts around the world to get our customers started on their analytics journeys. An Academy can be anywhere from one to two days, covering EA+ Basic (beginner to intermediate), EA Advanced (advanced), or ED Advanced (intermediate).

After two days of a deep dive into the navigation, dashboard properties, and compare tables, I was hooked, and I know you will be too. So, here are the Top 6 Reasons to Attend an EA+ Academy this year!


1. Jumpstart your EA+ Journey

Like I said- getting started can be tough! By joining along in one of our academy courses, you are led by a seasoned, analytics expert. This means your questions are answered on the spot and any hiccups that you might run into along the way can be uncovered and solved. Analytics are intricate, but there are endless possibilities about how data can change the way your organization operates. Hear about how Analytics can transform your business this year from our very own Analytics SVP & GM- Ketan Karkhanis!


2. Learn the Latest Release

The ACE Team (Analytics Center for Excellence) is responsible for teaching and creating curriculum for our Academy program. This means, we have some of the leaders and best maintaining our learning material to reflect release updates and changes. We thoughtfully craft exercises and team activities to help you navigate the EA+ Platform, as well as updates to the Salesforce Platform. Spring '19 Release details are being shared and taught in academies all over the world!

Looking for information on Spring '19? Check it out here!


3. Visualize Your Passions and Data

Have you ever seen your data perfectly visualized in a beautiful chart or table? Ugh. What a feeling. During my academy session, I learned how to utilize dashboard properties to build visualizations of my data. Of course, this turned into making a whole dashboard about something I love- PIE!

By collecting data on the ingredients I used and the ratings that my colleagues gave the pies, I was able to see how cost and rating combined could give me the data on which pie was the best value in terms of cost and rating!



Yum or YUM. Am I right?


4. Free Trainings, All Over the World

Did I mention that our academy sessions are FREE?! Yep, you heard it here first. We offer our customers top-of-the-line training at no cost to make sure that you are getting the absolute most out of EA+. Need we say more?




Oh, right. Swag and food provided 😉


5. Hands-On Exercises

Our Analytics documentation is AMAZING, but we are ready to dive in with you- head first! Our curriculum is packed with hands-on exercises. With a seasoned analytics expert guiding the way, you'll walk through use cases, simulations, and mini-projects to see how Einstein Analytics+ functions for you.

From updating color themes on your dashboard to perfecting your faceting skills, our learning material is jam-packed with exercises to complete in class and on your own (c'mon, we need to challenge you a bit!).




6. Meet Other Trailblazers

#DataTribe, now accepting applications! That's right, when you attend an Einstein Analytics+ Academy, you are warmly welcomed into the #DataTribe. The EA+ community is full of brilliant, kind, and helpful Analytics users who are dedicated to building a platform that uplifts data-lovers around the world! You can see this in action on our Success Community, with over 26,000 members.

Whether it's at Dreamforce, World Tour, or a Community Meetup, our users have banded together to grow our product, push our innovative spirits, and help each other succeed through AI and predictive intelligence.





Are you fired up about academies yet?! Our Einstein Analytics+ Academies are an amazing opportunity to grow your skills in EA+ and your network of Trailblazers. If you're interested in attending one of our global Academy sessions, please contact your Account Executive or your Success Manager.

Until then, check out our other amazing Educational and Onboarding Tools that are available to you TODAY! We'll see you at the next academy.

Sunday, January 6, 2019

Einstein Analytics Dataflow REST API by example

The following link may be placed on your bookmarks bar and following the directions below you may view, start and stop dataflows. Please note there is no bullet proofing the script won't check if something is already running, etc. Also, it will acquire your SID, so please review the code carefully for any concerns.

data_flow

Basic instructions.

1) Log into Analytics Studio
2) Launch script
3) Look for popup in the upper left
4) View all the dataflows then select if you want to start, stop, etc.

The code.




/*
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

(function () {

var JQ = null;
var JQ_VERSION = "3.2.1";
var API_STR = "v43.0/";
var PROTO_STR = "https://";
var BASE_PATH_STR = "/services/data/";
var CREDENTIALS_OBJ = getServerSid();
var DIV_DOM_ELEM = document.createElement("div");
var SELECT_DOM_ELEM = document.createElement("SELECT");
var MAX_TIMEOUTS = 15;

  function loadItem (u, i) {
      var d = document;
      if (!d.getElementById(i)) {
          var s = d.createElement('script');
          s.src = u;
          s.id = i;
          d.body.appendChild(s);
      }
setTimeout(checkJQueryVersion, 50);
console.info("waiting on timeout");
  }
  loadItem('//code.jquery.com/jquery-' + JQ_VERSION + '.min.js', 'jquery')

// There's a better way to do this, tired of trying to get onload to work
function checkJQueryVersion () {
function finishJQueryProcessing () {
JQ = jQuery.noConflict( true );
setupHTMLAdds();
}
if (MAX_TIMEOUTS < 0) {
console.warning("We did not detect the correct jquery version, but exceeded timeouts waiting. Could be slow network, or the requested jquery version was not configured correctly.");
finishJQueryProcessing();
return;
}
MAX_TIMEOUTS--;

if ($.fn.jquery == JQ_VERSION) {
console.info("Successfully loaded jquery version:", $.fn.jquery, ". FYI, timeouts remaining:", MAX_TIMEOUTS);
finishJQueryProcessing();
return;
}
setTimeout(checkJQueryVersion, 50);
}

function addBr (dom_elem, n) {
for (var i=0;i<n;i++) {
dom_elem.appendChild(document.createElement("br"));
}
}

function setupHTMLAdds () {
DIV_DOM_ELEM.appendChild(SELECT_DOM_ELEM);
var btns_arr = [
{label: "All Dataflows", proc: getDataflows},
{label: "Start Selected Dataflow", proc: startRunningDataflow},
{label: "Active Dataflows", proc: getRunningDataflows},
{label: "Stop Selected Dataflow", proc: stopRunningDataflow},
{label: "Close Me", proc: closeMe}
];

addBr (DIV_DOM_ELEM, 2);
for (var i=0; i<btns_arr.length; i++) {
var btn = document.createElement("button");
DIV_DOM_ELEM.appendChild(btn);
addBr(DIV_DOM_ELEM, 1);
btn.innerText = btns_arr[i].label;
btn.onclick = btns_arr[i].proc;
}

addBr(DIV_DOM_ELEM, 3);

if (document.body.firstChild) document.body.insertBefore(DIV_DOM_ELEM, document.body.firstChild);
else document.body.appendChild(DIV_DOM_ELEM);
}

function removeAllChildren (elem) {
while (elem.firstChild) {
elem.removeChild(elem.firstChild);
}
}

function closeMe () {
DIV_DOM_ELEM.parentNode.removeChild(DIV_DOM_ELEM);
}

function getServerSid () {
var server = window.location.href.replace(/https?:\/\//,"").split("/")[0];
var sid = document.cookie.match(/(^|;\s*)sid=(.+?);/)[2];
var shell_sid = sid.replace(/!/g,"\\!");
return {"server": server, "sid": sid, "shell_sid": shell_sid};
}

function secureHeaderPrepSf (sid) {
return function (xhr) {
xhr.setRequestHeader('Authorization', "OAuth " + sid);
}
}

function createAjaxErrorResponse (deco_text) {
return function (jqXHR, text_status, error_thrown ) {
console.error("Error (INFO:", deco_text, ")" , "'jqXHR':", jqXHR, "'text status':", text_status, "'error thrown':", error_thrown)
}
}

function startRunningDataflow () {
  var val = SELECT_DOM_ELEM.options[SELECT_DOM_ELEM.selectedIndex].value;
  var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs";
  var patch_data = {
command: "Start",
dataflowId: val
};
  JQ.ajax({
  type: "POST",
  data: JSON.stringify(patch_data),
  contentType: "application/json; charset=utf-8",
  url: url,
  beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
  error: createAjaxErrorResponse("starting dataflow"),
  success: function (data) {
  if (data.status) alert("Start request sent, status is currently: " + data.status);
  else alert("Start request sent, but no status indication was recieved");
  console.info("stopRunningDataflow data result:", data);
  }
  })
  }

 function stopRunningDataflow () {
var val = SELECT_DOM_ELEM.options[SELECT_DOM_ELEM.selectedIndex].value;
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs/" + val ;
var patch_data = {command: "Stop"};
JQ.ajax({
type: "PATCH",
data: JSON.stringify(patch_data),
contentType: "application/json; charset=utf-8",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("stopping dataflow"),
success: function (data) {
if (data.message) alert("Kill request sent and received message: " + data.message);
else alert("Kill request sent, but no message was recieved - likely the job was complete");
console.info("stopRunningDataflow data result:", data);
}
})
 }

function getRunningDataflows () {
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflowjobs";
JQ.ajax({
type: "GET",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("obtaining running dataflows"),
success: function (data) {
console.info("getRunningDataflows data result:", data);
removeAllChildren(SELECT_DOM_ELEM);
for (var i=0;i<data.dataflowJobs.length; i++) {
var duration = data.dataflowJobs[i].duration;
if (!duration) {
if (data.dataflowJobs[i].status == "Queued") duration = 0;
else {
duration = Math.round(( new Date() - new Date(data.dataflowJobs[i].startDate) ) / 1000);
}
}
var opt = document.createElement('option');
    opt.value = data.dataflowJobs[i].id;
opt.innerHTML = data.dataflowJobs[i].label + ", " + duration + " (s), " + data.dataflowJobs[i].status;
    SELECT_DOM_ELEM.appendChild(opt);
}
}
})
}

function getDataflows () {
var url = PROTO_STR + CREDENTIALS_OBJ.server + BASE_PATH_STR + API_STR + "wave/dataflows";
JQ.ajax({
type: "GET",
url: url,
beforeSend: secureHeaderPrepSf(CREDENTIALS_OBJ.sid),
error: createAjaxErrorResponse("getting dataflows"),
success: function (data) {
console.info("getDataflows data result:", data);
removeAllChildren(SELECT_DOM_ELEM);
for (var i=0;i<data.dataflows.length; i++) {
var opt = document.createElement('option');
    opt.value = data.dataflows[i].id;
opt.innerHTML = data.dataflows[i].label;
    SELECT_DOM_ELEM.appendChild(opt);
}
}
})
}

}());