Quantcast
Channel: tyoshikawa1106のブログ
Viewing all 1438 articles
Browse latest View live

SFDC:Quip Live Appsの開発を試してみました

$
0
0

Quip Live Appsを試してみました。Quipのトライアル環境作成などはこちら。


Live Appsのイメージ

プロジェクトに必要なもの

  • Quipアカウント
  • Node.jsがインストールされたローカル環境

Nodeってそういえば最新バージョンいくつだろうと確認してみたところ、v9.3.0まででてました。せっかくなのでアップデート。
f:id:tyoshikawa1106:20171228125927p:plain

Install the Quip SDK

下記リンク先からダウンロードできます。

https://quip.com/dev/sdk/download

デスクトップにappフォルダを用意してそこに解答しました。
f:id:tyoshikawa1106:20171228130234p:plain


ターミナルを起動してcdコマンドで移動します。
f:id:tyoshikawa1106:20171228130256p:plain


Quipにはシークレット・ウィンドウモードでログインしておきます。(Chromeで実施)

Quip Developer Portalを開く

サイドメニューのアプリを選択します。
f:id:tyoshikawa1106:20171228130516p:plain:w200


ポップアップが表示されます。
f:id:tyoshikawa1106:20171228130559p:plain


Build your own live app のリンクをクリックします。
f:id:tyoshikawa1106:20171228130715p:plain


次の画面が表示されました。
f:id:tyoshikawa1106:20171228130745p:plain

ライブアプリを作成する

右上のCreate a Live Appのリンクをクリックします。App IDが画面に表示されるので記録します。
f:id:tyoshikawa1106:20171228131022p:plain

Quip Live アプリをビルド

基本的なコードは用意されています。先ほどcdコマンドでSDKフォルダに移動したのでそこから下記コマンドを実行します。

./bin/quip-apps init “$APP_NAME” $APP_ID 

※$APP_NAMEは任意の名前に変更します。
※$APP_ID は先ほど確認したIDに変更します。

$ ./bin/quip-apps init my_quip_app VXXXXXD

f:id:tyoshikawa1106:20171228131508p:plain


これでmy_quip_appフォルダが生成されます。React.jsアプリとのこと。

ライブアプリをパッケージ化する

パッケージ化してQuipプラットフォームにアップロードしてQuip内でアプリを実行できます。まずはcdコマンドで移動します。

$ cd <quip-sdk-folder>/apps/<your app name>

f:id:tyoshikawa1106:20171228131738p:plain


npm install を実行します。
f:id:tyoshikawa1106:20171228131917p:plain


npm run build を実行します。
f:id:tyoshikawa1106:20171228132127p:plain


warningという文字が出ましたがひとまず問題ありませんでした。次のコマンドを実行します。(※my-quip-appは最初に指定したアプリ名)

$ cd ../../
$ bin/quip-apps pack apps/my-quip-app/app

f:id:tyoshikawa1106:20171228133041p:plain


これで「app.ele」ファイルが生成されます。
f:id:tyoshikawa1106:20171228133121p:plain


QuipのEdit Live Appページに戻りapp.eleファイルをアップロードします。
f:id:tyoshikawa1106:20171228133323p:plain


検証時には何かがうまくいかなかったみたいでもう一度実施したのですが、次の画面が表示されれば成功です。
f:id:tyoshikawa1106:20171228133801p:plain

あなたのライブアプリをQuipでテストする

Quipに移動して新規文書を作成します。@の挿入機能を使い、アプリ名を入力します。
f:id:tyoshikawa1106:20171228133955p:plain


これで自作のアプリをQuipで動かすことができました。
f:id:tyoshikawa1106:20171228134025p:plain


今回はHello Woldとテキストが表示されるだけですが、いろいろなQuipアプリを開発できそうです。


SFDC:プラットフォームイベントをつかった通知アプリの開発を試してみました

$
0
0

プラットフォームイベントをつかった通知アプリ開発を試してみました。マイドメインが有効化されたDE組織が必要になります。

プラットフォームイベントを定義

設定から新規作成できます。
f:id:tyoshikawa1106:20171228145610p:plain


作成画面はこんな感じです。
f:id:tyoshikawa1106:20171228145703p:plain


API名は「__e」になります。
f:id:tyoshikawa1106:20171228145752p:plain


カスタム項目を作成します。
f:id:tyoshikawa1106:20171228145843p:plain

Lightningコンポーネント作成

notificationConsole.cmpを作成します。

<aura:component implements="flexipage:availableForAllPageTypes" access="global">

  <aura:attribute name="notifications" type="Object[]"/>
  <aura:attribute name="isMuted" type="Boolean" default="false"/>

  <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>

  <aura:registerEvent name="toastEvent" type="force:showToast"/>


  <div class="container">

    <!-- Header -->
    <div class="slds-p-around--x-small slds-border--bottom slds-theme--shade">
      <div class="slds-grid slds-grid--align-spread slds-grid--vertical-align-center">
        <div>
          <span class="slds-badge">{!v.notifications.length}</span>
        </div>
        <div>
          <lightning:buttonIcon onclick="{!c.onClear}" iconName="utility:delete" title="Clear notifications"
            alternativeText="Clear notifications" variant="border-filled"/>
          <lightning:buttonIcon onclick="{!c.onToggleMute}"
            iconName="{!v.isMuted ? 'utility:volume_off' : 'utility:volume_high'}"
            title="{!v.isMuted ? 'Unmute notifications' : 'Mute notifications'}"
            alternativeText="Toggle mute" variant="border-filled"/>
        </div>
      </div>
    </div>

    <!-- Notification list -->
    <div class="slds-container--fluid slds-scrollable--y content">
      <aura:iteration items="{!v.notifications}" var="notification">
        <div class="slds-p-around--small slds-border--top">
          <div class="slds-grid slds-grid--align-spread slds-has-flexi-truncate">
            <p>{!notification.message}</p>
            <p class="slds-text-color--weak slds-p-left--x-small">{!notification.time}</p>
          </div>
        </div>
      </aura:iteration>
    </div>

  </div>

</aura:component>


Controllerを作成します。

({
  onInit : function(component, event, helper) {
    component.set('v.notifications', [
      {time: '00:01', message: 'Greetings Trailblazer!'},
      {time: '00:02', message: 'Congratulations on building this first version of the app.'},
      {time: '00:03', message: 'Beware of the bears.'}
    ]);

    helper.displayToast(component, 'success', 'Ready to receive notifications.');
  },

  onClear : function(component, event, helper) {
    component.set('v.notifications', []);
    },

  onToggleMute : function(component, event, helper) {
    var isMuted = component.get('v.isMuted');
    component.set('v.isMuted', !isMuted);
    helper.displayToast(component, 'success', 'Notifications '+ ((!isMuted) ? 'muted' : 'unmuted') +'.');
    }
})


Helperを作成します。

({
  displayToast : function(component, type, message) {
    var toastEvent = $A.get('e.force:showToast');
    toastEvent.setParams({
      type: type,
      message: message
    });
    toastEvent.fire();
  }
})


Styleを作成します。

.THIS.container {
  height:100%;
}
.THIS .content {
  height:calc(100% - 49px);
}

Lightningコンソールの作成

App ManagerにアクセスしてSalesアプリケーションを編集する形で進めます。(Classicアプリケーションでは作業不可)
f:id:tyoshikawa1106:20171228150302p:plain


Utility Bar設定で先程のLightningコンポーネントを追加します。
f:id:tyoshikawa1106:20171228150606p:plain


f:id:tyoshikawa1106:20171228150800p:plain

Cometdのダウンロード

下記リンク先からダウンロードできます。

https://raw.githubusercontent.com/cometd/cometd/3.1.1/cometd-javascript/common/src/main/webapp/js/cometd/cometd.js


静的リソースへアップします。
f:id:tyoshikawa1106:20171228160150p:plain


NotificationControllerの作成

NotificationController.clsを作成します。

public class NotificationController {
    
    @AuraEnabled
    public static String getSessionId() {
      return UserInfo.getSessionId();
    }
}

Lightningコンポーネントの修正

<aura:component controller="NotificationController" implements="flexipage:availableForAllPageTypes" access="global">

  <ltng:require scripts="{!$Resource.cometd}" afterScriptsLoaded="{!c.onCometdLoaded}"/>
  <aura:attribute name="sessionId" type="String"/>
  <aura:attribute name="cometd" type="Object"/>
  <aura:attribute name="cometdSubscriptions" type="Object[]"/>
    
  <aura:attribute name="notifications" type="Object[]"/>
  <aura:attribute name="isMuted" type="Boolean" default="false"/>

  <aura:handler name="init" value="{!this}" action="{!c.onInit}"/>

  <aura:registerEvent name="toastEvent" type="force:showToast"/>


  <div class="container">

    <!-- Header -->
    <div class="slds-p-around--x-small slds-border--bottom slds-theme--shade">
      <div class="slds-grid slds-grid--align-spread slds-grid--vertical-align-center">
        <div>
          <span class="slds-badge">{!v.notifications.length}</span>
        </div>
        <div>
          <lightning:buttonIcon onclick="{!c.onClear}" iconName="utility:delete" title="Clear notifications"
            alternativeText="Clear notifications" variant="border-filled"/>
          <lightning:buttonIcon onclick="{!c.onToggleMute}"
            iconName="{!v.isMuted ? 'utility:volume_off' : 'utility:volume_high'}"
            title="{!v.isMuted ? 'Unmute notifications' : 'Mute notifications'}"
            alternativeText="Toggle mute" variant="border-filled"/>
        </div>
      </div>
    </div>

    <!-- Notification list -->
    <div class="slds-container--fluid slds-scrollable--y content">
      <aura:iteration items="{!v.notifications}" var="notification">
        <div class="slds-p-around--small slds-border--top">
          <div class="slds-grid slds-grid--align-spread slds-has-flexi-truncate">
            <p>{!notification.message}</p>
            <p class="slds-text-color--weak slds-p-left--x-small">{!notification.time}</p>
          </div>
        </div>
      </aura:iteration>
    </div>

  </div>

</aura:component>

Helperの修正

({
  connectCometd : function(component) {
    var helper = this;

    // Configure CometD
    var cometdUrl = window.location.protocol+'//'+window.location.hostname+'/cometd/40.0/';
    var cometd = component.get('v.cometd');
    cometd.configure({
      url: cometdUrl,
      requestHeaders: { Authorization: 'OAuth '+ component.get('v.sessionId')},
      appendMessageTypeToURL : false
    });
    cometd.websocketEnabled = false;

    // Establish CometD connection
    console.log('Connecting to CometD: '+ cometdUrl);
    cometd.handshake(function(handshakeReply) {
      if (handshakeReply.successful) {
        console.log('Connected to CometD.');
        // Subscribe to platform event
        var newSubscription = cometd.subscribe('/event/Notification__e',
          function(platformEvent) {
            console.log('Platform event received: '+ JSON.stringify(platformEvent));
            helper.onReceiveNotification(component, platformEvent);
          }
        );
        // Save subscription for later
        var subscriptions = component.get('v.cometdSubscriptions');
        subscriptions.push(newSubscription);
        component.set('v.cometdSubscriptions', subscriptions);
      }
      else
        console.error('Failed to connected to CometD.');
    });
      },

  disconnectCometd : function(component) {
    var cometd = component.get('v.cometd');

    // Unsuscribe all CometD subscriptions
    cometd.batch(function() {
      var subscriptions = component.get('v.cometdSubscriptions');
      subscriptions.forEach(function (subscription) {
        cometd.unsubscribe(subscription);
      });
    });
    component.set('v.cometdSubscriptions', []);

    // Disconnect CometD
    cometd.disconnect();
    console.log('CometD disconnected.');
  },

  onReceiveNotification : function(component, platformEvent) {
    var helper = this;
    // Extract notification from platform event
    var newNotification = {
      time : $A.localizationService.formatDateTime(
        platformEvent.data.payload.CreatedDate, 'HH:mm'),
      message : platformEvent.data.payload.Message__c
    };
    // Save notification in history
    var notifications = component.get('v.notifications');
    notifications.push(newNotification);
    component.set('v.notifications', notifications);
    // Display notification in a toast if not muted
    if (!component.get('v.isMuted'))
      helper.displayToast(component, 'info', newNotification.message);
  },

  displayToast : function(component, type, message) {
    var toastEvent = $A.get('e.force:showToast');
    toastEvent.setParams({
      type: type,
      message: message
    });
    toastEvent.fire();
  }
})

Controller.jsの修正

({
  onInit : function(component, event, helper) {
      component.set('v.cometdSubscriptions', []);
      component.set('v.notifications', []);
    
      // Disconnect CometD when leaving page
      window.addEventListener('unload', function(event) {
        helper.disconnectCometd(component);
      });
    
      // Retrieve session id
      var action = component.get('c.getSessionId');
      action.setCallback(this, function(response) {
        if (component.isValid() && response.getState() === 'SUCCESS') {
          component.set('v.sessionId', response.getReturnValue());
          if (component.get('v.cometd') != null)
            helper.connectCometd(component);
        }
        else
          console.error(response);
      });
      $A.enqueueAction(action);
    
      helper.displayToast(component, 'success', 'Ready to receive notifications.');
    },
    
    onCometdLoaded : function(component, event, helper) {
      var cometd = new org.cometd.CometD();
      component.set('v.cometd', cometd);
      if (component.get('v.sessionId') != null)
        helper.connectCometd(component);
    },


  onClear : function(component, event, helper) {
    component.set('v.notifications', []);
    },

  onToggleMute : function(component, event, helper) {
    var isMuted = component.get('v.isMuted');
    component.set('v.isMuted', !isMuted);
    helper.displayToast(component, 'success', 'Notifications '+ ((!isMuted) ? 'muted' : 'unmuted') +'.');
    }
})


これでコーディング部分は作業完了です。

動作確認

Bear Watch Heroku appというサイトから動作確認できます。

f:id:tyoshikawa1106:20171228160827p:plain

https://bear-watch.herokuapp.com/


Loginボタンをクリックしてアクセスの承認します。
f:id:tyoshikawa1106:20171228160920p:plain


ボタンをクリックすると処理が実行されます。
f:id:tyoshikawa1106:20171228160943p:plain


このようにSalesforce側の通知処理が実行できました。
f:id:tyoshikawa1106:20171228161353p:plain


処理が動かない場合は『cmd + shift + r』のキーで画面を再描画すると解決すると思います。

Apexトリガをつかった通知

NotificationController.clsの処理を変更します。

public class NotificationController {
    
    @AuraEnabled
    public static String getSessionId() {
      return UserInfo.getSessionId();
    }
    
    public static void publishNotifications(List<String> messages) {
      List<Notification__e> notifications = new List<Notification__e>();
      for (String message: messages) {
        notifications.add(new Notification__e(Message__c = message));
      }
    
      List<Database.SaveResult> results = EventBus.publish(notifications);
    
      // Inspect publishing results
      for (Database.SaveResult result : results) {
        if (!result.isSuccess()) {
          for (Database.Error error : result.getErrors()) {
            System.debug('Error returned: ' +
                   error.getStatusCode() +' - '+
                   error.getMessage());
          }
        }
      }
    }
}


TopicAssignmentオブジェクトのトリガを作成します。

trigger BearAlertTopicAssignmentTrigger on TopicAssignment (after insert) {

  // Get FeedItem posts only
  Set<Id> feedIds = new Set<Id>();
  for (TopicAssignment ta : Trigger.new){
    if (ta.EntityId.getSObjectType().getDescribe().getName().equals('FeedItem')) {
      feedIds.add(ta.EntityId);
    }
  }

  // Load FeedItem bodies
  Map<Id,FeedItem> feedItems = new Map<Id,FeedItem>([SELECT Body FROM FeedItem WHERE Id IN :feedIds]);

  // Create messages for each FeedItem that contains the BearAlert topic
  List<String> messages = new List<String>();
  for (TopicAssignment ta : [SELECT Id, EntityId, Topic.Name FROM TopicAssignment
      WHERE Id IN :Trigger.new AND Topic.Name = 'BearAlert']) {
    messages.add(feedItems.get(ta.EntityId).body.stripHtmlTags().abbreviate(255));
  }

  // Publish messages as notifications
  NotificationController.publishNotifications(messages);
}


これで準備完了です。Chatterに下記テキストを投稿します。

#BearAlert False alarm: It’s just a big dog!

f:id:tyoshikawa1106:20171228161908p:plain


先ほどと同じように通知が表示されます。


以上がプラットフォームイベントをつかった通知処理です。ユーティリティバーの通知はLightnign Experienceのみ利用可能となりますがすごく便利そうでした。

SFDC:Salesforce DX Quick Startを試してみました

$
0
0

Salesforce DX Quick Startを試してみました。トライアル環境は下記リンク先から取得できます。ログイン後マイドメイン有効化をしておきました。

f:id:tyoshikawa1106:20171228174316p:plain

dx-signup | Salesforce Developers


設定のDevHub画面はこんな感じでした。
f:id:tyoshikawa1106:20171228183341p:plain

インストーラのダウンロード

下記のリンク先からダウンロードできました。

https://sfdc.co/sfdx_cli_osx


画面に従って操作して簡単にインストールできます。
f:id:tyoshikawa1106:20171228181624p:plain:w300


正常にインストールできていれば次のコマンドを実行できます。

$ sfdx

f:id:tyoshikawa1106:20171228181957p:plain


DevHub環境にログイン

$ sfdx force:auth:web:login -d -a DevHub

実行するとログインページに移動します。
f:id:tyoshikawa1106:20171228182814p:plain


ログインすると認証ページが表示されます。
f:id:tyoshikawa1106:20171228182849p:plain


これでSalesforce DXのログインが実行できました。
f:id:tyoshikawa1106:20171228182939p:plain:w200


GitHubからサンプルプロジェクトをダウンロードします。

$ mkdir my_sfdx_project
$ cd my_sfdx_project
$ git clone https://github.com/forcedotcom/sfdx-dreamhouse.git
$ cd sfdx-dreamhouse

f:id:tyoshikawa1106:20171228184026p:plain


ブランチの作成

$ git checkout -b my_branch

f:id:tyoshikawa1106:20171228184216p:plain


Salesforce DXコマンドの確認

$ sfdx force --help

f:id:tyoshikawa1106:20171228184319p:plain


configフォルダのproject-scratch-def.jsonファイルでスクラッチ環境の設定情報を管理しているようです。
f:id:tyoshikawa1106:20171228203814p:plain


次のコマンドでスクラッチ組織を作成できます。スクラッチ組織は開発用の環境です。

$ sfdx force:org:create -s -f config/project-scratch-def.json -a "default scratch org"

f:id:tyoshikawa1106:20171228204729p:plain


DevHubとして使用した組織のスクラッチ情報タブから現在存在するスクラッチ組織を確認できます。
f:id:tyoshikawa1106:20171228205359p:plain


有効期限も決まっているため無期限に利用できるわけではないようです。
f:id:tyoshikawa1106:20171228205555p:plain


スクラッチ組織作成後は下記のコマンドでアクセスできます。

$ sfdx force:org:open


スクラッチ組織にコードをデプロイするには下記のコマンドを実行します。

$ sfdx force:source:push

f:id:tyoshikawa1106:20171228210051p:plain


変更が反映されていることを確認できました。
f:id:tyoshikawa1106:20171228210159p:plain


テストデータ作成も簡単にできるようです。次のコマンドで実行権限を付与できるみたいです。

$ sfdx force:user:permset:assign -n Dreamhouse


テストデータ作成は下記コマンドです。

$ sfdx force:data:tree:import --plan data/sample-data-plan.json


テストデータはdataフォルダのjsonファイルで定義されています。
f:id:tyoshikawa1106:20171228210735p:plain


たぶん正常に作成できました。
f:id:tyoshikawa1106:20171228210943p:plain


Salesforce DX Quick Startはこんな感じでした。

SFDC:API ExplorerでSalesforce APIの動作確認

$
0
0

まだPreview版ですが、Salesforce APIの動作確認ができるAPI Explorerサイトが用意されているみたいです。

f:id:tyoshikawa1106:20171230071644p:plain

https://developer.salesforce.com/docs/api-explorer


REST APIページはこんな感じ。
f:id:tyoshikawa1106:20171230071733p:plain


Try it nowボタンをクリックするとSalesforceへの接続ボタンが表示されます。
f:id:tyoshikawa1106:20171230071816p:plain


こんな感じで実行できました。
f:id:tyoshikawa1106:20171230072013p:plain

SFDC:Salesforce DXの接続組織の参照と削除

$
0
0

Salesforce DXのCLIで接続組織の一覧表示

参照はこちら。

$ sfdx force:org:list

f:id:tyoshikawa1106:20180103182910p:plain

Salesforce DXのCLIでSalesforceへログイン

接続していると下記コマンドでログインできます。

$ sfdx force:org:open -u <登録したい組織の別名>
例)
$ sfdx force:org:open -u MyDev

別名を付けて接続するには下記コマンドを実行します。

$ sfdx force:auth:web:login -r https://login.salesforce.com -a <登録したい組織の別名>
例)
$ sfdx force:auth:web:login -r https://login.salesforce.com -a MyDev

実行するとブラウザでログインページが表示されます。ログイン後に認証確認画面が表示されるので承認すれば完了です。

Salesforce DXのCLIで接続組織の削除

不要になった場合は下記のコマンドで組織を削除できます。※スクラッチ組織削除用?

$ sfdx force:org:delete  --targetusername

例)

$ sfdx force:org:delete  --sample@example.com


sfdx force:org:listのリストから除外するコマンドだと思ったのですが、過去のWebセミナーで組織を削除できる話を聞いた気がするのでスクラッチ組織削除のためのコマンドだと思います。

force:org:listから除外する方法

「force:org:list remove」で検索したら下記ページが見つかりました。


下記コマンドを実行します。

$ cd ~/.sfdx
$ rm <username>.json


これでsfdx force:org:listのリストから除外できました。
f:id:tyoshikawa1106:20180103213650p:plain

SFDC:Salesforce CLIコマンドガイド

SFDC:Salesforce CLIのヘルプコマンド

$
0
0

トピック一覧

ヘルプコマンド

$ sfdx force --help
 force:alias        manage username aliases
 force:apex         work with Apex code
 force:auth         authorize an org for use with the Salesforce CLI
 force:config       configure the Salesforce CLI
 force:data         manipulate records in your org
 force:doc          display help for force commands
 force:lightning    create and test Lightning component bundles
 force:limits       view your org’s limits
 force:mdapi        retrieve and deploy metadata using Metadata API
 force:org          manage your Salesforce DX orgs
 force:package      install and uninstall first- and second-generation packages
 force:package1     develop first-generation managed and unmanaged packages
 force:package2     develop second-generation packages
 force:project      set up a Salesforce DX project
 force:schema       view standard and custom objects
 force:source       sync your project with your orgs
 force:user         perform user-related admin tasks
 force:visualforce  create and edit Visualforce files


利用できるコマンド一覧

$ sfdx force:doc:commands:list
  force:alias:list                   # list username aliases for the Salesforce CLI
  force:alias:set                    # set username aliases for the Salesforce CLI
  force:apex:class:create            # create an Apex class
  force:apex:execute                 # execute anonymous Apex code
  force:apex:log:get                 # fetch a debug log
  force:apex:log:list                # list debug logs
  force:apex:test:report             # display test results
  force:apex:test:run                # invoke Apex tests
  force:apex:trigger:create          # create an Apex trigger
  force:auth:jwt:grant               # authorize an org using the JWT flow
  force:auth:sfdxurl:store           # authorize an org using an SFDX auth URL
  force:auth:web:login               # authorize an org using the web login flow
  force:config:get                   # get config var values for given names
  force:config:list                  # list config vars for the Salesforce CLI
  force:config:set                   # set config vars for the Salesforce CLI
  force:data:bulk:delete             # bulk delete records from a csv file
  force:data:bulk:status             # view the status of a bulk data load job or batch
  force:data:bulk:upsert             # bulk upsert records from a CSV file
  force:data:record:create           # create a record
  force:data:record:delete           # delete a record
  force:data:record:get              # view a record
  force:data:record:update           # update a record
  force:data:soql:query              # execute a SOQL query
  force:data:tree:export             # export data from an org into sObject tree format for force:data:tree:import consumption
  force:data:tree:import             # import data into an org using SObject Tree Save API
  force:doc:commands:display         # display help for force commands
  force:doc:commands:list            # list the force commands
  force:lightning:app:create         # create a Lightning app
  force:lightning:component:create   # create a Lightning component
  force:lightning:event:create       # create a Lightning event
  force:lightning:interface:create   # create a Lightning interface
  force:lightning:lint               # analyse (lint) Lightning component code
  force:lightning:test:create        # create a Lightning test
  force:lightning:test:install       # install Lightning Testing Service unmanaged package in your org
  force:lightning:test:run           # invoke Lightning component tests
  force:limits:api:display           # display current org’s limits
  force:mdapi:convert                # convert Metadata API source into the Salesforce DX source format
  force:mdapi:deploy                 # deploy metadata to an org using Metadata API
  force:mdapi:deploy:report          # check the status of a metadata deployment
  force:mdapi:retrieve               # retrieve metadata from an org using Metadata API
  force:mdapi:retrieve:report        # check the status of a metadata retrieval
  force:org:create                   # create a scratch org
  force:org:delete                   # mark a scratch org for deletion
  force:org:display                  # get org description
  force:org:list                     # list all orgs you’ve created or authenticated to
  force:org:open                     # open an org in your browser
  force:org:shape:create             # create a snapshot of org edition, features, and licenses
  force:org:shape:delete             # delete all org shapes for a target org
  force:org:shape:list               # list all org shapes you’ve created
  force:package1:version:create      # create a first-generation package version in the release org
  force:package1:version:create:get  # retrieve the status of a package version creation request
  force:package1:version:display     # display details about a first-generation package version
  force:package1:version:list        # list package versions for the specified first-generation package or for the org
  force:package2:create              # create a second-generation package
  force:package2:list                # list all second-generation packages in the Dev Hub org
  force:package2:update              # update a second-generation package
  force:package2:version:create      # create a second-generation package version
  force:package2:version:create:get  # retrieve a package version creation request
  force:package2:version:create:list # list package version creation requests
  force:package2:version:get         # retrieve a package version in the Dev Hub org
  force:package2:version:list        # list all package versions in the Dev Hub org
  force:package2:version:update      # update a second-generation package version
  force:package:install              # install a package in the target org
  force:package:install:get          # retrieve the status of a package installation request
  force:package:installed:list       # list the org’s installed packages
  force:package:uninstall            # uninstall a second-generation package from the target org
  force:package:uninstall:get        # retrieve status of package uninstall request
  force:project:create               # create a new SFDX project
  force:project:upgrade              # update project config files to the latest format
  force:schema:sobject:describe      # describe an object
  force:schema:sobject:list          # list all objects of a specified category
  force:source:convert               # convert Salesforce DX source into the Metadata API source format
  force:source:open                  # edit a Lightning Page with Lightning App Builder
  force:source:pull                  # pull source from the scratch org to the project
  force:source:push                  # push source to an org from the project
  force:source:status                # list local changes and/or changes in a scratch org
  force:user:create                  # create a user for a scratch org
  force:user:display                 # displays information about a user of a scratch org
  force:user:list                    # lists all users of a scratch org
  force:user:password:generate       # generate a password for scratch org users
  force:user:permset:assign          # assign a permission set to one or more users of an org
  force:visualforce:component:create # create a Visualforce component
  force:visualforce:page:create      # create a Visualforce page

SFDC:Salesforce CLIのエラーメモ

$
0
0

根本的に使い方を間違えているかもしれませんが、下記のコマンドを実行した時にエラーになりました。

$ sfdx force:source:pull


エラーメッセージはこちら。

MemberName, IsNameObsolete FROM SourceMember WHERE RevisionNum >
^
ERROR at Row:1:Column:52
sObject type 'SourceMember' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.

f:id:tyoshikawa1106:20180103231850p:plain

検索したらこちらがヒット。


あとはこちら。


スクラッチ組織でしか実行できないのか、設定ファイルが必要なのか、それ以外なのかわかっていませんがいつか使うかもしれないのでメモ。

追記

やっぱりforce:source:pullはスクラッチ組織用のコマンドっぽい。


SFDC:Salesforce DXのアプリ開発を少し試してみました

$
0
0

Salesforce DXのアプリ開発を試してみました。開発者ガイドが用意されているのでこちらを参照。


CLIの環境構築とエディタについてはこちら。



デスクトップにappフォルダを作成してここで試します。
f:id:tyoshikawa1106:20180103180800p:plain

Salesforce DX プロジェクトの作成

myworkは任意のプロジェクト名です。

$ sfdx force:project:create --projectname mywork

ディレクトリの指定をする場合はこちら。

sfdx force:project:create --projectname mywork --defaultpackagedir myapp

f:id:tyoshikawa1106:20180103222803p:plain


これでappフォルダ内にmyworkプロジェクトが作成されました。VS Codeにドラッグ&ドロップするとエディタで表示できます。
f:id:tyoshikawa1106:20180103223200p:plain


configフォルダにSalesforce DXの環境ファイルが用意されています。DevHub組織未ログインでも作成されました。(※事前にやった過去ログインの設定情報削除されていれば...)
f:id:tyoshikawa1106:20180103223349p:plain


README.mdファイルも雛形が作成されています。
f:id:tyoshikawa1106:20180103223439p:plain


forceignoreというファイルも作成されました。gitignoreと同じ効果だと思います。
f:id:tyoshikawa1106:20180103223518p:plain


sfdx-project.jsonも設定ファイルです。API名とか指定できるようでした。
f:id:tyoshikawa1106:20180103223601p:plain

開発環境にログイン

$ sfdx force:org:open -u <登録したい組織の別名>

下記コマンドで登録されていることを確認できます。

$ sfdx force:org:list

ユーザ名の登録

ローカル環境でのみ利用できる開発者ユーザ名を登録します。

$ sfdx force:config:set defaultusername=<ユーザ名>

実行すると.sfdxフォルダにsfdx-config.jsonが生成されます。
f:id:tyoshikawa1106:20180103230003p:plain

package.xmlの準備

README.mdファイルと同じ階層に用意します。

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
	<types>
		<members>*</members>
		<name>ApexClass</name>
	</types>
	<types>
		<members>*</members>
		<name>ApexComponent</name>
	</types>
	<types>
		<members>*</members>
		<name>ApexPage</name>
	</types>
	<types>
		<members>*</members>
		<name>ApexTrigger</name>
	</types>
	<types>
		<members>*</members>
		<name>StaticResource</name>
	</types>
	<version>41.0</version>
</Package>

ソースコードのダウンロード

下記のコマンドでソースコードをダウンロードします。

$ sfdx force:mdapi:retrieve -r ./mdapipkg -u <ユーザ名またはエイリアス> -k ./package.xml


mdapipkgフォルダにZipファイルがダウンロードされます。それを解答するとソースコード一式を確認できます。
f:id:tyoshikawa1106:20180103234220p:plain


このあと下記コマンドでDX用に変換します。

$ sfdx force:mdapi:convert --rootdir ./mdapipkg/unpackaged


これでmainフォルダ内にソースコードをダウンロードできました。
f:id:tyoshikawa1106:20180103234422p:plain



ここまではうまく行きましたがソースコードのデプロイや最新版の取得はやはりDXの機能でDevHubとスクラッチ組織で実行が必要になります。DE組織での開発はJSforceコマンドをつかった方が良さそうです。


・・・MavensMateになれているのでコマンドで開発していける気がしなくなってきました。

SFDC:開発者ハブ (Dev Hub)の有効化時の注意点

$
0
0

Salesforce DXの開発フローを導入するには開発者ハブ (Dev Hub)の有効化が必要になりますが、1点注意がありました。

f:id:tyoshikawa1106:20180105140643p:plain


Salesforce DX の使用を開始するには、Dev Hub として機能する組織を選択します。Dev Hub は任意の有料組織で有効にできますが、本番組織以外の組織を使用することをお勧めします。・・とのことです。


試していませんがSandbox組織でも有効化できるっぽいです。本番で有効化するデメリットはわかりませんが、社内エンジニアの勉強用に有効化する場合はSandbox組織の方が良いかもしれません。(Sandbox組織は25個まで作成可能だったと思うので1開発者につき1つ組織を作るといったことはできないと思いますが。。)

SFDC:Salesforce DXの開発フローを試してみました

$
0
0

Salesforce DXでLightningアプリの開発をやってみました。

CLIの環境構築とエディタについてはこちら。

DevHub組織への接続

DevHub組織へログインします。

$ sfdx force:auth:web:login -d -a DevHub


コマンドを実行するとブラウザでログインページが表示されるのでいつもどおりログインと認証をすれば完了です。下記コマンドで正しく接続できているか確認できます。

$ sfdx force:org:list

f:id:tyoshikawa1106:20180105144004p:plain


上のコマンドでDevHubというエイリアス名で登録できているので、以後は下記コマンドでログイン可能になります。

$ sfdx force:org:open -u DevHub
オプションの見方
  • d : DevHub組織としての登録
  • a : エイリアスを登録する際に指定

Salesforce DXのプロジェクト作成

デスクトップにgeolocationという名前のプロジェクトを作成します。

$ cd desktop
$ mkdir app
$ cd app
$ sfdx force:project:create -n geolocation
$ cd geolocation


VS Codeでgeolocationフォルダを表示します。
f:id:tyoshikawa1106:20180105144838p:plain

スクラッチ組織の作成

下記のコマンドでスクラッチ組織を作成できます。スクラッチ組織のエイリアス名は「GeoAppScratch」を指定。

$ sfdx force:org:create -s -f config/project-scratch-def.json -a GeoAppScratch


作成後はDevHub組織でスクラッチ組織の情報にアクセスできます。
f:id:tyoshikawa1106:20180105145934p:plain

スクラッチ組織作成時の重要なオプション
  • s : このスクラッチ組織をこのプロジェクトのデフォルト組織にすることを指定します。

これでオブジェクト作成コマンドなどはスクラッチ組織を対象となります。


force:org:listコマンドを確認したところこのようになっていました。
f:id:tyoshikawa1106:20180105150711p:plain

スクラッチ組織にアクセス

下記コマンドでスクラッチ組織を開きます。-sでデフォルト指定しているので組織名は指定不可になっていると思います。

$ sfdx force:org:open


正しくスクラッチ組織にアクセスしているかは組織IDで確認できると思います。マイドメインは自動で登録されました。※DevHub組織との関連性なし。
f:id:tyoshikawa1106:20180105151406p:plain

確認中に気になった点

DevHub組織で作成したカスタムオブジェクトはスクラッチ組織に移行されていませんでした。Sandboxのようには使えないのかもしれません。

カスタム項目の作成

スクラッチ組織でカスタム項目を作成します。

  • [取引先] をクリックします。
  • [項目とリレーション] セクションで、[新規] をクリックします。
  • データ型に [地理位置情報] を選択し、[次へ] をクリックします。
  • 次の詳細を入力して、[次へ] をクリックします。
  • 項目の表示ラベル: Location (場所)
  • 緯度および経度表示の表記法: 小数
  • 小数部の桁数: 7
  • 項目名: Location (場所)

f:id:tyoshikawa1106:20180105152105p:plain


次の動作確認のため権限は除外します。
f:id:tyoshikawa1106:20180105152149p:plain


Location項目のアクセス権限を付与する権限セットを作成します。
f:id:tyoshikawa1106:20180105152423p:plain

f:id:tyoshikawa1106:20180105152436p:plain


下記のコマンドでユーザに権限セットの割当ができます。

$ sfdx force:user:permset:assign -n Geolocation

※Geolocationは権限セットの名前を指定

f:id:tyoshikawa1106:20180105152621p:plain


無事に割り当てが実行できていました。
f:id:tyoshikawa1106:20180105152655p:plain

スクラッチ組織の変更をローカル環境に反映

下記のコマンドを実行するとスクラッチ組織の変更をローカルのプロジェクトに反映できます。

$ sfdx force:source:pull

f:id:tyoshikawa1106:20180105152945p:plain


変更箇所のみが反映されるようです。ローカルのプロジェクトをみるとlayoutやobjectフォルダが追加されていました。
f:id:tyoshikawa1106:20180105153057p:plain

Gitでバージョン管理

Salesforce DXはGitなどによるバージョン管理を行なうことが前提の仕組みです。GitHubやBitbucketなどありますが、今回はプライベートリポジトリが利用できるBitbucketを使ってみます。


このような感じでリポジトリの新規作成を行いました。
f:id:tyoshikawa1106:20180106150547p:plain


これでssh urlの部分が取得できます。下記のコマンドを実行します。

$ git init
$ git remote add origin <ssh url>
$ git add -A
$ git commit -m "Add custom object and permset"
$ git push origin master


cdコマンドでgeolocationフォルダの一番上に移動している状態で実行しました。
f:id:tyoshikawa1106:20180106151004p:plain


これでローカルのソースコードをBitbucketのリポジトリに保存できました。
f:id:tyoshikawa1106:20180106151245p:plain


注意しないとプロジェクトごとにバラバラになってしまいそうなフォルダの階層管理もDXでは雛形を用意してくれます。またREADME.mdファイルもテンプレートがあるのでこれに合わせていけばよさそうです。

サンプルデータ

組織作成後に一番困るのはサンプルデータの作成です。Salesforce DXではサンプルデータを簡単にインポートできる仕組みが用意されています。

Salesforce組織でテストデータを作成

まずはスクラッチ組織にアクセスします。未ログインの場合はopenコマンドでアクセス可能です。

$ sfdx force:org:open


今回作成するのは取引先レコードです。
f:id:tyoshikawa1106:20180106151912p:plain


データの準備ができたらdataフォルダをプロジェクトに追加します。

$ mkdir data


次のコマンドでスクラッチ組織のサンプルデータをエクスポートできます。

$ sfdx force:data:tree:export -q "SELECT Name, Location__Latitude__s, Location__Longitude__s FROM Account WHERE Location__Latitude__s != NULL AND Location__Longitude__s != NULL" -d ./data

f:id:tyoshikawa1106:20180106152157p:plain


サンプルデータはJSON形式でエクスポートされます。インポートする際にJSON形式になっていればいいので、手動で作成したりも可能となっています。
f:id:tyoshikawa1106:20180106152252p:plain


作成したサンプルデータをインポートすれば組織作成後に簡単にテストデータを作成できます。わかりやすくなるように先ほどのデータは削除しました。
f:id:tyoshikawa1106:20180106152518p:plain



インポートは次のコマンドになります。

$ sfdx force:data:tree:import --sobjecttreefiles data/Account.json

f:id:tyoshikawa1106:20180106152608p:plain


スクラッチ組織を確認したところ正常に作成できていました。
f:id:tyoshikawa1106:20180106152734p:plain


こうしたインポート用のサンプルデータもGitリポジトリで管理できるようになります。
f:id:tyoshikawa1106:20180106153033p:plain


入力規則やトリガの追加があるので一度つくったサンプルデータをアップデートしていくのは頻繁に発生すると思います。こうした情報も管理できるようになるのはすごく良さそうです。

地理位置情報アプリケーションの作成

ここまでで開発用組織とサンプルデータ、Gitリポジトリの準備ができました。ここからLightningアプリの開発を行います。

Apex コントローラクラスの作成

次のコマンドでApexクラスを作成できます。

$ sfdx force:apex:class:create -n AccountController -d force-app/main/default/classes

f:id:tyoshikawa1106:20180106153416p:plain


エディタで次のように処理を実装します。 (インデントは適当ですが・・)
f:id:tyoshikawa1106:20180106153603p:plain


保存後に下記のコマンドを実行するとスクラッチ組織にアップロードされます。

$ sfdx force:source:push

f:id:tyoshikawa1106:20180106153719p:plain

public with sharing class AccountController {
 @AuraEnabled
 public static List<Account> findAll() {
 return [SELECT Id, Name, Location__Latitude__s, Location__Longitude__s
   FROM Account
   WHERE Location__Latitude__s != NULL AND Location__Longitude__s !=
          NULL
   LIMIT 50];
  }
}

無事に保存できていました。
f:id:tyoshikawa1106:20180106153815p:plain


エラーチェックも当然実施されました。
f:id:tyoshikawa1106:20180106153906p:plain

Lightning コンポーネントの作成

続いてLightning コンポーネントの作成です。下記のコマンドを実行します。

$ sfdx force:lightning:component:create -n AccountListItem -d force-app/main/default/aura

f:id:tyoshikawa1106:20180106154052p:plain


AccountListItemのソースコードはこんな感じ。
【AccountListItem.cmp】

<aura:component>
  <aura:attribute name="account" type="Account"/>
  <li><a>{!v.account.Name}</a></li>
</aura:component>

【AccountListItem.css】

.THIS {
    border-bottom: solid 1px #DDDDDD;
}

.THIS a {
    display: block;
    padding: 20px;
    color: inherit;
}

.THIS a:active {
    background-color: #E8F4FB;
}

コーディングはVS Codeから行っています。
f:id:tyoshikawa1106:20180106154319p:plain



AccountList コンポーネントを作成します。

$ sfdx force:lightning:component:create -n AccountList -d force-app/main/default/aura

f:id:tyoshikawa1106:20180106154412p:plain


【AccountList.cmp】

<aura:component controller="AccountController">

    <aura:attribute name="accounts" type="Account[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <ul>
    <aura:iteration items="{!v.accounts}" var="account">
        <c:AccountListItem account="{!account}"/>
    </aura:iteration>
    </ul>

</aura:component>

【AccountListController.js】

({
    doInit : function(component, event) {
        var action = component.get("c.findAll");
        action.setCallback(this, function(a) {
          component.set("v.accounts", a.getReturnValue()); 
        });
        $A.enqueueAction(action);
    }
})

【AccountList.css】

.THIS {
    list-style-type: none;
    padding: 0;
    margin: 0;
    background: #FFFFFF;
     height: 100%;
}


AccountLocatorコンポーネントを作成します。

$ sfdx force:lightning:component:create -n AccountLocator -d force-app/main/default/aura

f:id:tyoshikawa1106:20180106155408p:plain

【AccountLocator.cmp】

<aura:component implements="force:appHostable">
    <div>
        <div>AccountMap goes here</div>
        <div>
          <c:AccountList/>
        </div>
    </div>
</aura:component>

【AccountLocator.css】

.THIS {
  position:absolute;
  height: 100%;
  width: 100%;
  background: #FFFFFF;
}

.THIS>div {
  height: 50%;
}


これでコンポーネントの準備ができました。下記コマンドでスクラッチ組織にプッシュします。

$ sfdx force:source:push

f:id:tyoshikawa1106:20180106155702p:plain


作成したLightningコンポーネントへのアクセスはタブから行います。
f:id:tyoshikawa1106:20180106155905p:plain


このように表示されればひとまずOKです。
f:id:tyoshikawa1106:20180106160009p:plain


スクラッチ組織でタブを作成したのでローカルプロジェクトに持ってきます。

$ sfdx force:source:pull

f:id:tyoshikawa1106:20180106161538p:plain

地図表示処理の実装

Leafletのサイトから最新の安定バージョンをダウンロードします。

Download - Leaflet - a JavaScript library for interactive maps


静的リソースに保存します。
f:id:tyoshikawa1106:20180106161856p:plain


ローカルプロジェクトに反映します。

$ sfdx force:source:pull


試していてちょっとびっくりしたのですがSalesforce DXの機能で管理すればZipファイルの中身がきちんと解凍された状態で取得されました。
f:id:tyoshikawa1106:20180106162210p:plain

AccountMap コンポーネントの作成

AccountMap コンポーネントを作成します。

$ sfdx force:lightning:component:create -n AccountMap -d force-app/main/default/aura

【AccountMap.cmp】

<aura:component>

    <aura:attribute name="map" type="Object"/>

    <ltng:require styles="/resource/leaflet/leaflet.css"
        scripts="/resource/leaflet/leaflet.js"
        afterScriptsLoaded="{!c.jsLoaded}" />

    <div id="map"></div>

</aura:component>

【AccountMapController.js】

({
   jsLoaded: function(component, event, helper) {

      var map = L.map('map', {zoomControl: false}).setView([37.784173, -122.401557], 14);
      L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
        {
              attribution: 'Tiles © Esri'
        }).addTo(map);
      component.set("v.map", map);
  }
})

【AccountMap.css】

.THIS {
   width: 100%;
   height: 100%;
}

【AccountLocator.cmp】

<aura:component implements="force:appHostable">

    <div>
        <div>
            <c:AccountMap />
        </div>

        <div>
            <c:AccountList />
        </div>
    </div>

</aura:component>


スクラッチ組織にアップロード

$ sfdx force:source:push


Leafletの地図が表示されることを確認できます。
f:id:tyoshikawa1106:20180106162930p:plain

地図にマーカーを追加する Lightning イベントの作成

AccountsLoaded イベントを作成します

$ sfdx force:lightning:event:create -n AccountsLoaded -d force-app/main/default/aura

f:id:tyoshikawa1106:20180106163905p:plain

【AccountsLoaded.evt】

<aura:event type="APPLICATION">
    <aura:attribute name="accounts" Type="Account[]"/>
</aura:event>

【AccountList.cmp】

<aura:component controller="AccountController">
    <aura:registerEvent name="accountsLoaded" type="c:AccountsLoaded"/>
    <aura:attribute name="accounts" type="Account[]"/>
    <ltng:require styles="/resource/leaflet/leaflet.css" scripts="/resource/leaflet/leaflet.js" afterScriptsLoaded="{!c.doInit}" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <ul>
    <aura:iteration items="{!v.accounts}" var="account">
        <c:AccountListItem account="{!account}"/>
    </aura:iteration>
    </ul>

</aura:component>

【AccountListController.js 】

({
    doInit : function(component, event) {
        var action = component.get("c.findAll");
        action.setCallback(this, function(a) {
            component.set("v.accounts", a.getReturnValue());
            var event = $A.get("e.c:AccountsLoaded");
            event.setParams({"accounts": a.getReturnValue()});
            event.fire();
        });
    $A.enqueueAction(action);
    }
})

【AccountMap.cmp】

<aura:component>

    <aura:attribute name="map" type="Object"/>
    <aura:handler event="c:AccountsLoaded" action="{!c.accountsLoaded}"/>

    <ltng:require styles="/resource/leaflet/leaflet.css"
        scripts="/resource/leaflet/leaflet.js"
        afterScriptsLoaded="{!c.jsLoaded}" />

    <div id="map"></div>

</aura:component>

【AccountMapController.js】

({
    jsLoaded: function(component, event, helper) {

        var map = L.map('map', {zoomControl: false}).setView([37.784173, -122.401557], 14);
        L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
             {
                 attribution: 'Tiles © Esri'
             }).addTo(map);
        component.set("v.map", map);
    },

    accountsLoaded: function(component, event, helper) {

        // Add markers
        var map = component.get('v.map');
        var accounts = event.getParam('accounts');
        for (var i=0; i<accounts.length; i++) {
            var account = accounts[i];
            var latLng = [account.Location__Latitude__s, account.Location__Longitude__s];
            L.marker(latLng, {account: account}).addTo(map);
        }  
    }
})


更新を反映します。

$ sfdx force:source:push


マーカーが表示されるようになりました。
f:id:tyoshikawa1106:20180106164439p:plain

アプリケーションの検証

Trailheadにアプリケーション検証用のスクラッチ組織を作成してそちらで検証するのがいいと説明がありました。

開発で使用したスクラッチ組織を使用してテストを行うことももちろんできますが、常に新しいスクラッチ組織で開始することをお勧めします。新しいスクラッチ組織を使用することで、すべてのソースが組織の外部に適切に置かれていることを確認できます。


新しいスクラッチ組織を作成します。

$ sfdx force:org:create -f config/project-scratch-def.json -a GeoTestOrg


ローカルのソースとメタデータをスクラッチ組織に転送します。

$ sfdx force:source:push -u GeoTestOrg


権限セットを割り当てます。

$ sfdx force:user:permset:assign -n Geolocation -u GeoTestOrg


組織にサンプルデータを読み込みます。

$ sfdx force:data:tree:import -f data/Account.json -u GeoTestOrg


組織を開きます。

$ sfdx force:org:open -u GeoTestOrg


新しいスクラッチ組織でも問題なく動きました。
f:id:tyoshikawa1106:20180106165816p:plain



今回は基本的な部分なのでその他の部分も覚えないといけないことが多そうです。ひとまずスクラッチ組織の使い方はなんとなく理解できたのでよかったです。(Sandboxみたいに本番組織のコピー組織だと思ってました。)

参考

SFDC:Lightningアプリケーションへのアップグレードを試してみました

$
0
0

Lightningアプリケーションへのアップグレードを試してみました。
f:id:tyoshikawa1106:20180110115817p:plain


Lightning Experienceのアプリケーションマネージャーページにいくとアップグレードを実行できます。
f:id:tyoshikawa1106:20180110115921p:plain


実行するとラベルやAPI名を指定できます。
f:id:tyoshikawa1106:20180110120209p:plain


アップグレードボタンをクリックすると作成完了です。
f:id:tyoshikawa1106:20180110120250p:plain


Lightningアプリケーションの場合、編集ボタンでユーティリティバーなどの設定が可能になります。
f:id:tyoshikawa1106:20180110120318p:plain


プロファイルの割り当ても実行できるので一部ユーザのみ利用可能にして運用を開始することができます。
f:id:tyoshikawa1106:20180110120402p:plain


既存のアプリケーションをLightningアプリケーションへアップグレードしたとき、Classicでも引き続き使えたか確認したかったのですが、別アプリケーションとして作成されるので問題なさそうでした。(別アプリケーションとして作成されることは途中で記載もありました。)

MEMO:Macの初期化作業と復元サーバ接続エラー

$
0
0

利用者変更などでMacBookの初期化作業が必要になるのですが、下記の手順で対応できます。

1. MacBookを起動または再起動
2. shift + option + command + Rを押しっぱなし
3. 通常の起動とは異なり地球マーク的なものが表示されてプレログレスバーが表示されるので待機
4. メニューが表示されるのでディスクユーティリティを選択してデバイスまたはボリュームを選択。
5. 選択後に消去ボタンで保存データ削除
6. 前のページに戻ってmacOS のインストールを選択。
7. インストールが完了すると初期化終了


詳細はこちら。
f:id:tyoshikawa1106:20180119201758p:plain

macOS をインストールする方法 - Apple サポート


これで初期化作業完了なのですが、作業中に下記のようなエラーメッセージが表示されました。

復元サーバーに接続できません。


原因はネットワークに接続できていないためです。画面右上のWiFiマークからいつも通りにWiFi接続設定にアクセスできるのでネットワークに接続した状態で再度macOS のインストールを実行するとエラーが解決しました。ついつい忘れるので自分用にメモです。

SFDC:Salesforce v15.0 for iOSのβ版を試してみました

$
0
0

Salesforce v15.0 for iOS ベータ版を試してみました。今までこういう機会はなかったと思うのですが、ベータプログラムに登録することで最新版を体験できるようになっているみたいです。

f:id:tyoshikawa1106:20180119214508p:plain

Salesforce v15.0 for iOS の新機能

Phone X 対応:
• 新しいエッジツーエッジ画面用に最適化されたアプリケーションを使用できる

更新された機能:
• 最も使用頻度が高い項目にすばやくアクセス。お気に入りから追加や削除も可能
• 新しい検索機能で項目の検索がよりスピーディーに
• 好きなサードパーティキーボードを使用できる (Google Gboard、Swype、Bitmoji)
• Chatter ストリームにアクセスしてカスタムフィードを取得
• ディープリンク経由で Quip アプリケーションで Quip ファイルを開ける
• さらに、バグ修正や GDPR 対応も!

重要な情報:
• Apple の無料の TestFlight アプリケーションを通じてビルドをご利用いただけます。
• TestFlight ビルドにアクセスするには、ベータプログラムにご登録いただく必要があります。このフォームを使用してベータ版にご登録ください。
• TestFlight への招待をまだ承認していない場合は、「TestFlight」でメールを検索して招待メールを承認してください。今後のビルドに関する通知を受け取るには、招待を承認する必要があります。
• ご登録いただくと、ビルドがダウンロード可能になると通知が送られ、TestFlight アプリケーションをインストールするように指示されます。
• 今後のパッチリリースに関する最新情報を知るには、ここから Trailblazer コミュニティの「Salesforce for iOS & Android」グループにご参加ください。

ベータ版の利用手順

AppleのTestFlightアプリを利用します。TestFlightは今まで名前だけ知っていて実際にどういうものかわかっていなかったのですがアプリが公開されていました。

f:id:tyoshikawa1106:20180119214816p:plain

TestFlight on the App Store


続いてメールに記載されたリンクから専用のベータプログラム登録サイトに移動して必要事項を記入します。
f:id:tyoshikawa1106:20180119215042p:plain


登録後、すぐに招待メールが届きました。
f:id:tyoshikawa1106:20180119215235p:plain


メール内のボタンをクリックするとインストール方法の記載されたサイトに移動しました。この情報をつかってiPhoneのTestFlightアプリを起動してβ版のインストールページにアクセスできます。

f:id:tyoshikawa1106:20180119220437p:plain:w250


β版のインストールページは普通のアプリと同じような感じでした。
f:id:tyoshikawa1106:20180119220547p:plain:w250


iPhone X対応が気になっていたのですが、いい感じに表示されるようになっていました。
f:id:tyoshikawa1106:20180119220750p:plain:w250


ちなみに現在のバージョンの場合は次のような感じで黒い部分が表示されてしまいます。
f:id:tyoshikawa1106:20180119220842p:plain:w250


という感じでTestFlightを使ってβ版を試すことができました。TestFlightがどういうものが覚えることができてよかったです。試してみて意外だったのですが、β版アプリはインストール済みの安定版を上書きする形でインストールされました。気になる人は検証用端末などで試すようにした方が良さそうです。

SFDC:Salesforce MVP Nominations サイトを利用してみました (2018 January 9th Verion)

$
0
0

時間が経ってしまいましたがSalesforce MVP Nominations サイトが公開されました。年に3回新しいSalesforce MVPを推薦できるサイトです。Herokuアプリで作られていました。

f:id:tyoshikawa1106:20180113223108p:plain

Salesforce Trailblazer Community


Start your nomination here!の入力欄に推薦したい人の名前を記入します。(チェックするのは米国Salesforceチームだと思うので英語での記入になります。)
f:id:tyoshikawa1106:20180113223459p:plain


Trailblazer Communityとリンクしているのだと思うのですが、入力した名前からリスト一覧が表示されます。リストから選択すると次ページが表示されるときに初期値がセットされました。リストにいない場合でもNomination を選択すると次のページに移動します。

f:id:tyoshikawa1106:20180124195726p:plain

f:id:tyoshikawa1106:20180124195924p:plain


その人を推薦する理由とTwitterやLinkedIn、Trailblazer CommunityのプロフィールページURLなどの情報を入力できます。
必要事項を入力して登録ボタンをクリックしたら申込完了です。

f:id:tyoshikawa1106:20180124200259p:plain


内容が気になったので日本語翻訳してみたところ、一人で複数人を推薦することができますと記載がありました。
f:id:tyoshikawa1106:20180124200355p:plain


英語で書く必要がありますが、入力内容としては負担の無いレベルのページ数でした。今回のサイトは2018年2月5日で締切とのことです。


SFDC:リードと取引先責任者の敬称項目の表示条件について

$
0
0

リードと取引先責任者には敬称項目が用意されています。

f:id:tyoshikawa1106:20180125204144p:plain

f:id:tyoshikawa1106:20180125204236p:plain


この継承項目はユーザの地域に依存する項目とのことです。
f:id:tyoshikawa1106:20180125204345p:plain


ユーザ情報の「地域」項目が「日本語」「韓国語」「中国語」の場合は表示されない仕組みとなります。
f:id:tyoshikawa1106:20180125204335p:plain


表示されないのは詳細ページのみで値の入力時には普通に表示されます。またレポートでの表示も可能です。
f:id:tyoshikawa1106:20180125204533p:plain


詳細はこちらです。

SFDC:Salesforce Spring '18 リリースノートの日本語版が公開されました

SFDC:プレミアセミナー『お客様やパートナー様とつながるコミュニティ機能のご紹介』に参加しました

$
0
0

Salesforceプレミアセミナー『お客様やパートナー様とつながるコミュニティ機能のご紹介』に参加してみました。1月25日(木)16:00~18:00 の二時間で、 Sales Cloud または Service Cloud をご利用中かつPremierサクセスプランを契約しているユーザ向けのセミナーです。

f:id:tyoshikawa1106:20180125155317j:plain


セミナー自体はTrailblazer Communityで知りました。
f:id:tyoshikawa1106:20180126122538p:plain


はじめはあまり気にしていなかったのですが、パートナーコミュニティをつかったプロジェクトに参加予定となったため、概要や活用事例についての話を聞けたら良いなと申込みました。先着12名までの事前登録制のセミナーだったため、申込時に今からだと難しいかなと思ったのですが意外と大丈夫でした。

セミナーのアジェンダ

当日は下記の内容についてお話を聞けました。

  • Community Cloudの概要
  • 活用事例のご紹介
  • コミュニティサイト作成デモ
  • コミュニティ推進のポイント
  • 参考情報のご案内


資料も頂けました。自分で後から確認するのにも使えるのですが、社内の他のプロジェクトメンバーにもそのまま共有できたので良かったです。
f:id:tyoshikawa1106:20180126123447p:plain

はじめに

セミナーの始めに参加者の自己紹介の時間がありました。
・名前
・Salesforceの利用目的
・本日のセミナーに期待すること

他の参加者がSalesforceをどのように利用しているかの話が聞けて良かったです。

Community Cloudの活用事例

セミナーで特に話を聞きたかった部分だった活用事例についてです。下記のサイトで確認ができるそうです。表示条件の指定ができるようになっているので、製品をCommunity Cloudに絞り込んで表示といった使い方ができることを知りました。
f:id:tyoshikawa1106:20180126124817p:plain

Customer Stories - セールスフォース・ドットコム

セミナー資料にもいくつか事例紹介があったのと実際に公開されているとある企業のコミュニティサイトを見せてもらえました。

コミュニティ作成のデモ

コレが一番メインの時間だったと思うのですが、コミュニティの作成から公開までのデモを見せてもらいました。Community Buliderのテンプレートをつかったやり方であまり詳しくない分野だったので勉強になりました。
f:id:tyoshikawa1106:20180126125402p:plain


デモで利用していたのはCustomer Service (Napili)のテンプレートです。
f:id:tyoshikawa1106:20180126125508p:plain


ラベル変更やブランド設定は簡単に動かしたことがありましたが、多言語化設定とナレッジ公開の設定については自分で試したことがない設定だったので話を聞けて良かったです。(また今度別記事でまとめてみようかと思います。)


ページのバリエーション機能のことも知ることができました。いわゆる一般ユーザ向けとプレミアユーザ向けで表示内容を変更することができる機能です。Salesforceのイベントでこういったことができる話は聞いたことがあったのですが、設定を行う機能名については初めて知ることができました。


また、Community 360という機能のことも知ることができました。コミュニティに公開しているナレッジ記事の参照記録を取ることができる機能です。これで顧客が記事を参照後に解決しなかったことで問い合わせがあった際にサポート担当はその記録を確認して対応を行うことができるようになります。


Community 360という名前自体はどこかで見たことがあったかもしれませんが、特に必要にならなかったため詳細を調べたことはありませんでした。今回のセミナーで具体的な使用例と一緒に話を聞くことができて良かったです。


他にはコミュニティライセンス無くてもコミュニティ作成できるようになった話も聞けました。現時点では特に使うことは無い気がしますが、ログイン不要なコミュニティサイトを構築する必要ができたときに検討したいと思います。セミナー中に聞けた利用時のちょっとした注意点としてはページビューの上限について気をつけて下さいとのことです。(Force.comサイトでも同様の制限です)


Q&Aの時間もありました。他の参加者からの質問だったのですが、ナレッジのライセンスの話で勘違いしていたことがあったので勉強になりました。ナレッジのライセンスは記事の参照のみならライセンス不要で記事の登録を行うユーザにはライセンスを付与する必要があるそうです。デモで見せてもらったコミュニティとナレッジの組み合わせが非常に便利そうだったので少し導入を検討できないかなと思いました。

コミュニティ立ち上げ時のポイント

最後にTrailblazer Communityの立ち上げのポイントの話を聞かせてもらいました。Salesforce社の担当者がどのようにコミュニティを大きくするため試行錯誤したかが聞けておもしろかったです。


大きな会社なので運営メンバーも多いのかなと思っていたのですが、アメリカだけで約9名、日本やその他の国を合わせても20名行かないぐらいのメンバーで運営しているそうです。通常はあまり聞く機会の無い運営時の失敗談なども聞くことができました。コミュニティ運営ではないのですが自社への定着化の点で悩んでいる部分で近い話があったのでいろいろと参考になりました。

さいごに

今回はじめてPremierサクセスプラン契約ユーザ向けのセミナーに参加してみました。Premierサクセスプラン(ずっとプレミアサポートの名前でおぼえてました。)はユーザライセンス数が多いと料金も大きくなってしまうのですが、こうしたセミナーや機能導入についての相談、サポートセンターの利用ができるので導入時やユーザ数が少ない企業は契約しておくとメリットが大きいのかなと思いました。

SFDC:Success Cloudのイベントカレンダーページがリニューアルされました

$
0
0

Success Cloudのイベントカレンダーページがリニューアルされたみたいです。

f:id:tyoshikawa1106:20180204130335p:plain

Find Salesforce Webinars, Events and Videos - Success Cloud


過去に見た時は日本のイベントがあまりなかった気がしたのでそれほど気にしたことがなかったのですが、プレミア自習室やウェブセミナーのスケジュールが確認しやすくて便利でした。

f:id:tyoshikawa1106:20180204130527p:plain


ユーザグループ側のイベントも表示されていましたが、そちらは下記のサイトでも確認可能です。
f:id:tyoshikawa1106:20180204130725p:plain

Salesforce Trailblazers Community

SFDC:Salesforceの製品紹介動画

$
0
0

Trailblazer CommunityでSalesforceの製品紹介動画とその概要が共有されていました。社内で説明する必要があるときに便利かもしれません。

Trailblazer Community


確認したのはSales Cloudだけですが日本語動画になっているみたいです。

Sales Cloud のご紹介 - 概要デモ

世界No.1の営業支援システムであるSales Cloudを、見込み客の獲得から、受注、リピートまでどのように活用するのか、さらに人工知能(Einstein)によって営業がどう変わるのかを確認いただける動画です!

Pardot のご紹介 - 概要デモ

PardotはSalesforceとシームレスにつながり、マーケティングと営業の強固な連携を可能にします。MA+SFA+Analyticsの組み合わせでB2B Marketingを行うべき理由を掴んでいただけます。

Salesforce CPQ のご紹介 - 概要デモ

CPQはSales Cloudと合わせて活用する、見積ソリューションです。お客様の要望に合わせてカスタマイズすることができます。商品構成が複雑、SKU数が多い企業で大きな効果をあげることができます。

Sales Cloud PRM - 概要デモ

PRM=Partner Relationship Management

代理店やパートナーとつながるコミュニティポータルを使えば、社内外問わず常に最新の情報を共有しながらビジネスを進めることができます。

Quip のご紹介 - 概要デモ

Salesforceがここ最近とても推しているコラボレーションプラットフォームです。
Quipは無料トライアルから気軽に始めていただけます!!

https://quip.com/landing/salesforce-signup

Viewing all 1438 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>