【ブログ新URL】
https://base.terrasky.co.jp/category/tech_blog
今後、テラスカイの情報発信の場として『TerraSky Base』にTech blogや製品ブログをはじめ、会社にまつわる様々な情報発信を行っていきます。
ご愛読頂けますと幸いです。
https://base.terrasky.co.jp/
なお、RSS登録している方は、お手数ですが、RSSリーダーに再登録をお願いします。
https://base.terrasky.co.jp/category/tech_blog.rss
みなさん、こんにちは。今年からテラスカイにジョインしました吉清です。
思い起こせば30年近くPMをやってきました。職歴としては世界一のDBベンダー、日本一のSIer、世界一のCRMベンダーなどを渡り歩いてきました。開発規模も大きいものでは数百人月くらい、幾つかの伝説的なプロジェクトもやらせて頂きました。開発手法もウォーターフォールからアジャイルまで何でもやってきており、日々業界の変化を楽しんでいる現場大好きエンジニアです。
技術寄りではない、普段のTechBlogとは違った観点で今日は書いていきたいと思います。
巷ではアジャイルという開発手法がよく聞こえてきますが、浸透していかない状況もあります。それではどのような課題があるのでしょうか。
・ユーザ企業はアジャイルのようなスピード感を持って開発したいが自社で開発要員がいないため、開発ベンダー依存からなかなか脱却できない。
・開発スタイルがウォーターフォール型と大きく異なり、成果物に対して検収するわけではなく、作業に対して対価を支払う形式のため、日本で主流の請負契約とは非常に相性が悪い。
アジャイル型開発が急速に普及してきている欧米はユーザ企業にIT技術者が多く在籍し、契約を挟まない開発をすることで、上記の課題にとらわれることなく非常にスピーディーな開発が可能となっています。
課題がありつつも時代はアジャイル開発に向かっており、海外企業と戦うことが多い日本企業はアジャイル開発にシフトしていかないとスピードで負けて国際競争力を失うことになりかねません。
ユーザ企業と開発ベンダーが合意出来る契約形態、ジョイントベンチャーのような形を作ることが急務と言えます。
IPAからも非ウォーターフォール型開発の普及要因と適用領域の拡大に関する調査報告書が出ていますので、参考にしてみてください。
では本題のアジャイル時代のプロジェクト管理とはどのようなものでしょうか。
PMBOKではアジャイルの考え方を取り入れた「PMBOKソフトウェア拡張版」もリリースされており、マネジメント領域が定義されてきています。
ウォーターフォールのような計画駆動型(予測型)の開発では、計画を事前にしっかり作り、WBSでスケジュールを管理し、各チームから上がってきた課題を管理し、開発メンバーの稼働、コストを管理し、工程ごとの作成物の品質を管理することがPMの仕事でした。いわゆるQCD管理です。
アジャイルのような適応型ソフトウェア開発は、未来を予測することは困難という前提でおこないます。
そのため計画立案、実行を重視するのではなく、臨機応変に対応することが必要です。ただし無計画ではなくイテレーションと呼ばれる2週間程度を1サイクル(要件確認~テスト)として複数回繰り返すことで、ソフトウェア開発をおこなうようにします。
そこで求められる主なプロジェクト管理とは以下になります。
PMBOKの知識エリア |
具体的な作業 |
統合マネジメント |
プロジェクトマネジメント計画書作成 プロジェクトの作業監視、コントロール 変更管理(発生した変更への積極対応、プロダクトバックログへのインプット) |
スコープ・マネジメント |
優先順位付きプロダクトバックログからのイテレーション計画作成 |
タイム・マネジメント |
タイムボックスの設定 タスクボード作成:筆者は無料のTrelloを使用しています |
コスト・マネジメント |
イテレーションの回数、優先順位付きのプロダクトバックログ設定 |
品質マネジメント |
品質を落とさない短期開発のための品質計画の策定と品質保証活動の実施 |
人的資源マネジメント |
プロダクトオーナー、スクラムマスターの選定 アジャイルチーム編成(コミュニケーションパス数を考慮すると1チーム9名以下が望ましい) |
コミュニケーション・マネジメント |
ユーザ企業との密なコミュニケーション チーム間コミュニケーション |
リスク・マネジメント |
リスク特定 リスクコントロール |
ステークホルダー・マネジメント |
ステークホルダーを効果的に関与させる |
作業だけ見ると、過去に身に着けた基本スキルは変わらずに、やり方を変化させることでプロジェクト管理は行えそうに思えないですか。もちろんスピード感を持った対応が必要にはなりますが。
ウォーターフォールで育ったPMも積極的にアジャイル開発をおこない、管理手法を身に着け、それを周りに展開していくことを期待しています。
今までのようにユーザ企業が要件をベンダーに伝えればあとは開発をしてくれるというやり方ではアジャイルに向きません。デジタル・トランスフォーメーション時代に備えるためにも、ユーザ企業自らが主体的に開発をリードする欧米型に変化するか、ジョイントベンチャー方式の自社と開発ベンダーを並列化するような体制を作れるかがカギとなります。そのためにはまずは小さなアジャイル型開発を成功させ、成功事例を徐々に展開し社内にウエーブを起こすことが必要と思われます。その成功事例をテラスカイがお手伝い出来ると信じています。
]]>
トランザクションセキュリティというこの機能、元々は2要素認証の調査をしてる時に、「これは便利かも!?」と思い、ちょっと触ってみようと思った次第です。
ちなみに調査というのは、
「Salesforce Authenticatorにて毎度認証するのは不便なので、特定のIPアドレスからのアクセスの場合は認証をスキップしたいんだなあ」
的なことをやろうとして、こちらのページのパッケージを入れたりしたんですが、現在(Summer '17)では「セッションの設定>(ID 検証)信頼済み IP アドレスからのみ許可」にチェックを入れるだけで出来てしまったりします。素晴らしい!
トランザクションセキュリティについてヘルプに記載されている概要は、
トランザクションセキュリティは、設定したポリシーに基づいてイベントを監視します。これらのポリシーは組織内のイベントに適用され、特定のイベントの組み合わせが生じた場合に実行するアクションを指定します。ポリシーがトリガされると、アクションが実行され、必要に応じて通知を受信できます。
とのこと。
イベントって何?アクションって何?ということで、ヘルプや設定画面を確認しますと、設定出来る内容としては
カスタムポリシー(カスタムトランザクションセキュリティポリシー) + Apex ポリシー(ApexTxnSecurity.PolicyCondition インターフェースを実装したApexクラス)で構成
カスタムポリシーは、イベント・リソース名・リアルタイムアクション・通知等を設定する(選択可能な内容は下記表参照)
イベントの種別 | リソース名 | リアルタイムアクション | 通知 |
Login | ― | ・None ・ブロック ・2 要素認証 ・ログインするためにセッションを終了 |
・アプリケーション内通知(Salesforce1のみ) ・メール通知 |
Entity | Chatter メッセージ | ・None ・ブロック ・ユーザを凍結 |
|
アイデア | |||
フィードコメント | |||
フィード項目 | |||
質問 | |||
クライアントブラウザ | ・None | ||
ログイン IP | |||
認証セッション | |||
認証プロバイダ | |||
DataExport | Account | ・None ・ブロック ・2 要素認証 |
|
Case | |||
Contact | |||
Lead | |||
Opportunity | |||
Access Resource | レポート & ダッシュボード | ・None ・ブロック ・2 要素認証 |
|
接続アプリケーション |
といった感じですかね。
設定の詳細については、ヘルプやtrailheadを参照ください。
なお、Apex ポリシーのサンプルコードも色々あります。こちらのヘルプやリファレンスを見るとより何が出来るかのイメージが湧くかと思います。
例えばこんな要件にも利用出来たりもします(あるかわかりませんが・・)。
レポートのエクスポートはシステム管理者以外も使用する。(プロファイルの「レポートのエクスポート」を有効にする必要がある)
だけど、Contactだけはシステム管理者以外のユーザには、レポートやDataloader等でエクスポートさせたくない。
実装内容(及び結果)はこんな感じになります。
・Apexポリシー
global class ExportPolicyCondition implements TxnSecurity.PolicyCondition { public boolean evaluate(TxnSecurity.Event e) { return 'システム管理者' != [Select Profile.Name From User Where Id = :e.userId].Profile.Name; } }
・カスタムポリシー
・レポート実行結果
AccountやLeadのカスタムポリシーを作れば、同じApexポリシーが使えますね。
今後、DataExportの対象にカスタムオブジェクトも選択出来るようになると更に良いですね。
トランザクションセキュリティの利用にあたって、いくつか制限や注意点がありましたので少し触れてみようかなと。
まず、評価結果が「true」または「false」のどちらでも、DML 操作はロールバックされるそうです。
DMLがダメならメール送信はどうなんだろうと、SingleEmailMessageを確認してみましたが、こちらも「Too many Email Invocations: 1」のエラーに抵触してしまい、送信できませんでした。
ということで、下記のように非同期で試してみるとDMLもメール送信も正常に動作しましたが、評価結果が「true」の場合のみ実行されるという結果になりました。
global class ExportPolicyCondition implements TxnSecurity.PolicyCondition { public boolean evaluate(TxnSecurity.Event e) { createLog(JSON.serializePretty(e)); sendMail(JSON.serializePretty(e)); return 'システム管理者' != [Select Profile.Name From User Where Id = :e.userId].Profile.Name; } @future private static void createLog(String s){ insert new EventLog__c(logDetail__c = s); } @future private static void sendMail(String s){ Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); mail.setTargetObjectId(UserInfo.getUserId()); mail.setSubject('TxnSecurity.PolicyConditionをメールしてみる'); mail.setPlainTextBody(s); mail.setSaveAsActivity(false); Messaging.sendEmail(new List<Messaging.Email> { mail }); } }
とすると、非同期でレコードを作成し、戻り値を一律「true」、アクションを「None」とすれば、レポートをブロックさせずにエクスポート履歴を取ることとかも出来そう!と思ったのですが‥、アクションを「None」とすると、評価結果が「false」の場合と同じく何も動作しない‥。残念。
じゃあ、「None」てどういう時に使うんだろうなあと少々疑問は残りますが、新しめの機能としてはあるあるですかねー。今後に期待です。
他にはですね、同じイベントとリソースの組み合わせは、複数作成すること出来ないという制限がありました。
つまり、一つのイベントとリソースの組み合わせに対し、アクションを使い分けることは出来ないということなんですね。
最後にも一つ、当然なんですが、いい加減なログイン制御のカスタムポリシーを有効化してしまうと、システム管理者でもログイン出来なくなります。結構ドキドキしますのでご注意ください。
それでは。
]]>こんにちは。
テラスカイの八木です。
さっそくですが、皆さんSalesforceを触っているときに文字コード意識されていますか?
Salesforce単独で使用している場合はあまり意識しなくても問題はないかも知れませんが、他システムとの連携(特に基幹系など)があると意識せざるを得ませんね。
今回は文字コードについていくつかパターンを試してみたいと思います。
Salesforce内部ではUTF-8として処理されています。
UTF-8である文字(例として㊑)を実際に標準画面で登録してみましょう。
問題なく登録できましたね。
せっかくUTF-8なのでサロゲートペア(例として𩸽)も登録してみましょう。
こちらも問題なく登録できましたね。
ちなみにどの文字コードに対応しているかはWindowsならIMEパッドで確認できます。
㊑について、Shift_JISがハイフンとなっていることが分かると思います。
いえいえそんなことはありません。
以下のようにいくつかの設定で文字コードを変更することができます。
<apex:page contentType="text/html;charset=Shift_JIS" showHeader="false">
ただし、標準画面については文字コードについて設定する箇所がないので、UTF-8以外に対応するのは難しいと思われます。
さきほど登録したUTF-8の文字をShift_JISにエンコードしてレポート出力すると「?」になっていると思います。
このままでは文字化けした状態になってしまうので、出来ればSalesforce登録時にエラーになると助かりますね。
Salesforceの設定ではShift_JISのみ許可するなどはできないと思われますので、以下のようなチェック処理を作成し、トリガなどで呼び出すと良いと思います。
public with sharing class DemoCheckUtility { /** * 許可された文字かどうか */ private static String ENCODING_SCHEME = 'Shift_JIS'; public static Boolean isAllowedCharacters(String sentence) { if (String.isBlank(sentence)) { return true; } // 指定文字コードに変換 String encode = EncodingUtil.urlEncode(sentence, ENCODING_SCHEME); String decode = EncodingUtil.urlDecode(encode, ENCODING_SCHEME); // 変換前後で比較 if (sentence != decode) { return false; } return true; } }
チェック処理を適用したらどうなるか見てみましょう。
さきほどの文字登録の「制限あり項目」に上記チェック処理を適用したので、UTF-8の文字を登録してみます。
きちんとエラーになっていますね。これでSalesforceに登録する時点で連携できない文字を除外できるのではないでしょうか。
他システムとデータを連携した際に「?」と表示されるとドキっとしますね。
そうならないように事前に文字コードの知識を深めて作業できると良いですね。
皆さんこんにちは
全てのナレッジを愛し、全てのナレッジに愛された男!になりたいと思ってから、早半年...
ナレッジをこよなく愛する仲です。
ナレッジ好きな方であれば待ちに待ったLightning KnowledgeがSummer'17で正式リリースされました。
今回のブログでは正式にリリースされた「Lightning Knowledge」についてリリースノートの中からいくつかピックアップして機能をご紹介したいと思います。
Summer'17のリリースノートには下記のように記載があります。
Lightning Knowledge が正式にリリースされました。レコードホームページのカスタマイズ機能、ファイルオブジェクトへのレコードタイプと関連ファイルのインポート機能、Lightning Experience での Knowledge 設定、コミュニティのサポートなどが提供されます。この変更は Lightning Experience にのみ適用されます。
では早速正式版になったLightning Knowledgeを見てみましょう!
今まではClassicで設定を変更する必要がありましたが、Lightning Experienceで設定変更ができるようになりました。
切替が不要になってよいですね!
このリリースで、ビューの条件に言語と公開状況を指定する必要がなくなりました。
ただし、公開状況を条件に指定しない場合は公開の条件がデフォルトで適用されるため
公開状況をまとめて表示するビューは設定できません。
ベータ版の時と比較すると設定できる項目が増えていますね。
(ソースを見るとCKEditorのパスの記載があるのでClassicに合わせて戻した感じでしょうか)
ベータ版の場合
クラシックの場合
Lightning Knowledgeを触ってみて、いくつか気になる点を見つけました。
いくつかレコードを参照したのですが、最近参照したデータにはレコードが表示されませんでした。
ベータ版では下記のような表示が出ていましたが、メッセージは変わっているようです。
記事の編集ボタンをクリックして編集画面に遷移しますが、リッチテキストの場合はさらに編集ボタンをクリックして編集する流れになっています。
保存ボタンを押すと、レコードが保存される流れになっています。
今回正式リリースとなったLightning Knowledgeについてピックアップしてご紹介しましたが、リリースノートにはLightning Knowledge に関する考慮事項として下記の記載があります。
現在、Classic Knowledge に複数の記事タイプがある場合は Lightning Knowledge を有効にできません。
Lightning Knowledge では、複数の言語と翻訳はサポートされません。現在、組織で複数言語が有効になっている場合は Lightning Knowledge を有効にできません。
Lightning Knowledge はデータカテゴリ数が 300 未満の場合にのみ使用することをお勧めします。これより多い場合は、パフォーマンスが低下する可能性があります。
記事タイプを1つにすることや、データカテゴリを300未満にすることは大変かもしれませんが、記事の管理についてはクラシックよりも格段にやりやすいので切り替えるメリットは十分にあると思っております。
次回のバージョンアップでどんな機能が追加されるのか、今からとても楽しみです。
]]>こんにちは。鍬田です。
今回はTwilioとSalesforceを組み合わせてコールセンターを構築してみたいと思います。皆様の会社ではコールセンターを設置していますか?
コールセンターの役割は営業、受注、アフターサポートなど多岐に渡りますが、いずれも直接顧客とコンタクトする重要なチャネルとなっている事でしょう。
また、顧客データベースと共に、過去の営業活動や応対履歴を記録しておく事で、応対品質の向上が期待できます。
しかし、このようなシステムの構築はPBX設置や回線工事などを伴い気軽に試すにはハードルが高いものでした。
TwilioはPBXや回線をサービスとして提供しているので、一般的なWeb関連のスキルがあれば連携を行う事が出来ます。
今回は顧客管理システムと音声基盤の連携を受電機能に絞って紹介します。手順は以下の通りです。
通話機器はブラウザフォンを使用します。
開発者向けのプラットフォームでTwilioのAPIを使用する事で、コミュニケーション手段を拡張できます。
電話/SMS/ビデオ/チャットなど対応可能なインターフェイスは多岐に渡ります。電話機能としてIVR、通話録音用のAPIもあります。
個人的には、各種言語用ドキュメントや簡潔なAPIも整備され、さらにはSalesforce向けのSDKまである部分がとてもよい印象です。
※無料サインアップ > 自身の情報を入力
Twilioアカウント取得後に以下の手順で進みます。
Twilioからの着信イベントを受け取るために、Twilioからアクセス可能なエンドポイントの設置が必要となります。
今回はHeroku上にエンドポイントを作成します。使用したソースコードはこちらをご覧ください。
Node.jsでexpressのテンプレートを使用してサクっとサーバを立ち上げます。
主な実行環境やバージョンは以下の通りです。
今回は着信確認のプログラムである為、実用にはセキュリティ面や複数人で使用する場合のケアが必要です。
Herokuへのアプリのデプロイ方法は割愛しますが、10分で分かる!使える!Force.com Canvasが参考になります。
ポイントとなるコードを解説します。
No1.で設定したWebfookを作成します。今回はTwilioで電話の着信イベントが発生時に call/recieve にPOSTリクエストの送信設定をしました。
まずは、IVR(自動音声応答)の定義する為のTwiMLの作成を行います。
ユーザーの Twilio 番号に音声通話や SMS が着信すると、Twilio はこの Twilio 番号に関連付けられた URL を検索し、この URL 宛にリクエストを送信します。 Twilio はこの URL で TwiML の命令を読み込み、通話を録音する、メッセージを再生する、キーパッドで数字をダイヤルするようアナウンスを流すなど、次の動作を判断します。
たとえば、次のサンプルでは短いアナウンスを流した後、発信者の声を録音します。
<?xml version="1.0" encoding="UTF-8"?> <Response> <Say voice="woman">Please leave a message after the tone.</Say> <Record maxLength="20" /> </Response>TwiML は HTML とよく似ています。 一度に1つの TwiML 文書だけが実行されますが、TwiML 文書を複数リンクさせれば、複雑な音声処理アプリケーションを作ることができます。
Twilio 番号からその他の番号への発信通話も、着信通話と同じように、TwiML を用いて制御します。 発信通話の最初の URL は、Twilio REST API リクエストのパラメーターとして渡されます。
call.js -> call/recieve
/** IVRに誘導 **/ router.post('/recieve',twilio.webhook({validate: false}), function(req, res, next) { var twiml = new twilio.TwimlResponse(); var actionUrl = process.env.APP_BASE_URL + '/call/recieve/select_menu'; //チャネル名 var clientDialer = function(dial) { dial.client("support_agent"); }; var opt = { voice: 'woman', language: 'ja-jp' //日本語 }; //自動音声ガイダンスの設定 twiml.say('こちらは、テラスコです。', opt) .gather({ action: actionUrl, method: 'GET', timeout:20 },function () { this.say('請求に関するお問い合わせは1番を',opt) .say('オペレータと通話を希望されるかたは2番を',opt) .say('その他のお問い合わせは3番を',opt) .say('入力後シャープを押してください',opt) }); //TwiMLをtwilioに送信する res.send(twiml.toString()); });
なんと、日本語も解釈して読み上げてくれます!
call/recieve/select_menu でIVR(自動音声応答)の選択結果に応じたTwiMLを返します。
call.js -> call/recieve/select_menu
/**IVR 選択判定結果処理**/ router.get('/recieve/select_menu',function(req, res, next) { var pushNumber = req.query.Digits; var twiml = new twilio.TwimlResponse(); var opt = { voice: 'woman', language: 'ja-jp' }; var clientDialer = function(dial) { dial.client("support_agent"); } if(pushNumber === "1"){ twiml.say('おてすうですが、請求書に関しては03,00,00,00,00へお掛け直しください', opt); } if(pushNumber === "2"){ twiml.dial({ callerId : convertJpPhoneFormat(req.query.From), record: true }, clientDialer); } if(pushNumber === "3"){ twiml.say('その他のお問合せに関しては現在使われておりません。もう一度お掛け直しください。', opt); } res.send(twiml.toString()); });
call.js -> call/create_token ではチャネル名や認証情報を設定しています。
var appSid = process.env.TERRA_CALL_CENTER_SID; var accountSid = process.env.TWILIO_ACCOUNT_SID; var authToken = process.env.TWILIO_AUTH_TOKEN; var twillioPhoneNum = process.env.TWILIO_PHONE_NUMBER; var capability = new twilio.Capability(accountSid, authToken);
capability.allowClientOutgoing(appSid); capability.allowClientIncoming("support_agent");
var token = capability.generate(600); router.post('/', function(req, res, next) { res.writeHead(200, {'content-type': 'text/json' }); res.end(JSON.stringify({ token : token}) ); });
Personal App > 今回作成したアプリ名 > Settings > Reveal Config Var
※電話番号が「050-1234-5678」の場合は、「+815012345678 」を設定
HTML、CSS、Javascriptだけで作れます。デザインの部分はLighting-Design-Systemを使用しています。
試しにソフトフォンを用意してみました。
phone.ejs
コールセンターの定義用にXMLを作成します。
ポイントは「item sortOrder="02"」のノードにソフトフォンのURLを設定している部分です。
<callCenter> <section sortOrder="0" name="reqGeneralInfo" label="General Information"> <item sortOrder="0" name="reqInternalName" label="InternalName">DemoOpenCTI</item> <item sortOrder="1" name="reqDisplayName" label="Display Name"> テラコールセンターデモ</item> <item sortOrder="2" name="reqAdapterUrl" label="CTI Adapter URL">https://<MY_APP>.herokuapp.com/phone</item> <item sortOrder="3" name="reqUseApi" label="Use CTI API">true</item> <item sortOrder="4" name="reqSoftphoneHeight" label="Softphone Height">300</item> <item sortOrder="5" name="reqSoftphoneWidth" label="Softphone Width">500</item> </section> </callCenter>
コールセンターのSalesforceの設定については、"おしえて!OpenCTIアダプタ設定"にも記載があるので参考にしてください。
ソフトフォンがサイドバーに表示されているか確認します。
電話機からTwilioで取得した電話番号にcallしてみます。
ピッポッパッ.........トゥルルル.....掛かりました!!
音声ガイダンスに従い、電話機の「2」をプッシュします。
着信成功です!受信ボタンを押下してみます。
発信機能もまた機会があれば紹介したいと思います。
TwilioとSalesforceというクラウドサービスを掛け合わせる事で、時間と労力を抑え顧客管理システムと連携した受電機能をスピーディに構築できました。
クラウドの化学反応の一端をお見せできたかと思います。
]]>みなさんこんにちは。社内でHeroku推進活動をしている溝井です!
ブログでも過去数回Herokuに関する記事を投稿しております。
当ブログはSalesforceの内容を期待してご覧になられた方がほとんどかと思います。
そこで今回はHerokuとSalesforceどちらかでも利用可能なAI、
「Einstein Vision」を取り上げてみたいと思います!
Herokuに興味がない方も是非最後までお付き合い頂ければと思います。
また非常に長い記事になってしまったので、雰囲気だけつかみたい方は、
後半の「動作確認」セクションのGIFイメージやサンプルアプリをご確認頂ければと思います!
以下にあるようにセールスフォース・ドットコム社が提供する画像認識に関するAPI群となります。
Einsteinのコンセプトどおり簡単にAIの機能を利用することができます。
この度セールスフォース・ドットコムは、パワフルな新しいAPI群である「Einstein Vision」の提供を開始します。これにより、Force.comやHerokuの開発者といったあらゆるスキルセットの方々が、CRMに画像認識を活用したり、AI(人工知能)を組み込んだアプリの開発を迅速に行うことを可能にします。セールス、サービス、マーケティング部門を横断したエンドユーザーがよりスマートに、さらにプレディクティブに業務を行えるようにするために、開発者はあらかじめ学習済みの画像認識器を活用したり、あるいは自身で認識器をトレーニングして様々な画像認識の課題を解決することが可能になります。
2017 Salesforce Einsteinのカタチ Vol.1 Einstein Visionが登場 画像認識技術がより身近により引用
先日開催されたHerokuのイベント「Heroku Meetup #17 Heroku Strike」に参加してきました。
その時の懇親会LTで以下のサンプルアプリのデモがとてもおもしろかったのでご紹介させて頂きます。
ここから先はHerokuアカウントがある場合の前提で進めさせて頂きます。
サンプルアプリのGithubに遷移します。
ページ中程のHerokuボタン「Deploy to Heroku」をクリック。
アプリ名を入力して「Deploy」をクリック。
以上!
上記作業だけであっという間に自分のHerokuアカウントにサンプルアプリがデプロイされます。
「View」ボタンで登録されたアプリを起動してみましょう。
サンプルアプリが利用可能になりました。
試しに画像をアップロードしてみます!
サンプルアプリでは「Einstein Vision」が提供している予測・解析モデルの「General Image Classifier」というモデルが利用されています。
モノを対象とした画像認識を行い、予測結果が返却されます。
今回は手元にあった腕時計の画像をアップロードしてみました。
結果は「analog clock」の可能性が49%でほぼ正解です!なかなかおもしろいです!
ではアプリの詳細を確認していきたいと思います。
Herokuボタンでデプロイする際にも表示されていましたが、サンプルアプリには2つのアドオンが利用されています。
アドオンが登録されたタイミングでアプリの環境変数に以下の値がセットされています。
ここで重要なのは「EINSTEIN_VISION_ACCOUNT_ID」と「EINSTEIN_VISION_PRIVATE_KEY」となります。
上記のアドオンを追加したタイミングで「Einstein Vision」を利用するためのアカウント情報が作成され、
環境変数に登録されているということになります。
サンプルアプリで作成されたアカウントを用いて、Einstein VisionのAPIを触っていこうと思います。
参考:リファレンス
リファレンスを読み進めていくとApexからEinsteinを利用する手順が記載されていますが、今回はHerokuで利用するための手順を抜粋してご紹介させて頂きます。
token取得用サイトでHerokuアプリに設定された環境変数の「Einstein Vision」のアカウント情報からアクセストークンを発行します。
まずはHerokuアプリの環境変数を確認します。
上記で確認したHerokuアプリの環境変数の情報を元に、
token取得用サイトで以下の項目を設定して「GET TOKEN」ボタンをクリックします。
設定項目 | 設定値 |
Email or Account ID | Herokuアプリの環境変数「EINSTEIN_VISION_ACCOUNT_ID」の値 |
Private Key | Herokuアプリの環境変数「EINSTEIN_VISION_PRIVATE_KEY」の値 |
Expiration in Mins | 任意の分数 |
アクセストークンが取得できました。
ここからはWindowsでGitをインストールする際に利用できるようになるGit BASHを利用して操作をしていきます。
またレスポンス結果の値は見やすいように一部整形しております。
コマンドラインの操作でアクセストークンを多用するので変数化しておきます。
$ mytoken=先程取得したアクセストークン
以下のコマンドで設定した変数が反映されているか確認できます。
$ echo $mytoken
ではさっそく以下のAPIにて現在のデータセットの一覧を確認してみます。
$ curl -X GET -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" https://api.einstein.ai/v1/vision/datasets
まだデータセットを作成していなので1件もありません。
{ "object": "list", "data": [] }
今回はロゴ画像をアップロードしたら、会社のロゴなのか、製品のロゴなのかを判定してくれる独自の予測・解析モデルを作ってみたい思います。
以下の様な構成のZIPファイルを用意します。
icon
├terrasky
└terrasky-products
※「terrasky」フォルダには弊社のロゴ画像を40枚以上格納
※「terrasky-products」には弊社製品のロゴ画像を40枚以上格
次の手順で利用するAPIにより、
ルートディレクトリの「icon」がデータセット名となり、
各ディレクトリの名称がラベルとなります。
最低限2つのラベルが必要で、一つのラベルには40以上のサンプルが必要となります。
はじめは用意するZIPファイルの構成やAPIの仕様がわからず苦戦しましたが、
以下のウェビナーの資料が大変参考になりました。
Create a Dataset From a Zip File Asynchronously
引数の「data」には「icon.zip」を格納している任意のパスを指定して下さい。
$ curl -X POST -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" -H "Content-Type: multipart/form-data" -F "data=@C:\path\to\icon.zip" https://api.einstein.ai/v1/vision/datasets/upload
以下のようなレスポンスが返ってきます。
{ "id": 1005089, "name": "icon", "createdAt": "2017-06-27T07:23:48.000+0000", "updatedAt": "2017-06-27T07:23:48.000+0000", "labelSummary": { "labels": [] }, "totalExamples": 0, "available": false, "statusMsg": "UPLOADING", "type": "image", "object": "dataset" }
上記の"available":false,"statusMsg":"UPLOADING"とあるように上記のAPIは非同期処理のため、まだデータセット作成が完了していない状況となります。
データセットのidはこの後も利用するため、変数化しておきます。
$ datasetid=1005089 $ echo $datasetid
$ curl -X GET -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" https://api.einstein.ai/v1/vision/datasets
以下の様なレスポンスが返ってきます。
{ "object": "list", "data": [ { "id": 1005089, "name": "icon", "createdAt": "2017-06-27T07:07:41.000+0000", "updatedAt": "2017-06-27T07:07:43.000+0000", "labelSummary": { "labels": [ { "id": 24066, "datasetId": 1005089, "name": "terrasky", "numExamples": 40 }, { "id": 24067, "datasetId": 1005089, "name": "terrasky-products", "numExamples": 41 } ] }, "totalExamples": 81, "totalLabels": 2, "available": true, "statusMsg": "SUCCEEDED", "type": "image", "object": "dataset" } ] }
上記のとおり、"available":true,"statusMsg":"SUCCEEDED"となり準備が完了致しました。
モデル名を設定する必要があるため変数化して設定しておきます。
$ modelname="Icon Model" $ echo $modelname
トレーニングの処理を実施します。
$ curl -X POST -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" -H "Content-Type: multipart/form-data" -F "name=$modelname" -F "datasetId=$datasetid" https://api.einstein.ai/v1/vision/train
以下の様なレスポンスが返ってきます。
{ "datasetId": 1005089, "datasetVersionId": 0, "name": "Icon Model", "status": "QUEUED", "progress": 0, "createdAt": "2017-06-27T07:40:20.000+0000", "updatedAt": "2017-06-27T07:40:20.000+0000", "learningRate": 0, "epochs": 0, "queuePosition": 1, "object": "training", "modelId": "RT5FVCCFFTZRXQK5I2PCSBPZZY", "trainParams": null, "trainStats": null, "modelType": "image" }
こちらも非同期処理のため、実行直後のステータスは"status":"QUEUED"となり、完了まで少し時間がかかります。
私の場合は5~10分もかからなかったかと思います。
この時、modelIdが返却されているため、変数化しておきます。
$ modelId=RT5FVCCFFTZRXQK5I2PCSBPZZY $ echo $modelId
$ curl -X GET -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" https://api.einstein.ai/v1/vision/train/$modelId
完了していないと以下の様に"status":"RUNNING"のままとなります。
もう少し時間をおいて上記のコマンドを実行してみます。
{ "datasetId": 1005089, "datasetVersionId": 2613, "name": "Icon Model", "status": "RUNNING", "progress": 0.67, "createdAt": "2017-06-27T07:24:49.000+0000", "updatedAt": "2017-06-27T07:25:57.000+0000", "learningRate": 0.001, "epochs": 3, "object": "training", "modelId": "RT5FVCCFFTZRXQK5I2PCSBPZZY", "trainParams": null, "trainStats": null, "modelType": "image" }
完了していると以下の様なレスポンスが返ってきます。
{ "datasetId": 1005089, "datasetVersionId": 2614, "name": "Icon Model", "status": "SUCCEEDED", "progress": 1, "createdAt": "2017-06-27T07:40:20.000+0000", "updatedAt": "2017-06-27T07:41:46.000+0000", "learningRate": 0.001, "epochs": 3, "object": "training", "modelId": "RT5FVCCFFTZRXQK5I2PCSBPZZY", "trainParams": null, "trainStats": { "labels": 2, "examples": 81, "totalTime": "00:01:23:120", "trainingTime": "00:01:21:335", "earlyStopping": false, "lastEpochDone": 3, "modelSaveTime": "00:00:01:781", "testSplitSize": 6, "trainSplitSize": 75, "datasetLoadTime": "00:00:01:785" }, "modelType": "image" }
いよいよトレーニングした独自の予測・解析モデルを用いた画像認識処理を実行します!
このテストでは弊社のロゴ画像をアップロードしてみます。
※引数の「sampleContent」には予測対象の画像ファイルの格納先を指定して下さい。
$ curl -X POST -H "Authorization: Bearer $mytoken" -H "Cache-Control: no-cache" -H "Content-Type: multipart/form-data" -F "sampleContent=@C:\path\to\terrasky-icon.png" -F "modelId=$modelId" https://api.einstein.ai/v1/vision/predict
結果は以下のとおりとなり、terraskyでラベルである可能性が「0.99955267」、terrasky-productsである可能性が「4.4736138E-4」となりterraskyラベルに限りなく適した画像であると認識されました!
{ "probabilities": [ { "label": "terrasky", "probability": 0.99955267 }, { "label": "terrasky-products", "probability": 0.00044736138 } ], "object": "predictresponse" }
サンプルアプリのREADME.mdにも記載されていますが
サンプルアプリは自分で作成したカスタムのデータモデルを利用できるようになっています。
せっかくなので上記で作成したデータモデルを適用させてみたいと思います。
「CUSTOM_MODEL_ID」に先程トレーニングしたmodelIdを設定します。
以上!!!
とっても簡単ですね!
せっかくなので今回作成した独自の予想・解析モデルを利用して、デモアプリを弊社仕様にブランディングして実装してみました。
元のアプリとの挙動を比較してみましょう!
TerraSkyのロゴを分析すると「ski mask(スキーマスク)」と認識されてしまいます。
しっかりとTerraSkyと認識されました。
ちなみに製品ロゴの方で試してみても、トレーニングした内容でしっかりと認識してくれました!
簡単なサンプルですが非常に短い手順でカスタムの画像認識のデータモデルを作成することが出来ました!
他のAPIなどもいろいろ試してみて、今後はより精度の高い画像認識ができるようにしてみたいと思います!
※今回は2つのラベルだけで作成したので、あくまでどちらかのラベルに近い方への認識結果を返却されるようになっています。
※全然関係ない画像をアップロードするとどちらか近い方の結果に偏ります。
サンプルなのであまり精度は高く無いかもしれませんが、
ぜひ上記のアプリで弊社のロゴ画像や製品画像が写り込んだイベントの写真をアップして、
EinsteinのAI機能を体感して頂ければと思います!
まだイベントの写真をお持ちでない方はサンプル画像で試して頂くか、
7月に開催される弊社イベント「TerraSky Day 2017」にお申込み頂き、写真を撮りに来て頂けると幸いです!
*** 追記 ***
当ブログ執筆後で公開前のタイミングで、Salesforce 開発者および管理者向けの有償イベント「TrailheaDX」にて「Einstein Platform Service」に関して発表がありました。
概要は「Salesforce Developers Japan Blog」に記載されておりますが、文章に関する2つ新機能が追加になりました!
さっそく、リファレンスを見ると「language」に関するAPIが追加されていました!
今後も新たなAPIに期待して、積極的に検証していきたいと思います!
Snap-ins チャットを皆さんは使ったことはありますか?
Winterにベータ版、Springにて正式リリース、Summerでは機能強化とNapiliのコミュニティテンプレートへ対応されました。
今回はそんなSnap-ins チャットに関して執筆致します。
Snap-insは顧客と企業の繋がりの強化する製品として発表されました。
サービスクラウドで提供されていたナレッジ・ケース管理・Live Agent・SOSが基になっており、
それぞれのインターフェース面が強化されたものと私は思っています。
そしてSnap-ins チャットはLive Agentが基になった機能となります。
まずSnap-ins チャットの設定には以下の設定が必要です。
※今回はSnap-ins チャットの記事なのでコンソール、LiveAgent、コミュニティの設定はヘルプなどを参考にしてください。
1.設定画面>機能設定>スナップインと遷移し、新規リリースボタンを押下してください。
2.項目を入力して作成ボタンを押下します。
スナップインリリース名:任意
API参照名:任意
サイトエンドポイント:現在設定してあるコミュニティ or Site
※コミュニティかSiteの設定が必要な点はLiveAgentとは異なる点です。
3.Live Agent の基本設定の設定をします。
Live Agent リリース:LiveAgentのリリース設定
Live Agent ボタン:LiveAgentのボタン設定
4.事前チャットページの設定し、次へを押下します。
セールスのシナリオ、サービスのシナリオ、基本シナリオの3つがありますが
今回は取引先責任者とケースを作成するサービスのシナリオを選択します。
作成するレコードにレコードタイプの指定がある場合は画面下部で選択してください。
次の画面でオブジェクトごとに事前ページに必要な項目を設定します。
項目の追加は+ボタンから行えます。
もうSnap-insチャットの基本設定は完了です。
ちなみにNapiliのコミュニティテンプレートを利用しているとSnap-ins チャットのコンポーネントが追加されています。
コミュニティビルダーで以下のようにこのコンポーネントを追加するとユーザに見せるところまでも完了です。(こっちも簡単!)
1.コミュニティビルダーにて対象画面にSnap-ins チャットのコンポーネントをドラッグアンドドロップ
2.設置したコンポーネントの設定で作成したSnap-insチャットを選択し、チャットボタンを表示にチェックをつけます。
以下簡単な動きのキャプチャです。チャットの動きはLiveAgentと変わりません。
1.設置したコミュニティの右下に開始ボタンが表示されている
2.ボタンをクリックするとユーザは事前チャットページ画面に遷移します、
自分の情報をいれてチャットを開始します。
4.チャットウィンドウを開いたままで画面遷移も可能です。(フォームから検索して記事のページに移動しました)
LiveAgentの画面を実装したことがある方はコーディング無しで設定できることに驚いたのでは無いでしょうか?
LiveAgentの標準設定では設定完了時にコピペするソースが提供されて対象のHTML,VFページへの反映が必要でした。
またそのソースを反映するだけでは以下の機能しかありませんでした。
特に事前チャットページの設定は
javascriptとLive Agent 開発者ガイド中の第五章(事前チャット機能で一章分あります)を理解する必要がありました。
その点、Snap-ins チャットでは設定手順4.だけでコーディングが不要になっています。
また画面遷移しても右下にチャットウィンドウを開き続けることが可能となり
ユーザはエージェントの指示に従って親画面を動かすことが出来ます。
今回はNapiliテンプレートのコミュニティでの利用をお見せしましたが、
LiveAgentと同様に提供されるコードを利用してWEBページにチャット開始ボタンを設置することも可能です。
コーディングによる細かい動作のカスタマイズ性はLiveAgentに分がありますが、
基本的な動作に関してはSnap-ins チャットで満たせるのではと思います。
LEXの時代になりリッチな機能・UIを簡単な設定から実装可能になっております。
「Snap-ins」という括りでServiceCloudの機能がより一層便利になっていくのは楽しみですね。
こんにちは。大阪でSalesforce基盤を使ったシステム開発に従事している佐野です。Salesforceを使うと、導入型のシステム開発と比べると驚くほど簡単に魔法のように早く開発出来ます。GUIでブラウザからオブジェクト(≒テーブル)を定義すると画面が自動的に出来るだけでなく外部とのSOAPインターフェースも自動的に出来ます。
とは言え少し複雑な業務を設計する時にはしっかりデータモデリングしてから開発する事が重要です。読者の中には「データモデルなんて過去のもの、今から学ぶならオブジェクト指向アプローチ(OOA)かドメイン指向設計(DDD)では?」と思っている人も多いのではないでしょうか。しかしそれは誤解です。プログラム設計/クラス設計の時にはOOAを使いますが、業務設計はRDBで構築する事を前提とする限りデータ・モデリングが最適です。「帳簿組織を設計する」という感覚が重要なのですがそれは今回のテーマではありませんので触れません。
開発基盤としてSalesforceを選ぶならデータモデリングで業務設計するしかありません。そこで筆者が実践しているデータモデリングの手法をさらっと説明した後に、Salesforceでどうやって実装しているのかを説明します。(これらは基盤だけでなく業務に踏み込んだ話ですのでプロジェクトごとに変化します。あくまでも一つの例だと捉えてください。)
筆者が新人の時には、まだ日本にリレーショナルデータベース(RDB)はありませんでした。日本ORACLEが1985年に設立され、1990年ごろから広がり始めました。2000年頃にはRDB以外のデータベースは新規では使わなくなりました。RDBの原点は当時IBMのE.F.Codd博士の1970年の論文です。それまでのデータベースはポインタを使ってアクセス経路の構造を作っていましたが、「純粋にデータだけを見て関係がわかる」全く新しい理論に基づいた論文でした。この辺り興味のある方は次のブログをご覧下さい。
RDB以前のシステム設計の手法は主に業務の過程や手順に着眼して設計を行うPOA(Process Oriented Approach)でした。このRDBが広がると共に、処理よりもデータが変化に強い(変り難い)特性を生かしてデータとデータ間の関連に着目するデータモデリングを基本に設計する流れが生まれました。この手法は日本ではDOA(データ中心アプローチ)と呼ばれて独自の進化を遂げています。英語のDOAはドラマ「ER」などで出てくるDOA(Dead On Arrival=来院時心肺停止 状態)という意味になりますのでこれは日本語英語です。米国では情報工学(InformationEngeneering : IE)や情報資源管理(Information Resource Management:IRM)と呼ばれていますが、日本の流派ほど細かく分析はしません。
Salesforceにはsummer'12から正式リリースになった「スキーマビルダー」というツールがあります。このツールを使うことで画面上からドラッグ&ドロップの作業でオブジェクト(テーブル)や項目を作ることが出来ます。
スキーマビルダーで描画すればそのまま実装も出来るところは大変便利ですが、データモデル構造だけをシンプルに見たいという用途には向きません。そこで筆者はオープンソースのモデリングツール「X-TEA(エクスティ) Modeler」を使用しています。モデリングツールは何種類か試しましたが、1:Nの関係を親子関係と参照関係で明示的に表現出来る事と、項目に「更新不可属性」を設定出来る(何故必要かは後述)ためこのツールを重宝しています(作者に感謝)。このデータモデルツールの特徴はジェームズ・マーチン氏のIE(information engineering)表記法(俗に「鳥の足」とも呼ばれます)を横長に表記してある事です。他のツールでも同じ表現は出来ますので使い慣れたツールをお使い下さい。
では、上と同じデータ構造をX-TEAで見てみましょう。
顧客・顧客担当者・商談だけを関係付けたデータモデルです。「顧客」と「顧客担当者」の間は鳥の足のような特徴的な線で結ばれています。これが親子関係を表します。「顧客担当者」と「商談」の間は先が点々になっています。これは同じ1:NでもN側にNullを許す参照関係を表しています。この2つの書き分けが出来るツールは珍しいのでSalesforceに向いています。
顧客オブジェクトの先頭の項目「011-id」は顧客オブジェクト(011)のSalesforceIdを示しています。
SalesforceIdとはオブジェクトの各レコードに一意に付けられる番号です。この値を見れば、会社の中でレコードを1つに特定出来ます。一般に言う「オブジェクトキー」とほぼ同じです。Salesforceはこの値をURLに指定するとレコードを検索出来るという奇跡のようなURI設計(笑)になっています。
お客様との会議に使う時は実データ(インスタンス)を表示するとお客様はよりイメージが湧きデータ構造についての議論が楽になります。我々は「顧客名」というメタデータで議論する事に慣れていますが、地に足がついた議論をお客様とする時は実データで会話する事をお奨めします。例えば「テラスカイ商事」と話をするとお客様から「営業所が10箇所あるから・・・」「2箇所の営業所に所属している人も居て・・」というような情報を得る事が出来ます。メタデータで抽象的な議論をしている限りこういう情報を引き出すのは難しいです。
※Salesforceでは親子関係の事を主従関係と呼んでいます。これは英語のMaster-Detail Relationshipsの正確な訳語ですが、親子関係と表現する事もありますのでご了承下さい。
筆者個人はこの方式で書くことも多いのですが、実はこのデータモデルには少し誤魔化しがあります。Salesforceのフレームワークはすべてのオブジェクトの主キーはSalesforceIdなのです。このモデルは複合主キーとして表現しているため正確ではありません。とは言え主従関係の項目はNULLを許さない必須項目になりますし、子レコードを作成後に別の親レコードに変更出来ない更新不可属性も付きますので実質は複合主キーと同じです(変更可能にする事も出来ます)
このとおりSalesforceのデータ構造はER(EntityRelationship)構造を強く意識した機能が多くありますので業務システムを構築しやすくなっています。
本当に複雑なデータモデルの時に主キーも正確に表したい時は、外部キー(foreign key)を使います。複合主キーと外部キーの違いはNotNull制約と更新不可制約だけです。
X-TEA Modelerの特徴的な鳥の足が表現できないのですが、これで誰からも後ろ指を刺されないデータモデルとなりました←誰も刺しません(笑)
普通のRDBのSQLではテーブル間で同じ項目があれば表を結合する事が出来ますが、SalesforceのSOQLでは結合という構文がありません。その代わりオブジェクト間に予めリレーションを設定することでリレーションをたどる事が出来るようになります。E.F.Codd博士が「純粋にデータだけを見て関係がわかる」事を目的としてRDBを発明されましたが、RDBの場合同じ「顧客コード」がAテーブルとBテーブルで同じ意味を持っているのか明白ではありません。Salesforceは明示的に関係を項目として書いてしまいますのでRDBよりも「データだけを見て関係がわかる」という目的に合ってるのかも知れません(冗談です)
次の4つのカスタムオブジェクトを定義します。
子オブジェクトから親オブジェクトへは「リレーション名」を使ってあたかも子オブジェクト内の項目かのように参照することができます。カスタムオブジェクトのリレーション名は、主従(参照)関係項目名+__rとなります。
SOQLのFrom句には子オブジェクトしか指定しませんが、最大5レベルまで(主従/参照の)親のリレーションをたどる事が出来ます。
//MDtest04をベースのオブジェクトとして、親を辿るコード Select a.TextField__c, b.TextField__c, c.TextField__c, d.TextField__c From MDtest04__c a, MDtest04__c.MDtest03__r b, MDtest04__c.MDtest03__r.MDtest02__r c, MDtest04__c.MDtest03__r.MDtest02__r.MDtest01__r d
親オブジェクトから子オブジェクトを参照する時には、子リレーション名を使用したサブクエリを使用します。上記のデータモデルでは子リレーション名を( )で表示しています。
// MDtest02から子オブジェクトのMDtest03を参照する時 Select a.TextField__c, (Select b.TextField__C From MDtest03s__r b) From MDtest02__c a
ここで大きな制限があります。ベースとなるオブジェクトの子オブジェクト1つだけ、たどる事が出来ます。子の子や親の子にアクセスする事は出来ません。
1:Nの関係の1からNをアクセスしていますので結果は複数行になります。子の子のアクセスだと複数行の結果に対して複数行をアクセスする事になりますからプラットフォームのリソースを使いすぎるためだと推測しています。将来的には多少緩和される事を期待しています。
親:5レベル、子1レベルの範囲であれば1つのクエリで同時にアクセスが出来ます。
業務モデリングに慣れていない方はオブジェクトとオブジェクトの関係が多対多になっても気にされない事があります。例えば、商談に複数の商品が紐付く場合、商談オブジェクトと商品オブジェクトは多対多になります。
業務モデリング的には多対多になるという事はまだ分析が不十分だとみなします。オブジェクト指向系のモデリングツールを使用されると多対多が描けてしまいますのでご注意下さい。Salesforceでも無理やり多対多のオブジェクトを設定する事は出来ますが業務的に使えないシステムになります。その時の解決策として、「連結オブジェクト」という特殊なオブジェクトが用意されています。2つの主従関係を持つだけであり、難しくありませんのでドキュメントをご覧下さい。商談と商品の間に商談商品という連結オブジェクトを持ちます。
ただ、直接の関係と比べるとレポートなどに制限が出ます。非正規形にすることで連結オブジェクトを避ける方がSalesforceの標準機能を多く使える事も多いです。お客様にとってどちらの方がメリットがあるかをしっかり議論しましょう。
RDBの数学的な基礎は正規形(normal form:NF)です。様々な学者が様々な正規形を発明(?)発見(?)されていますが、実務者としては横目で見る程度で良いだろうと思います。どこまで厳格に実装するかはシステム次第ですしエンジニアの腕の見せ所です。正規形の目的は更新異常を防ぐ事です。
「One Fact In One Place」(1つの事実は1つの場所に)という言葉を聞かれた事があるでしょうか?それを目的と勘違いされているエンジニアを見かけますが、目的は更新異常を防ぐ事です。または更新異常が発生しても業務に影響のないように設計しましょう。更新異常が発生しないように入力規則・ワークフロー・トリガーなどを駆使しましょう。
正規形についてhttp://sasurahi.up.seesaa.net/docs/HigherNormalization.pdf から引用します。BCNFより上はNullを防ぎ、更新異常を防ぐ事を目的とし過ぎて業務的な関係を保持出来なくなっています。SalesforceはNullは怖くありませんのでそれらの考慮は不要です。
Normal Form | 排除したい状態 | 定義した人 |
第1正規形(1NF) | 繰り返し項目 | E.F.Codd(1970),C.J.Date(2003) |
第2正規形(2NF) | 部分関数従属 | E.F.Codd(1971) |
第3正規形(3NF) | 推移的関数従属 | E.F.Codd(1971) |
BC正規形(BCNF) | 非キーからキーの一部への関数従属 | Raymond F.Boyce and E.F.Codd(1974) |
第4正規形(4NF) | 対象性のある多値従属性 | Ronald Fagin(1977) |
第5正規形(5NF) | 自明でない結合従属性 | Ronald Fagin(1979) |
ドメイン/キー正規形(DKNF) | 静的な値に隠れたドメイン制約 | Ronald Fagin(1981) |
第6正規形(6NF) | 複数属性 | C.J.Date,Hugh Darwen,and Nikos Lorentzos(2002) |
※参考:ドキュメント リレーションの考慮事項
小さなオブジェクトを作成すると使い勝手が悪くなります。
選択リスト値セットはオブジェクトではありませんが、使い勝手が
めったに変更されないもので、1000件以内なら使えます。
MDtest04からMDtest01の項目を参照するのは3レベルです。
MDtest03__r.MDtest02__r.MDtest01__r.TextField__C
参照も含めて5レベルまでしか辿れません。必要な時は途中のオブジェクトに中間結果の数式を持ちます。
将来の機能追加を考えると15個程度で収まるように設計します。
実装は正規形にこだわらず、更新異常を防ぐ事が出来ているかを意識します。
4つ目の主従関係を設定しようとしても出てこなくなります
01→02→03→04と主従関係があるとき、05の主従関係には04のオブジェクトが出てきません。
どうしても必要な時は、04の中に05の内容を横持ち(1NF違反)するか親を03とします。
どうしても必要な時は非正規化するなど工夫して解決策を探します
親→子1→子2で親から1クエリで子2までアクセスしたい時
例1:子1にトリガを作り子2の中の必要な項目を子1の項目として持たせる
(削除について考慮する必要のないときだけ使える手です)
例2:親→子2という参照関係も同時に作り、検索後子1のものだけ選択する
他にも方法はあります
参照関係は多数設定出来ますが、主従関係は2つまでです。
3つのオブジェクトの連結オブジェクトは作成出来ません。
連結オブジェクトの2つの主従関係に同じ主オブジェクトを設定出来ません。
自己参照関連では細かい制約を見過ごして設計見直しする事がたまにあります。
実際のデモ組織で設定出来るかを調べながら設計しましょう。
今日はここまで。これからも明るくデータモデリングしましょう!
]]>Summer'16正式リリースされましたが、有償オプションであるために、なかなか使う機会がない「Event Monitoring」と、イベントログの可視化ツール「Event Monitoring Wave アプリケーション」ですが、実際に使ってみたので詳細をレポートします。
「Event Monitoring」は、ユーザーのレポートのエクスポートや、ページの閲覧、ドキュメントのダウンロードなど、広範囲な操作のログをモニタリングすることができ、取得できるイベントタイプは下記34種類(Spring'17)です。
「Event Monitoring Wave アプリケーション」は、イベントモニタリングで取得したログを、可視化・分析するツールで、ライセンスは、「Event Monitoring」の一部とされ「Analytics Cloud」のライセンスが無くても使用可能です。
特徴は下記の通りです。
ここで注意が必要なのは、イベント発生から、EventLogFilesオブジェクトに格納されるまで最大24時間、EventLogFilesオブジェクトに格納されてから、Waveのデータセットに入るまで最大24時間かかることです。
リアルタイムに監視するには向いていないことが分かります。
設定は下記の手順で行います。
詳細な手順は下記ヘルプページを参照してください。
https://help.salesforce.com/articleView?id=bi_app_admin_wave.htm
「Event Monitoring Wave アプリケーションとのインテグレーション」を有効にし、権限セットライセンスを割り当て、権限セットを作成して割り当てる
Salesforce社とEvent Monitoringを契約するとライセンスが有効になりますので、設定画面から「Event Monitoring Wave アプリケーションとのインテグレーション」を有効化し、権限セットライセンスを割り当て、権限セットを割り当てます。
Event Monitoring Wave アプリケーションの作成
「Event Monitoring Wave アプリケーションとのインテグレーション」を有効化すると、右上のアプリケーション「Wave Anarytics」というアプリケーションが出てきますが、開いても何も出てきません。
「アプリケーション作成」からウィザード(下記イメージ)に従ってWaveアプリケーションを作成すると、ダッシュボードやデータセットが自動的に作成されます。
下記イメージのようダッシュボードが作成されます。
これがいわゆる「事前作成済みダッシュボード」です。
事前作成済みダッシュボードでは下記のことが確認できます。
データフローの時刻設定は1日1回、任意の時刻に実行するようにスケジュール可能です。
実際のWaveアプリ画面は下記イメージのようになります。
これは、Chatterに「Koala.jpg」という画像ファイルを添付して、プレビューし、ダウンロードしたときの「File」ログです。
タイムスタンプはGMTで格納されており、ユーザー名、ユーザープロファイル、ファイル名、ファイル種別、操作(保存、プレビュー、ダウンロード)が記録されているのが分かります。
さて、Waveでの表示は上記のようになりますが、EventLogFilesオブジェクトの中身はどうなっているのでしょうか?
Dataloaderでダウンロードしてみました。
イベントタイプ毎に1レコードとなっていて、ログファイルの形式がCSVであることが分かります。
一番右側のLOGFILEが、イベントタイプ毎のイベント内容が集約されているCSVファイルの実体ですが、Base64でエンコードされているため、直接見ることができません。
上記のように、EvenLogFileオブジェクトはイベントタイプ毎に集約されてCSV化されています。
これをイベント毎に見る方法として、「Salesforce Event Log Browser」というツールが用意されています。
下記URLから、システム管理者アカウントでログインすると、日付を指定してイベントタイプ毎のCSVをダウンロードすることが可能です。
https://salesforce-elf.herokuapp.com/
下記イメージは「Salesforce Event Log Browser」で検索した結果画面です。
左側のActionのアイコンで、CSVファイルをダウンロードできます。
このツールでダウンロードしたCSVを見てみます。
これは、上記の「koala.jpg」をChatterに画像ファイル添付、プレビュー、ダウンロードしたときのログです。
「Event Monitoring Wave アプリケーション」の最下部に表示されているRaw log data と同内容となります。
「Event Monitoring」及び、「Event Monitoring Wave アプリケーション」の要点は下記のようになります。
実際に、システム管理者として、特定のデータのダウンロードや、操作内容を追跡するには、ログファイルの見方や、Waveダッシュボードの使い方などの運用スキルが必要となります。
ログファイルを外部に取り出し、解析し、アラートを出すようなインテグレーションをSOAP/RestAPIを使って開発することで、運用の生産性を上げることが可能となります。
こんにちは、三上です。
突然ですが、Open CTIがLightning Experienceに対応したのはご存知ですか?
今回は「Lightning時代のOpen CTI」と題し、LEXでのOpen CTIアダプタ設定方法や新しいOpen CTIライブラリについて書いてみたいと思います。
まずは、Salesforce社から提供されているLEX対応版Open CTIデモアダプタを導入してみましょう。
下記URLからパッケージ「Open CTI Lightning Demo Adapter」をインストールします。
https://login.salesforce.com/packaging/installPackage.apexp?p0=04t41000000bSXh
※インストールの前にLightning Experienceの有効化と、私のドメインの設定忘れずに!
パッケージをインストールすると、コールセンター「Demo Call Center Adapter」が自動で組織に作成されます。
次に、このコールセンターにユーザを追加する必要があります。
追加手順はClassicと同様です。
詳細は下記の記事をご確認ください。
おしえて!OpenCTIアダプタ設定 - そもそもCTIアダプタが出てこない
アダプタを表示するため、Lightningアプリケーションを作成します。
ステップ1)アプリケーションの詳細、ステップ2)アプリケーションオプションは適宜設定してください。
ポイントは3つ目のステップ「ユーティリティバー」で、アダプタを追加することです。
ユーティリティバーの設定 - ユーティリティバー項目の追加ボタンから「Open CTIスマートフォン」を選択します。
ユーティリティバーに「Phone」が追加されました。
ステップ4)項目を選択、でタブを追加、ステップ5)ユーザプロファイルへの割り当て、でアプリケーション利用権限を付与し完了です。
動作を確認するため、作成したアプリケーションを開きます。
画面左下の「Phone」ボタンをクリックするとアダプタが表示されます。
ここではLEX版のOpen CTIと、Classic版のそれとの違いをまとめたいと思います。
Open CTI関連の開発をされている方向けの情報となりますが、、、お付き合いください。
前述のパッケージでインストールされたアダプタのVisualforce「demoAdapterPage.page」のソースを開いてみましょう。
読み込んでいるOpen CTIライブラリが、Classicのそれとは別個のものであることが確認できるはずです。
Classic版
<script src="/support/api/38.0/interaction.js" type="text/javascript"></script>
LEX版
<script src="/support/api/38.0/lightning/opencti_min.js" type="text/javascript"></script>
また、メソッドの呼び出し方も異なります。
着信ポップアップを実現するsearchAndScreenPop()を例に取ると、、、
Classic版(interaction.js)
sforce.interaction.searchAndScreenPop('09011112222', 'DNIS=0311112222', 'inbound', callback);
LEX版(opencti_min.js)
sforce.opencti.searchAndScreenPop({searchParams:'09011112222', queryParams:'DNIS=0311112222', callType:sforce.opencti.CALL_TYPE.INBOUND, deferred:false, callback:callback});
名前空間や引数の渡し方が異なっていることが確認できると思います。
また、getDirectoryNumbers()など、LEX版では未サポートのものがあるので注意が必要です。
これらは今後に期待したいところです。
詳しくはこちら
Open CTI開発者ガイド
CTI Toolkitが廃止され、主流はOpen CTIとなりました。
また、LEXは日々進化・普及しており、今後はOpen CTIもLEX版がスタンダードになっていくことが容易に想像が付きます。
Open CTIの今後の進化に期待ですね。
以前の私のブログで「Salesforce Files ConnectでOne Driveとファイル共有してみた。」と題して、SalesforceのFiles Connect機能により、MicrosoftのOneDriveに接続してファイルを共有できるように設定して触ってみる記事を書きました。
その後しばらく時間が経ってから、社内外の方から「書いてある通りに設定しようとしたけどうまく行かない」との指摘を頂くようになり、私の方でも確認してみましたが確かにうまく設定できませんでした。
当時は確かに設定がうまく出来たのですが、どうやらその後に設定方法や内容が少し変わってしまったようです。
そこで今回は記事の修正版ということで、現時点で設定できる内容を書きました。
※このブログに記した内容は2017年5月時点で設定した内容であり、また、正確でない可能性がありますのでご承知ください。
・Salesforce
ヘルプを見ると、Salesforce Classic および Lightning Experience の両方で、Professional Edition、Enterprise Edition、Performance Edition、Unlimited Edition、および Developer Editionとなっています。
今回の評価にはDeveloper Editionを利用しました。また設定ではClassic画面で記載しています。
また、以前は社内のオンプレミス環境で構築された外部データソース向けにFiles Connect を使用可能にする有料ライセンスがありましたが、2016年12月末に販売停止になりました。
しかし、クラウドサービス向け(OneDriveやGoogleドライブ、Boxなど)のFiles Connect は無料で引き続き利用頂けるようです。
・OneDrive
「OneDrive for Bissiness」というアカウントが必要なようです。個人用のアカウントで接続できるかどうかは分かりません。
今回は「OneDrive for Bissiness」の評価版ライセンスを取得して設定してみました。評価版の有効期間は30日間となっています。
ここでは、SalesforceとOneDrive for Bissinessのアカウントは取得済みと想定して進めます。
メニューの[設定][カスタマイズ][Salesforce Files][設定][Files Connect]とたどり設定画面を表示します。
[編集]ボタンをクリックして、[Files Connect の有効化] をチェックして有効化すると、[ファイル共有] 、[外部オブジェクト検索レイアウトを使用]、[リンク変換を有効化]が設定できるようになります。
[ファイル共有]については、「コピー」と「参照」があり、OneDriveに権限が無いユーザにもファイルを共有した場合に「コピー」を選ぶとSalesforceにファイルがコピーされて共有されます。
「参照」を選択した場合はOneDriveに権限が無いとSalesforceに共有されません。
有効化が済んだら、次はSalesforceユーザとシステム管理者へのOneDriveへのアクセス権限を許可します。
権限の設定はプロファイルと権限セットで設定できます。権限セットで設定することで複数ユーザへの権限付与が容易になります。
今回は権限セットを作成して設定しました。
[設定] | [ユーザの管理] | [権限セット] とたどり、[新規] ボタンから作成します。
[表示ラベル]、[API参照名]を設定し[保存]します。その後[システム権限]リンクをクリックし、「Files Connect(クラウド)」にチェックします。
権限セットの作成後は、「割当の管理」ボタンから作成した権限セットを自分や他ユーザに付与します。
認証プロバイダの作成では大きく以下の3つの手順があります。
・認証プロバイダの作成
・OneDriveへの登録
・認証プロバイダの編集
[設定][セキュリティのコントロール][認証プロバイダ]とたどり、[新規]ボタンでプロバイダを作成します。
プロバイダタイプは「Microsoftアクセスコントロールサービス」を選びます。
次の設定画面で「名前」と「URL接頭辞項目」は決定する必要がありますが、以下4つの項目にプレースホルダ値(仮の値)を設定し保存します。
・コンシューマ鍵
・コンシューマの秘密
・承認エンドポイント(httpsで始まるURLでプレースホルダ値)
・トークンエンドポイント(httpsで始まるURLでプレースホルダ値)
保存したら、詳細画面に遷移しますので、画面下部の「コールバック URL」をメモ等にコピーします。次の手順3-2.でこの値を利用します。
・以下のURLへ接続します。([your company name]はOneDriveの設定により適宜変更してください。)
https://[your company name]-my.sharepoint.com/_layouts/15/appregnew.aspx
・「クライアント ID」、「クライアントの秘密」は項目は「生成」ボタン押下して値を生成します。
生成された「クライアント ID」、「クライアントの秘密」の値はメモ等にコピーします。後ほどの手順3-4.で利用します。
・「タイトル」は任意の値を設定します。
・「アプリケーションドメイン」項目へは対象のSalesforceの組織のインスタンスURLを入力します。(ap5.salesforce.comなどです)
・「リダイレクト」項目へは3-1.でコピーしておいたコールバックURL値を入力します。各項目入力後は作成ボタンを押下します。
・次に以下URLへ接続します。([your company name]はOneDriveの設定により適宜変更してください。)
https://[your company name]-my.sharepoint.com/_layouts/15/appinv.aspx
・「アプリID」項目に3-2.でコピーしておいた「クライアント ID」値を入力し、[参照]をクリックします。
画面が更新されたら、「権限の要求 XML」に以下の値を入力し[作成]をクリックします。
<AppPermissionRequests> <AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="Write"/> <AppPermissionRequest Scope="http://sharepoint/social/tenant" Right="Read"/> </AppPermissionRequests>
・確認メッセージの画面が表示されたら、[信頼する]をクリックします。
3-1.でプレースホルダにて作成した認証プロバイダを編集します。
・「コンシューマ鍵」には3-2でコピーしておいた「クライアントID」値を設定します。
・「コンシューマの秘密」には3-2でコピーしておいた「クライアントの秘密」値を設定します。
・「承認エンドポイント URL」は以下を設定([your company name]はOneDriveの設定により適宜変更してください。)
https://[your company name]-my.sharepoint.com/_layouts/15/OauthAuthorize.aspx
・「トークンエンドポイント URL」は指定の値をOneDriveの設定値より修正し設定します。([your company name]はOneDriveの設定により適宜変更してください。)
https://accounts.accesscontrol.windows.net/[your company name].onmicrosoft.com/tokens/OAuth/2?resource=00000003-0000-0ff1-ce00-000000000000/[your company name]-my.sharepoint.com@[your company name].onmicrosoft.com
値を設定したら「保存」し「OneDriveの認証プロバイダを作成」は完了です。
[設定][開発][外部データソース]とたどり設定画面を表示します。
・「外部データソース」「名前」項目には適当な値を入力します。
・「種別」は"Files Connect: Microsoft OneDrive for Business"を選択します。
・「サイトの URL」にはOneDriveのURLを指定します。([your company name]はOneDriveの設定により適宜変更してください。)
https://[your company name]-my.sharepoint.com
・「認証プロバイダ」には、3-1.で作成したプロバイダを選択します。
・「保存時に認証フローを開始」はチェックします。
「保存」ボタンで保存します。
確認メッセージの画面が表示されたら、[信頼する]をクリックします。
グローバル検索で外部データも検索できるように設定します。
[Files Connect 設定]で、「外部オブジェクト検索レイアウトを使用」をチェックします。
・4-1で作成した、データソース名をクリックして詳細ページ表示後、「検証して同期」ボタンを押下します。
・表示されたテーブル名の[選択]をチェックし、「同期」ボタン を押下してソース全体に対応付ける外部オブジェクトを作成します。
[外部オブジェクト]から、外部オブジェクトの「編集」を押下から「リリース済み」をクリックし「保存」 します。
[権限セット]から、2.で作成した権限セットを選び、作成されたオブジェクトを選択し、オブジェクトと項目の権限を設定します。
プロファイルの「有効な外部データソースアクセス」で、該当の外部データソースを指定して保存します。
設定がすべて終わりましたので、SalesforceでOneDrive上のファイルが共有されるか確認してみます。
Chatterの画面を開くとファイルのリンクの下にOneDriveのリンクが出来ており、クリックでOneDriveに作成されたファイルが表示されました。
またChatterのフィードに、OneDriveにあるファイルを添付することが出来ます。
カスタムタブを作成し、表示してみました。ちゃんとOneDrive上のファイルが表示されています。
企業でのファイル管理も、最近ではオンプレのサーバシステムからクラウドサービスへの切り替えが多くなって来ていると感じます。
クラウドサービスであれば、Salesforceとの親和性も良く、プログラミングすること無く設定を行うだけで、しかも、無料で連携共有することが可能となっています。
ぜひ、有効活用して頂きたいと思います。それにこの記事がお手伝いできれば幸いです。
みなさん、こんにちは。昨年はSOSにフォーカスしてサービスクラウドのソリューションを書きましたが、今年はまた、より自分の得意分野?のガバナンス系に戻って書いてみたいと思います。
最近はもう言わずもがなになってきましたがSalesforceはCRM、SaaSの枠組みをはるかに飛び越え、顧客自身がアプリケーションを作成・開発できるPaaSとしての位置づけを確固たるものとしています。
お客様の中には単に一部のアプリケーションあるいは一部の部門でSalesforceを活用するだけでなく、ほぼ全社におけるアプリケーション基盤として利用されている、利用されようとしているケースもかなり増えてきてのではないかと思います。
今回は特に、今後Salesforceを"全社におけるアプリケーションを開発する基盤"として活用しようとされているお客様向けに書いてみようと思います。もちろん既にSalesforceを導入済みのお客様や、Salesforceを導入・開発するベンダーサイドの方々にとっても何らかのヒントやリマインダーになれば大変幸いです。
先ず全社基盤として、Salesforceを導入するということの定義について書いておこうと思います。
必ずしも会社の全てのシステム、アプリケーションをSalesforceで行うということを意味したものではありません。もちろん会社規模がまだ小さく、例えば経理システム以外は全部Salesforceで!と、全てをクラウドシステムで賄うお客様もいらっしゃるかもしれませんが、大抵の場合、
・過去からの歴史の中でERPをはじめとする基幹業務パッケージ
・自社独特の業務仕様を実現するために自社開発したシステム
・システム間連携を実現する連携基盤
・ユーザ/ID管理基盤
・ミッションクリティカルな業務をカバーするためのシステム
・部門毎に利用している独自・分散型のシステム 等々
非常に複雑な状態のお客様が大多数ではと思います。
実際こういった仕組みの全てをSalesforceに置き換えることは困難且つ不可能に近いですし、敢えてその必要も無いと思います。そこで全社導入として導入することをここでは以下の形で(緩く)定義しておきます。
色々なご意見はあるかとは思いますがご容赦下さい。
それでは上記のような導入ケースの場合にどういった点を考慮するのが良いでしょうか。
個別のプロジェクトやアプリケーションの導入に際してというより、全体的な仕組み・体制・進め方という観点で見てみたいと思います。また、ここでは社内におけるクラウド導入を説得しなければならないというより政治的・事前調整的なアプローチは割愛させて頂き、導入前提の直前もしくは初期のフェーズのシステム的な観点のアプローチに絞らせて頂きます。
自分自身の経験と考察に基づいて以下の4点は少なくとも導入に際して考慮し策定しておくべきだと考えます。
※私が一昨年投稿させて頂いた「COEってご存知ですか?」で書きました、COE (Center of Excellence)もこのようなSalesforceを全社アプリケーション基盤の一つとして導入する際に、上記4つのアプローチを策定・実行していくにあたって必要となる要員体制・仕組みになると思います。
それではそれぞれの項目について見ていきたいと思います。
SalesforceのDNAとも言えるCRM関連のアプリケーションであれば、特に特別な検証をせずともSalesforceでやろう!ということに落ち着くと思いますが、いわゆるPaaS上に今まで別の仕組みやシステムで構築していたアプリケーションをSalesforceに乗せたい、新たな業務をSalesforceでやりたいという場合は、果たしてそのアプリケーションがSalesforceに向いているかどうか(正確にはどの程度向いているか)を見極めて、開発の優先順位と導入のロードマップを決めていく必要があると思います。
PaaSなのだから何でもかんでもSalesforce上に乗せたい!という気持ちもわかりますが、向き不向きと難易度、ビジネス上の優先度を冷静に見極めた上で進めることが、結果的にトラブルを回避する上で得策であり、より多くのアプリケーションをSalesforceで実現したいというゴールに対して近道になることをご理解頂きたいと思います。
Salesforceに向いているアプリケーションかどうかの適合性判定には経験的にも手法がありますが、ビジネスインパクトや開発の難易度等を軸としてマトリクス分析する方法があります。
さらに開発の難易度を判定するために、該当アプリケーションのUI/UX、ロジック、データモデル、連携等の各要素の複雑度を計数化して表して評価を行うこともできます。分析の結果として、Salesforceの標準機能を活かして、設定カスタマイズだけでアプリケーション要件を満たせるものがあればそれに越したことはありません。
また、ユーザの操作性向上のためにどうしても画面開発が必要、データの2重入力を避けるため他システムと連携も必要なので開発工数もかなりかかってしまうが、実現した場合の効果が非常に大きい場合は導入した方が良いということもあるかもしれません。
これらはあくまで、分析・適合性判定における一例ですが、Salesforce導入前/初期のタイミングではお客様だけで判定することは難しいと思いますので、セールスフォース社やSalesforceを手掛けるベンダーに協力を仰ぐのが近道だと思います。
手前味噌で恐縮ですが、弊社テラスカイのコンサルティングメニューの一つとしてクラウド・オリエンテッド・アプローチ(COA)というサービスもありますので是非ご検討下さい。
(アウトプットの一例)
システム・アーキテクチャーの観点だけでなくマネジメントや業務プロセスの観点からも検討していく手法もあります。
適合性判定のプロセスで大まかな開発工数と技術要素を洗い出すことができればベストです。これにより3.の開発及び運用・サポート体制と教育計画と併せてロードマップを作成することができます。
Salesforceを単体でユーザ/業務部門主導で導入する場合はともかく、全社規模で導入する場合は、必ずと言ってよいほど、既存システムとの連携が課題になります。よくあるケースはCRMでSalesforceを使う場合も基幹システムとの間で顧客データなどのマスター系DB連携、商談成約から受発注のためのデータ連携などが挙げられます。
機器構成等をSalesforceで見積作成する場合は、製品マスターなども連携対象になるかもしれません。また連携がバッチ的な仕組みだけでなくリアルタイムな仕組みで必要になるかもしれません。より簡易で連携数も少ない場合は個別にJava等でAPIを利用し連携プログラムを開発、連携することも一つの方法ですが、将来アプリケーション数も増え、連携対象のアプリケーション・処理も増えていくことが予測されている場合には、連携用のサーバー/基盤を利用することを検討した方が良いと考えます。
既に社内にSalesforceをはじめとするクラウドシステムに対して、連携可能なアダプターを持つETLやEAIがある場合はそれを利用することも一手段ですし、社内で標準の連携基盤が無い場合は新たに導入することも検討すべきと思います。
これもまた手前味噌で恐縮ですが、サーバー導入型であればData Spider/DC Spider、クラウド型であればSky On Demand/Data Spider Cloudが実際の連携事例も多数ありお薦めできます。
実際には1.のアプリケーションのSalesforce適合性判定と優先度、ロードマップで検討するアプリケーション群をベースにして、どのようなタイミング・方向・件数・方式、で連携が必要かを見極めて適切なETL/EAIツールを選択することが必要です。
重要なことは具体的な連携方式をパターン化して連携アーキテクチャーを標準化しアプリケーション、連携インターフェースが増える度に個別新規に連携開発するのではなく、策定した標準パターンを適用しながら連携ジョブ、プロセスを効率的に開発・実行できる状態にすること、また将来の保守工数の低減にも寄与できるような状態にすることです。
そのためには連携のアーキテクチャー設計時に知見のあるエンジニアの支援も必要になってくると思います。
また、連携のアーキテクチャーを考える上では、ユーザ情報管理、認証方式についても考慮することが必要です。
既にActive Directory (AD)などの仕組みを利用してシングルサインオンを実現されているケースもあると思います。この場合に、Salesforceにログインする際にSAMLなどの仕組みを通じてシングルサインオンの仕組みを実装するかどうかも、連携のアーキテクチャー全般を検討する上で必要な要素となります。
また、ユーザ情報の登録・更新・管理を2重、3重にシステム毎に実施する手間を最小化するためにも、ユーザ情報自体を連携対象にしてADからSalesforceに自動連携することが必要かどうかについても検討しておく必要があると思います。
複数/多数のアプリケーションをSalesforce上に構築する場合、それらを並行して開発するのか、或いはどこまで並行して開発するのか、優先順位を元に、順次開発していくかについて、1. アプリケーションのSalesforce適合性判定と優先度、ロードマップで述べたマスタースケジュールに盛り込みます。
とはいえ、これはそれらのアプリケーションを開発するリソースの手当があってこそ実現できる内容です。当然のことながらアプリケーションを検討・分析する際に各アプリケーション開発に必要な業務/技術スキル要素、ボリューム・難易度から見た工数等を、自社もしくは外部の開発ベンダーのリソース状況を勘案してロードマップと重ね合わせて調整していく必要があります。
また近々は難しいとしても、将来的に可能な限り社内のリソースを活用していきたいと考えられている場合は、ロードマップに沿って要員・体制と必要な研修計画と研修受講・スキル習得状況のモニタリング方法も検討しておきたいところです。
また、一旦アプリケーションが稼働しそれがどんどん増えてくると、それに対して利用ユーザからの問合せや改修要望も必ず発生しますので保守・改修のプランと併せてそれに対応するための体制・窓口として専任の窓口を設けること、またエンドユーザ-社内開発/保守チーム-外部開発ベンダーとの間やセールスフォース社も含めたコミュニケーションプランを決めておく必要があると思います。
まだアプリケーションが動く前からプランするのは大変かもしれませんが、アプリケーションが増え、規模も大きくなってくると社内でも専任体制をとることも必要になってくると思いますので早いタイミイグから検討頂きたい内容です。
SalesforceがSaaS、PaaSとしていかに開発者、システム管理者に優しく容易なシステムだとしても開発を拡げていく場合は、設定/開発規約、UI規定、プロジェクト規約等最低限定めておくべきかと思います。
開発作業を、一人や非常に少人数なチームで未来永劫継続できることも無いと思いますし、状況により外部のベンダー企業(1社だけに限定できるとも限らない)もSalesforceの組織に入り、作業を実施されることもあると思いますので、少なくとも後から見た際にも一貫したわかり易いものにしておきたいものです。
全社で複数/多数のアプリケーションを開発する場合は特にあてはまると思います。また利用ユーザが多い、同時利用数も多い、扱うデータ量も多くパフォーマンスにも注意が必要、処理が複雑、バッチ的な動きや連携も実施する、という要素が増えれば増える程、Salesforceのガバナ制限や大規模・大量データ利用時のベストプラクティスを意識しておく必要があります。
ここは前述しました「COEってご存知ですか?」や、Salesforceのエキスパート/アーキテクトの支援も活用しながら、社内でのガイドラインやべからず集などをまとめていくことが有用だと思います。
また、仮にアプリケーションの多くがSalesforceの標準機能をドラック&ドロップだけでカスタマイズするだけで済んだとしても、ユーザ規模もアプリケーション規模も大きくなる場合、いわゆるセキィリティモデルの設計とガイドラインは最初のタイミングでしっかり決めておきたいところです。
ロール、公開グループ、プロファイル、権限セット、共有ルールを後から変更することは規模が大きくなる程大変ですし、パフォーマンスへの影響や組織変更時の影響も事前に意識して設計しておかないと、予期しない対応に大きなワークロードを割くことにもなりかねません。
さらにこれも言わずもがなかもしれませんが、開発を行う場合に利用する環境やSalesforceにコードをリリースする際のツール、手順も個々ばらばらでなく、
Eclipseを使うのか、Antを使うのか、変更セットを使うのか等、開発~テスト~本番リリースに至るライフサイクルの中で、SandBoxをどう使うのかという取り決めも、併せてガイドラインを策定しておき後追いで問題をフォローする手間を減らすことも重要です。
以上の点(アプローチ)を個々別々に進めていくのではなく、導入当初に分類・タスク化して整理しておき、計画的に進めていくことをお薦めします。
今回はSalesforceを全社の開発・アプリケーション基盤として導入する際に考慮しておいた方が良いと思われるいくつかのポイントにつき主にシステムサイドの観点から書いてみました。
実際の状況では、一度に全てを策定して進めることは難しいと思いますし、最初から社内のリソースだけで対応するのは難しいかもしれません。しかし、外部のベンダー企業からの支援を仰いだとしても、一旦アプリケーションの適合性判定基準、連携方式・アーキテクチャーの定義、開発~運用・サポート体制の構築、開発・運用についての標準化・ガイドライン策定等々のベースを作っておければ、策定した基準・方針をユーザ企業様内でメンテナンス、拡張していくことも決して無理な話では無いと思います。
チャレンジも多いと思いますが、私共もクラウドインテグレーターとして少しでもご支援できる所があればと考えておりますので、その際は是非お声掛け下さい。
どうも、Service Cloudを愛する人、山下です。
今回はユーザ向けと言うより開発者向けの話になります。
...と言っても、SalesforceのOpen CTI関連の開発をされている方はほんの一握りだと思いますので、少しマニアックな記事と言えるかもしれませんが、お付き合いください。
Open CTIについてはもう説明の必要はないと思いますが、このOpen CTIを利用するインターフェイスが用意されています。
JavaScriptのAPI 「interaction.js」 として提供され、ライブラリを読み込むことで使用できます。 ライブラリを参照するためには以下のようにscriptファイルのURLを指定します。
<script type="text/javascript" src="/support/api/25.0/interaction.js"></script>
Interaction.js で良く利用されるものをご紹介します。
上記のメソッドの中から今回は Service Cloud コンソールにて screenPop() メソッドを利用して対象レコードを表示してみます。
取引先を表示ボタンをクリックすると取引先のテラスカイのレコードが表示される。
※通常はありえないですが、今回は対象レコードのID(00128000001xyui)を直接指定しています。
<apex:page showHeader="true" sidebar="true"> <script src="/support/api/39.0/interaction.js"></script> <script type="text/javascript"> var callback = function (response) { if (response.result) { alert('成功'); } else { alert('失敗:' + result.error); } }; function screenPop() { sforce.interaction.screenPop('/00128000001xyui', true, callback); } </script> <apex:form> <button onclick="screenPop();">取引先を表示</button> </apex:form> </apex:page>
取引先を表示ボタンをクリック
想定通り、取引先のテラスカイが表示されました。
ちなみに取引先以外のオブジェクトでもIDを指定すれば、ちゃんとそのレコードが表示されます。
今回、ご紹介した機能は一部ですが、「interaction.js」と「integration.js」を組み合わせるともっとService Cloudは楽しくなります!
冒頭でも話しましたが、Open CTI関連の開発をされている方はほんの一握りだと思いますが、弊社テラスカイには、Salesforceと音声基盤との連携経験が豊富な技術者が在籍しておりますので、お困りの際は是非ご相談ください。
いつでもご連絡をお待ちしております。
]]>みなさんこんにちは。エンジニアの高橋です。
4月に入り新入社員の方は実務に向けた研修が始まった頃かと思います。
その中で、Force.com 開発をやっているがプログラムを書いた経験が数日しかないという人が多いのではないでしょうか?
というかいるはず。
偶然にも(?)条件に当てはまった読者を Force.com 開発に引き込むべく、 本記事では Visual Studio Code で始める Force.com 開発 (in 2017) についてお話します。
そもそも Visual Studio Code って何でしょう?
wikipedia で確認してみます。すると
Visual Studio Code はオープンソースのソースコードエディタである。マイクロソフトにより開発され、Windows, Linux, macOS 上で動作する。
と書いてあります。ここで Microsoft 社が開発したエディタということが分かります。
なので、開発元である Microsoft 社の Visual Studio Code のwebサイトを確認してみます。
モダンな Web アプリケーションから、高機能なクラウドアプリケーションまで、多彩なアプリケーションのビルド、デバッグ定義を見直し、コードを編集するための最適な環境を提供します。
つまり、コードエディタなんだけど、マルチプラットフォームで動作し、多彩なアプリケーションのビルド・デバッグもできてしまう・・・
話を聞くとなんか凄そうです。というか、Microsoft 社が開発しているので、凄いのは間違いない。
余談ですが、筆者がこのエディタの存在を知ったのは昨年末で、牛めし大好きなあの Microsoft社のエバンジェリストさんから知りました。わーい。
ここからは、開発環境を構築していきます。手順は下記になります。
以上です。
え~、過去の開発環境構築の記事は結構手間かかっていたのに、これだけで大丈夫なんですか?という声が聞こえてきそうですが、
大丈夫だ。問題ない。
参考 : 過去の開発環境構築の記事
まずはインストーラーを取得します。
インストーラーを Visual Studio Code のダウンロードサイトから使用している環境に合わせてダウンロードして下さい。
執筆当時(2017.4.7)ではバージョンは 1.11.1 です。
ダウンロードしたら、インストーラーを起動しインストールを進めていきます。
※. インストールの手順はこの記事では割愛します。インストーラーのガイドに沿って進めていけば問題ないと思います。
また、Visual Studio Code の基本的な使い方に関しては、ITmedia 社の記事で特集が組まれていますので参考にしてみて下さい。
特集:Visual Studio Code早分かりガイド:Visual Studio Codeの使い方、基本の「キ」 (1/6)
ここからは Force.com 開発をできるようにするための作業になります。
本記事では、windows 10上で実行しています。
まず、インストールした Visual Studio Code を始めて起動すると下記の画面が表示されます。
始めからメニュー表示がローカライズされていることに個人的に感動しています。
表示されている画面の左側にあるオレンジ色で囲った「拡張機能」ボタンをクリックします。
押下すると、左サイドに拡張機能のウインドウが表示されます。
ここから、オレンジ色で囲った検索ワードの入力フィールドに「@sort:installs」とあるので「force」に変更します。
変更すると、force のワードに該当する拡張機能の一覧が表示されます。
今回インストールする拡張機能「ForceCode」が見つかりますので、オレンジ色で囲った枠中の「インストール」ボタンをクリックします。
「インストール」ボタンをクリックすると、確認のダイアログが表示されます。
「はい」を選択します。
選択するとインストールが始まります。 1分もかかりませんでした。
インストールが完了すると「再度読み込む」という青いボタンに変わっていますのでボタンをクリックします。
その後にアクティブ化の確認ダイアログが出ますので「ウインドウの再読み込み」ボタンを選択します。
ウインドウの再読み込みが終わると、最初にVisual Studio Code を起動した時と代わり映えしませんが、
画面左下のオレンジで囲った部分「ForceCode 0.5.13 is Active」と表示されれば、拡張機能「ForceCode」のインストールは成功です。
※. 執筆当時(2017.04.07)のバージョンは 0.5.13 です
ここで、再び「拡張機能」ボタンをクリックしてみましょう。
すると、「ForceCode」 の他にも別の拡張機能がインストールされていることが分かります。
先の確認ダイアログで表示された「依存関係」によるものです。
「Apex」は Apexコード、「Visualforce」は Visualforce のコードに対し、シンタックスハイライトを有効にして開発者に見やすくしてくれる機能です。
(※. 昨年末の段階では合わせてインストールされることはありませんでした。)
以上で、開発環境の構築は終了です。
どうでしょうか?
過去の2つの記事による環境構築と比較すると、かなり手軽に感じられるのではないでしょうか?
開発環境の構築ができましたので、実際に使用していきます。
今回は、構築した Salesforce developer 環境上に trailhead の 開発者初級 > Visualforce の基礎 > カスタムコントローラの作成および使用 のテキストで作成される Apexクラスと Visualforce ページが登録されているという何とも都合の良い状態から、
のシナリオで進んでいきます。
始めに、ファイルのダウンロード先となるフォルダを開きます。
オレンジ色で囲った「エクスプローラ」ボタンをクリックします。
クリックすると表示内容が変わります。
「フォルダーを開く」ボタンをクリックします。
クリックするとフォルダ選択ダイアログが表示されますのでフォルダを選択します。
フォルダを選択すると、選択したフォルダの下にあるファイルが展開されます。
例ではフォルダの下にファイルがないので、何も展開されません。
次に、「コマンドパレット」を起動します。
コマンドパレットとは、Visual Studio Codeの機能をキーワード指定で実行するためのキャラクターユーザインターフェースです。
※. コマンドパレットについての詳しい説明は 本記事では割愛します。
メニューバーから「表示 > コマンドパレット」の順で選択します。
選択すると、小さいウインドウがエディタ上に表示されます。(上の絵)
表示された小さいウインドウのテキスト入力フィールドに「force」と入力すると検索結果が絞り込まれるので、オレンジ色の枠で囲まれた選択肢を選択します。(下の絵)
選択すると、salesforceの認証を行っていないため、ログイン情報の入力を求められます。(認証済みの場合はスキップします。)
まずは、ユーザ名。
その次が、環境。
本シナリオでは 「Production / Developer」を選択します。
最後に、コードの保存時にデプロイもするかどうか。
本シナリオでは「No」を選択します。
入力が終え認証が通ると、ダウンロードできる クラス、ページ、トリガーの一覧が表示されます。
ここではApexクラス「ContactsListController.cls」を選択します。
選択すると、エディタ上に 選択した Apexクラスファイルが表示されます。
同時に、左側のエクスプローラに選択した Apexクラスファイルが追加されていることが分かります。
同様の手順で Visualforce ぺ―ジ「ContactsList.page」を選択します。すると下のようになります。
また、認証時に入れた情報は force.json というファイルに保存されます。
ユーザが直接ファイルを変更することが可能です。
各設定項目についてはリファレンスを参照して下さい。
余談ですが、ファイル選択のところで、複数選択できないか試してみましたが執筆時点では選択することはできませんでした。
面倒くさいな~と思いつつも、将来できるようになることを期待したいと思います。
ここからは 先ほど取得した Visualforceページを編集・保存・デプロイしてきます。
以下が Visualforceページを取得した後、Apexクラス側のウインドウを閉じた状態です。
ファイルを保存した状態が下の絵になります。
ここで、ちょっと寄り道して salesforce上のファイルを確認します。
ForceCode の設定でコードの保存時にデプロイしないように設定にしました。
なので、この段階では 変更は反映されていません。
デプロイしていきます。
左のサイドバーから編集した Visualforceページ名の上で右クリックしコンテキストメニューを表示します。
その中のオレンジ色で囲った枠「Force: Save/Deploy/Compile」を選択します。
選択すると、デプロイが開始されます。
少し待つとステータスバーの表記が変わります。
下のオレンジ色で囲った中のチェックマークが表示されたらデプロイ成功になります。
salesforce上の内容を確認すると、下のように変更内容が反映されていることが確認できます。
「ForceCode」以外で Force.com 開発を助けてくれる拡張機能「vsforce」を紹介します。
個人的に、この拡張機能で強力と思ったのが Auto-
(他にもできることがありますが、詳細はリファレンスを参照してください)
ではインストールしていきます。
「拡張機能」ボタンをクリックして左にサイドバーを表示させた後、検索ワードのフィールドに「vsforce」と入力します。
下の絵にある拡張機能が表示されたら、後は「ForceCode」と同様にインストールしていきます。
インストールしてアクティブ化が完了すると、Visualforceページでは 「<」とタイプしただけで Apex タグの候補がずらっと表示してくれます。
Visual Studio Code は、拡張機能を豊富にそろえています。
Apex だけでなく、html, javascript, css などの拡張機能を入れて開発効率をさらに up させましょう。
どのような拡張機能があるかは webサイト Visual Studio の Marketplace から確認できます。
これからプログラムをガリガリと書くことになる人、そしてそれが Force.com 開発である人をターゲットに開発環境構築の段階で挫折しないよう書いたつもりですが、いかがでしたでしょうか?
Visual Studio Code はテキストエディタ以上、IDE未満のエディタという表現をされる方がいますが、
Force.com 開発の環境構築も同じような「force.com IDE による方法と Sublime Text による方法の中間に位置している」というイメージを持ちました。
本記事が Force.com 開発の手助けとなれば幸いです。
それでは良い Force.com 開発生活を~♪
追伸: 1年後には構築手順が変わっていそうなので、来年の3月末あたりに誰かリメイクをお願いします。
]]>みなさんこんにちは。今岡です。
テラスカイはお客様やパートナーの皆様に支えられ、おかげさまで案件数が2500件(2017/03/29現在)を突破しました。確実な品質と納期の積み重ねが評価・信頼されたものと大変喜ばしく思っております。大部分の案件がご期待する品質と納期でお届けできているものの、残念ながらプロジェクトが長期化してカットオーバーを迎えた案件もゼロではありません。
いわゆる炎上プロジェクトとなった原因を探ると、高い割合で「要件定義の失敗」が理由として挙げられます。プロジェクトの成功の鍵はいくつかあると思いますが、プロジェクト成功の重要な位置付けとなる「要件定義」の進め方について、いくつかのポイントを概略でお届けしたいと思います。
認定テクニカルアーキテクトの合格を目指す読者の方もいらっしゃると思います。認定テクニカルアーキテクト試験というと、プラットフォーム特性や制限を理解し、より大規模かつ複雑なプロジェクトに対応できる技術的な設計・実装スキルに着目しがちですが、プロジェクトのライフサイクル、様々なタイプの開発パターンや開発方法、プロジェクト全体のリスク検知なども必要スキルとして求められます。
提案時やプロジェクトが開始した直後に「このプロジェクトはなんだか上手く進まない気がする」といった感覚を覚えたことはありませんか? ここでは、そのような感覚を「危険なプロジェクトの香り」と称して、危うさ漂うプロジェクトの典型的なケースを挙げてみます。
提案者:「アジャイルなので早く安く失敗しません! ドキュメントも作りません。」
提案する側の典型的なよくない提案例です。Salesforceの標準カスタマイズは確かに高品質・高生産性を約束するでしょう。しかし、標準カスタマイズの生産性が高いとはいえ、データモデルの変更を伴う変更要求のインパクトは大きいものです。また、ユーザインターフェースやビジネスロジックの一部をVisualforceやApexで実装するケース、外部システムとのインテグレーションを伴うケースなど、従来のスクラッチ開発相当な期間と工数を要するでしょう。また、業務フローや機能要件一覧などの最低限のドキュメントは作成する必要があるでしょう。ユーザに耳当たりの良い話をして開発者が後から苦労するような提案をしていませんか?
開発者:「要件が収束しません!後から知らない仕様を言われました...」
プロジェクトの開始時にユーザとスコープの認識は合意できていますか? 例えばRFPが提示されるような案件の場合、それに含まれる業務フローや機能要件一覧などからスコープを検討し、要件定義でヒアリングする業務を決めることでしょう。ところがプロジェクトがいざ始まったら、ユーザから「業務全般を理解してもらった上で今回対象とするシステムの要件定義を進めて欲しい」という話があったとします。スケジュールは気になりつつも、ヒアリングしなければ先に進まないという開発者の焦りから、当初想定していない業務までヒアリングを続けた結果として、要求が膨れ上がり要件定義が収束しない、ようやく収束したものの当初予算を大幅に超過することが判明して次工程に進めない、要件定義の収束を優先した結果として、要求仕様の詳細な詰めが甘く後工程で品質面に課題が出るといった事態を招きかねません。
お客様:「予算も納期も要求も全部決まっていますが、アジャイル的にお願いします!」
アジャイル開発の考え方や進め方を誤解されていませんか? プロジェクトの中で当初想定していなかった新たな要求仕様や変更要求が出てくることはあります。アジャイルで進めることが前提であれば、要求仕様の追加や変更要求が発生した場合、その優先順序は見直され、常にスコープ調整とセットであるべきでしょう。要求が全部決まっているという中には「現在使われているかよくわからないが、既存システムにあるから...」というようなものが含まれる場合もあります。「当初要求すべてが実装されないと受け入れられない」ではなく、「作らないことの良さ」という選択肢もあってもよいのではないでしょうか?
お客様:「この要件は別担当です。ただし、仕様は現行踏襲でお願いします!」
要件定義で業務を確認していく過程で、仕様に関する決定ができずユーザ内で担当がたらい回しになるケースです。開発者は仕様を早急に決定したいものの、誰に確認したらよいか判らずスケジュールだけが差し迫る事態となるでしょう。また、「現行踏襲」がうたわれるケースも要注意です。現行システムからプラットフォームも変わり、その特性や制限も異なる中、何をどこまで踏襲すればよいのでしょう? ユーザがユーザインターフェースの振る舞いは理解していても、内部的なビジネスロジックまで仕様提示できないケースもあります。結果として、現行システムの膨大なドキュメントや場合によってはソースコードから読み解くという事態になり兼ねません。
Salesforceを導入する上で、ウォーターフォール、アジャイル、あるいはその両方をハイブリッドに取り入れて行うケースがあります。ウォーターフォールに慣れ親しんだユーザからすると、アジャイルでの進め方がイメージできなかったり、誤解している場合があります。最悪の場合「いつ仕様を合意したかわからなかった...」という切ない事態が生じることがあるかもしれません。 やはりユーザとプロジェクトを進める上で開発手法の十分な説明と理解が必要でしょう。また、お客様の文化やシステムの特性がその選択に影響を及ぼすケースも考慮したいところです。
要件定義を進める上で、ユーザは現在直面する課題解決や新たな取り組みに対する期待効果の検討に注力したいものです。開発者はそれを理解しつつも、ユーザ自身が気付いていない課題を抽出したり、ユーザ自身が詳しく把握していない仕様を掘り下げることが必要となります。そのためにはどのようなアプローチが考えられるでしょうか?
Salesforceの要件定義において、標準カスタマイズを用いたプロトタイピングを行わないケースはないでしょう。プロトタイピングは実際に動くものが見れるため、ユーザにとって業務での利用シーンをイメージしやすく、意思決定がしやすいというメリットがあります。非常に有効な手段の一方で、デメリットもあります。
ユーザにとってわかりやすい反面、機能や操作性に偏ったレビューや要望になる場合があります。結果として、業務的な観点での検討やビジネスロジックの検討が不十分となるリスクがあるでしょう。
このような出来事が起こったらどうでしょう...
要件定義も終盤に差し掛かり、これまで取りまとめた成果をレビューする場面において、今まであまり姿を見なかったユーザ部門の方がいらっしゃいました。開発者が説明を終えるとその方から「こういうものを作って欲しいのではない! 我々のビジネス構想をわかっていない!」とちゃぶ台をひっくり返されました。。
極端な例ですが、真にシステム化の目的やゴールを理解しているのが、必ずしも要件定義の中で積極的な発言や要望を出すユーザとは限りません。システム化を進める中では多くのステークホルダーが参加します。最終的な意思決定に影響を及ぼすユーザの把握や、予算執行の権限を持つ人物などの把握とコミュニケーションは必要でしょう。
要件定義に毎回大勢のユーザがミーティングに参加し、ユーザ間で議論が白熱してしまい遅々としてヒアリングが進まないということはありませんか? あるいは「仕様面の最終的な決定はユーザ部門に確認しないと決められない」として、いつまでも仕様が確定しないケースもあるでしょう。要件定義を円滑に進める上で、意思決定可能な少数ユーザと集中して要件定義を進めることは重要になります。
ユーザの現場を見ると、その現場で起こっている生の課題や雰囲気を肌で感じることができます。そしてユーザの考えるシステム化の目的やゴールの理解がより高まり、開発者としてシステムを作る上での意気込みや思いも高まることでしょう。例えばコールセンターで数百席のオペレーターが業務を行っている様子を見ると、開発者として「絶対止まらないシステムにしなくては!」や「オペレーターのみなさんに喜んでもらえるシステムを作るぞ!」といった気持ちになると思います。
ユーザの業務を理解する上で現行システムに関するヒアリングを行う場面があると思います。ユーザから操作マニュアルや設計書が提示され、それにもとづきヒアリングすることも多いと思いますが、実際に動く現行システムの説明を受けながらヒアリングすると、ドキュメントでは気付かなかった仕様が確認できたり、ユーザが機能面で重要視しているポイントなどがより具体的に把握できることでしょう。
ユーザが現行システムに関する仕様を十分に説明できない場合はあるでしょう。開発者として現行システムを俯瞰的に把握したい時、現行システムのデータモデルを見ることはそれを助けると思います。また、外部システムとのインテグレーションなどを検討する上で、既存システムのテーブル定義書からキー項目やデータ型を把握することは設計の精度をあげるでしょう。さらにユーザ自身が詳細に把握しづらい入出力のチェック仕様やステータスによるアクセスコントロールなども設計書から得られる重要事項になるでしょう。
初期データ移行や外部システムとのインテグレーションなどを検討する上で、実際の生データを見ることが時として重要になります。ユーザ自身がトランザクションのキー項目として認識していた項目を調べてみると重複するデータが含まれていたり、Nullを許容しない想定の項目に値が入っていない、日付型として扱う想定の項目に日付としてあり得ないデータが含まれているなどは実例です。
最終的な要件定義完了までに具体的にどのようなアウトプットを作っていますか? Salesforceの導入では比較的ドキュメントが少ないと言われますが、最低限必要であろうアウトプットを紹介します。
上記で挙げたアウトプットは、それ自体を要件定義の終盤で作るというものではありません。業務フローを検討し、システム全体を通して業務が回ることに主眼を置いたプロトタイプで確認し、システム全体の骨格となるデータモデルに落とし込みます。さらに、業務を行う上で重要となる主要項目や業務上の分岐や状態を表すステータスを明確化します。これらを要件定義の過程でサイクリックに実施し、機能要件一覧へと取りまとめます。要件定義ではどうしても機能面に着目しがちですが、セキュリティモデルはシステムの非常に重要な位置付けとなりますので、確実に確認しアウトプットしましょう。
要件定義では多くの要求仕様が提示されますが、限られた予算と納期の中で常に優先順序をつけてスコープの調整を図る必要があります。優先順序の付け方は様々なやり方があると思いますが、ここでは「狩野モデル」を紹介します。例えば、ある機能についてユーザに「あればどう思いますか?」という質問と、「なければどう思いますか?」という2つの質問をします。ユーザからあればどう思うかの質問に対して「当然である」という回答が得られ、なければ「気に入らない」という回答だったとします。あれば当然でなければ気に入らないと怒り出すのですから、この機能は「必須」として必ず作らなければならない機能となるわけです。
M:"必須"がおのずと優先順序を高くして開発する対象となり、E:"魅力的"は従来のシステムや競合他社との差別化が図れることになります。L:"線形"はあればあるほど満足度が上がることになるため、コストと納期の見合いになるでしょう。I:"無関心"はあってもなくても気にならないので優先度を下げ、R:"逆効果"はあると困りますので作りません。Q:"懐疑的回答"は回答がおかしいので要求として取り下げて構わないでしょう。
要件定義を通じて収集された要件が現在どのような状態にあるかをトレースできますか? 要件がいつ発生し、その優先順序はどう設定され、フェージング、いつ着手する、あるいは現在開発中、テスト中である、リリース済みであるなど...システムは一度のリリースを経たのちも随時新たな要望やエンハンス、改修要望などが発生し続けます。これら全体が管理され常にスコープ調整と状態が把握できる仕組みを作ることも検討してみては如何でしょう?
要件定義をテーマに寄稿しましたが、要件定義をテーマに1冊の書籍が書き上がるほど奥深いものなので、内容に物足りなさを感じられる方もいらっしゃると思います。ただ、ここで記載した内容は多少のアレンジはありますが、実体験にもとづきます。恥ずかしながらの事例公開ということになりますが、開発者のみなさんが同じ轍を踏まず、生き生きとプロジェクトが遂行されればと思った次第です。
]]>みなさんこんにちは。AWSも好きなSalesforceエンジニアの吉澤です。
今日はSalesforceとAmazon SESを使ったメール配信システムについてお話したいと思います。
1組織あたり1日に最大5000個の外部メールアドレスに対し一括メール送信ができる。
Salesforceの一括メール送信は取引先責任者、個人取引先、リード、および内部ユーザにのみ。
(内部ユーザへのメール送信は制限はありません。)
※Salesforceヘルプより引用
今回は、以下のような場合に、どうやったら簡単にメール配信ができるかを考えてみました。
1.Salesforceの外部ユーザ(5000人以上)に対し、ダイレクトメールを送付したい。
2.迷惑メール業者に認定されたくないので、不達管理は行う!
メール配信を考えたときにまずはじめに思いついたのが、Amazon SESです。
Amazon SESはAmazon Web ServicesのEメールプラットフォームです。
メールの送信機能には以下のような特徴があります。
・SPFやDKIMなどの認証に対応している。
・メールが不達だった場合、Amazon SNSを使って結果を返してくれる。
・弊社連携ツールである、SkyOnDemandのメールアダプタを使うと簡単に送信できる。
こうした特長から、Amazon SES&SkyOnDemandであれば、今回の条件でも簡単にメール配信&不達管理ができそうです。
1.配信者はメール対象オブジェクトに対象となるメールアドレスを登録します。
2.配信者がメール配信処理を行うと、SkyOnDemandがメール配信対象から対象メールアドレスを抽出し、Amazon SESを使ってメール配信される
3.不達のメールはAmazon SNSを使ってSalesforceに返され、Salesforceの処理で不達フラグを立てる。
メール配信の事前準備として、メール送信サーバーのグローバルリソースの設定を行います。
こちらはリージョンごとに固定です。
メール配信スクリプトはメールデータ取得→送信対象→宛先セット→メール送付と、これだけです。
メール送信アイコンでは認証キーが必要ですので、以下のように設定します。
必須設定タブ
送信元メールアドレス:AWS側で認証済のメールアドレス
認証タブ
ユーザ名 :AWSで発行したメールユーザのアクセスキー
パスワード:AWSで発行したメールユーザのシークレットキー
メール送信はたったこれだけの作業でできました!
不達になったメールはAmazon SNSで通知されます。
まずはAmazon SNSの仕様を調べてみました。
Amazon SNSの通知方法は6種類があります。
・HTTPS(JSON)
・HTTP(JSON)
・SQS
・Email
・Email-JSON
・Application
今回はSalesforceのメールサービスを使い、不達メールアドレスを受け取るようにしました。
メールサービス設定はこのような形で設定します。
このメールサービスで呼び出すクラスでは、メール本文の解析、バウンスメールレコードを作成、メール本文内からステータス、メールアドレスを抽出し、メール配信対象オブジェクトを検索。該当するメールアドレスのメール配信対象に対し、不達のチェックフラグを立てる。
といった処理を行います。
global class BounceMailHandler implements Messaging.InboundEmailHandler { global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) { Messaging.InboundEmailResult result = new Messaging.InboundEmailresult(); try { // バウンスメールを作成 Bouncemail__c bmail = new Bouncemail__c(); bmail.Detail__c = email.plainTextBody; // ステータス検索 String statuscode = getObjectFromBody(bmail.Detail__c,'status\\\\":\\\\"','\\\\','"Message" : ','status'); bmail.Status__c = statusCode; // メールアドレス検索 String bounceMailAdderess = getObjectFromBody(bmail.Detail__c,'destination\\\\":\\[\\\\"','\\\\','"Message" : ','destination'); bmail.Email__c = bounceMailAdderess; // タイムスタンプ検索 Datetime bounceDatetime; String bounceTimeStamp = getObjectFromBody(bmail.Detail__c,'Timestamp" : "','"','"Timestamp" : ','Timestamp'); if(!String.isEmpty(bounceTimeStamp)){ System.debug(bounceTimeStamp); // 年取得 Integer bYear = Integer.valueOf(bounceTimeStamp.subString(0,4)); // 月取得 Integer bMonth = Integer.valueOf(bounceTimeStamp.subString(5,7)); // 日取得 Integer bDay = Integer.valueOf(bounceTimeStamp.subString(8,10)); // 時取得 Integer bHour = Integer.valueOf(bounceTimeStamp.subString(11,13)); // 分取得 Integer bMin = Integer.valueOf(bounceTimeStamp.subString(14,16)); // 秒取得 Integer bSec = Integer.valueOf(bounceTimeStamp.subString(17,19)); System.debug(bYear); System.debug(bMonth); System.debug(bDay); System.debug(bHour); System.debug(bMin); System.debug(bSec); // 日時型へ変換 Datetime tmpDate = datetime.newInstance(bYear,bMonth,bDay,bHour,bMin,bSec); // 9時間加算 Datetime bDate = tmpDate.addHours(9); // 項目セット bmail.SendDateTime__c = bDate; } if((statuscode=='5.1.1' || statuscode=='5.3.0') && !String.isEmpty(bounceMailAdderess)){ // 該当メールアドレスが設定されている取引先を検索 List<SendMailTo__C> bounceMailToList = getMailToFromEmail(bounceMailAdderess); // メール配信対象更新 if(bounceMailToList != null && bounceMailToList.size() > 0){ for(SendMailTo__C cont : bounceMailToList){ cont.MailBounceFlg__c = true; cont.MailBounceDate__c = SYstem.now(); } update bounceMailToList; // メール配信対象と紐づけ bmail.mailToUpdateFlg__c = true; } } Insert bmail; }catch(Exception e){ String errMsg = '◆◆◆バウンスメール処理エラー:' + e.getMessage(); system.debug(errMsg); // 本文のみセットし登録 Bouncemail__c errorMail = new Bouncemail__c(); errorMail.Detail__c = email.plainTextBody; Insert errorMail; // throw new EstimateWSMailHandlerException(errMsg); } return result; } }
※処理の基幹部分のみを抜粋
これで不達となった対象ユーザを把握できるようになりました。
より充実した機能を求めるとApp Exchangeでメール配信サービスなどの利用を考えますが、今回は単純なメール配信サービスであれば、Salesforceと他のサービスをつなぐ事で比較的簡単にできました。
SalesforceやAWSはどんどんと新しいサービスが発表されておりますので、より新しいサービスを触ってみたいと思います。
それではさっそく参りましょう!下半期ブログランキングです!
Dreamforceの期間中に16もの記事を公開しましたが、ほとんどのブログが上位に入っていました。さすがDreamforceですね!
中でも特によく読まれていたブログ3つをご紹介します。
http://www.terrasky.co.jp/blog/2016/161005_001845.php
http://www.terrasky.co.jp/blog/2016/161006_001850.php
http://www.terrasky.co.jp/blog/2016/161005_001844.php
次に、技術ブログの上位5つをご紹介します!
最後までお読みいただきありがとうございました。
それではまた半年後にお会いしましょう~!
みなさんこんにちは。自称:標準機能のスペシャリスト佐々木です。
今日は、見積機能のご紹介です。えっ見積ってずいぶん前からあるじゃんと思った方も
多いと思いますが、Spring'17のLightning Experience(以下LEX) 対応でPDFが進化したということで、
改めてご紹介します。
また、2016年秋にリリースされたSalesforceCPQとSalesforce標準の見積の機能の違いにも
触れていきたいと思います。
LEXの設定画面でご紹介します。
「設定」→「機能設定」→「セールス」→「見積」→「見積設定」画面で有効化を行います。
「設定」→「機能設定」→「セールス」→「見積」→「見積テンプレート」画面にアクセスします。
標準のページレイアウト同様にドラッグ&ドロップで見積に表示する項目を選択できます。
見積レイアウトの特徴は、関連する【取引先】【取引先責任者】【商談】【組織】【ユーザ】オブジェクトの
項目を数式なしに配置できるところです。
Tips:見積に会社のロゴを設定するには?
以下の手順で行います。
Configure(設定)、Price(価格)、Quote(見積)の頭文字をとっています。
見積作成のミスをなくし、承認プロセスをスピードアップできます。
今後は、請求・入金といった、会計につながるプロセスもカバーしていくそうです。
Salesforce標準の見積とSalesfroceCPQの見積の違いは以下の通りです。
いかがでしたか?改めて見積機能を紹介しましたが、LEXで見る見積は、Classicより分かりやすく、
使いやすくなっていると感じました。
いくつかの制約はありますが、スモールビジネスでのスタートアップなどでは、
十分に活用できるのではないでしょうか。是非、見積機能の活用をご検討ください。
また、もっと複雑な見積が必要、一画面でヘッダと明細をまとめて編集したいという皆様は、
弊社製品「SkyVisualEditor」のご利用もご検討ください。
みなさんこんにちは。
結婚して名字が変わりました、エンジニアの溝井です。
旧姓の植松として過去に記事を書いておりましたが、
これからは溝井としてどんどん投稿していきたいと思います!
先週HerokuのMeetupイベントに参加してきたので、今回もHerokuネタについて書いていこうかと思います。
Heroku Meetup #15 Heroku Ninja
Heroku開発では、Salesforce開発とは異なりGitベースの開発フローとなります。
その中で欠かせないのがコマンドラインツールの「Heroku CLI」です。
主にHerokuへのアプリケーションデプロイで利用しますが、
使いこなすと便利な機能が沢山あるので、ピックアップしていきたいと思います!
コマンドラインツールを取り上げるのは、非常に地味ですが、
一般的にGUIでの操作に比べて以下の利点があるかと思います。
特にHeroku CLIではアプリケーションやアドオンの管理が柔軟に対応できるため、
作業をHeroku CLI中心に寄せて作業ログをとったり、チーム内での作業共有に関しては有効な手段となります。
さっそくHeroku CLIのコマンドをみていきたいと思います!
インストールがまだの方は、以下のリファレンスに各OSのセットアップ方法が記載されていますのでご参照ください。
https://devcenter.heroku.com/articles/heroku-cli
動作環境
$ git push heroku master
$ heroku open
今回は、Heroku社が作成して公開している「heroku-accounts」というPluginを紹介させて頂きます。
Herokuを仕事でも利用されている方は、プライベートでもアカウントを持っていたりするなど複数のHerokuアカウントを取得しているケースが多いかと思います。
そんな時に通常のHeroku CLIだとCLI操作前にログアウト、ログインしてアカウントを切り替える必要がありますが、
「heroku-accounts」のPluginを利用するとあらかじめ利用アカウントを登録でき、すぐに切り替えることができるようになります。
$ heroku plugins:install heroku-accounts
personalという名称で個人利用目的アカウント追加:
$ heroku accounts:add personal Enter your Heroku credentials. Email: david@heroku.com Password: ******
workという名称で仕事用アカウント追加: ※認証はsingle sign-on (SSO)
$ heroku accounts:add work --sso Enter your organization name: my-company-name Opening browser for login... done Enter your access token (typing will be hidden): **********************************
※上記の例ではSSOで設定していますが、SSOはオプションなのでpersonal同様に普通の認証でアカウント登録可能です。
アカウント切り替え:
$ heroku accounts:set personal
アカウント一覧表示:
$ heroku accounts * personal work
現在のアカウント表示:
$ heroku accounts:current personal
アカウント除外:
$ heroku accounts:remove personal Account removed: personal
「heroku-accounts」では複数アカウントをすぐに切り替え出来て便利ですね!
この様な独自のプラグインを作成したい場合は、「Developing CLI Plugins」をご参照ください。
いかがでしたでしょうか。気になるコマンドは見つかりましたでしょうか?
最後に紹介した「Heroku CLI Plugins」に関してはHeroku社のGithubでいくつか「heroku-cli-plugin」Topicのついたリポジトリがありました。
他にも便利なPluginが公開されているかもしれませんので今後もチェックしていきたいと思います。
Heroku CLIは奥が深そうなので、今後もHerokuのリファレンスを中心にキャッチアップしていきたいと思います!
<参考>