チームスピリットデベロッパーブログ

チームスピリット開発者のブログ

QAエンジニアが参画する時の7つの確認リスト

この投稿はチームスピリット Advent Calendar 2017 - Adventarの20日目の記事です。

adventar.org

こんにちは、QAチームの生井(id:riririusei99)です。
今年も残すところあと少しになりましたね。

はじめに

QAエンジニアは「テスト」や「品質保証」といった幅が広いテーマに対してリードするエンジニアです。
テストの自動化、テスト設計&テストマネジメント、開発チームのテストを改善していく役割など仕事内容は会社・チームによって異なるかと思います。 そんな中でどういった働き方を期待されているのかは認識にズレがないように把握している必要がありますよね。

今回のテーマはそんなQAエンジニアがチームに参加する前に確認しておくべき項目について、 ソフトウェアテストドキュメントの国際標準であるIEEE829-2008を参考に作ってみましたという内容です。

7つの確認リスト

  1. 目的
  2. テストアイテム&スコープ
  3. アプローチ
  4. アウトプット
  5. 参加するまでのタスク
  6. 役割
  7. あってはならないこと

1.目的

ここではなぜQAエンジニアが必要なのかを思い切って確認します。
プロダクトへの課題感、期待されていることが聞けるはずです。
目的を聞くことで目指すべき品質目標や今後のテスト計画が立てやすくなります。
どんなことを聞けばいいかわからない場合は、QAエンジニアやソフトウェア品質を大枠で捉えて分解して考えてみると良いかもしれません。

2.プロダクト&スコープ

携わるプロダクトについて現段階でわかっていることを確認します。
具体的にテストして欲しいバージョンや環境、開発フェーズといったことを聞くことで必要なものが見えてきます。 その他、既に十分テストしている機能がある場合など、テストするもの/しないものをわかっている範囲で確認しておきましょう。

3.アプローチ

目的を達成するためにどのような手を打つのかスケジュール、テスト体制などをすり合わせます。
開発スプリントとテストスプリントを別々に用意しテストする場合や、スプリント期間内にテスト期間に設けるなど参加するチームによってそれぞれ変わっていく部分だと考えています。
余裕があれば目的を達成したあとの話も確認できると良いです。(現在はテストの設計がメインだが、テストの自動化にも注力したい。など)

4.アウトプット

テストなどの活動の結果として何をアウトプットとするかあらかじめ決めておきます。
具体的な内容としてテストレポートやインシデントチケットなどが挙げられます。
同時にインプットとして提供してもらえる資料などを確認することも重要です。
テスト計画書やインシデントチケットの項目など、弊社では作成した成果物をなるべく使いまわせることを意識しながら作成しています。

5.参加するまでのタスク

参加するまでに準備しなければいけないタスクを洗い出します。
テストデータの準備や環境準備など、QAエンジニアだけで解決できないものがないか確認しましょう。

6.役割

QAエンジニアしかできない仕事や、開発メンバーに協力してもらう部分を明らかにします。
具体的な例で言うと「インシデントチケットの起票はQAが行い、原因調査などは開発メンバーが行う」ことや、 「大容量テストに向けた設計をQAが行い、データの作成と実施を開発者メンバーに担当する」
といった想定される仕事の中でどの部分でだれが役割を分担するか確認しておきましょう。

7.あってはならないこと

プロダクトにおける「あってはならないこと」などは聞いておくとテストの優先順位や、品質目標を決める助けになります。
今後リスクになりそうな部分について事前に聞いておきましょう。
ここで聞いた内容は当たり前品質における観点材料やリスクベースドテストの分析材料など、様々な場所で再利用ができます。

まとめ

開発チームに参加した時によく聞かれそうな、聞いておけばよかったと思った内容をまとめてみました。
IEEE829はテスト計画書の作成に使われ、テストにおける共通認識を用意するには有用です。また今回確認したチェック項目は時間の経過とともに変わっていくこともあるので定期的に見返してみることも重要だと思います。
QAエンジニアといっても自動化が得意な人、テストのプロセス改善が得意な人などいろんなタイプがいますので、アサインした人、された人の双方の理解が深まる手助けになればうれしいです。

プロダクトディベロップメントチーム解体新書!(技術・開発環境編)

みなさんこんにちは。松田(id:a-matsuda)でございます。
今回は、仲間も増えてきたプロダクトディベロップメントチーム(以下、PDチーム)を解体したらどうなる?という企画で、計2回の連載でお届けします♪ 今回は、技術・開発環境編!
PDチームメンバーに、マクロミル社のセルフアンケートシステムQuestantでアンケートを行い、その結果をまとめました。

あなたの役割を教えて!

PDチームでは、弊社で提供している働き方改革プラットフォーム”TeamSpirit”や"TeamSpirit HR"を始めとしたファミリー製品の開発を行っています。
チームには、開発エンジニアだけでなく、プロダクト開発に関わるさまざまな役割のメンバーがおり、一人二役という場合もありますので(たとえばフロントエンドもサーバサイドも両方担当しているメンバーがいる、スクラムマスターは兼任など)、延べ数での割合はこのようになりました!

f:id:teamspiritinc:20171219161931p:plain

それぞれの役割や、開発プロセスについては、きっと近々、チームリーダーやプロダクトマネージャーが記事にしてくれることと思います!(id:dackdive id:a-kura

仕事で使っているキーボードを教えて!

続いて、みんなどんな環境で仕事しているんでしょうか? PCは、MacBook Proが9割、一部のメンバーがWindowsマシンを利用しています。
そんななか、キーボードには、みんなの個性が滲み出ているような・・・気がしたので、聞いてみました!

f:id:teamspiritinc:20171219144659p:plain

キーボードこだわりのあるメンバーは1/3程度でしたね。
その中でも、プログラマーから人気が高いそうですが、使うのに少し気がひけるという意見もある Happy Hacking Keyboard を利用しているメンバーに聞いてみました。

  • 打ち心地が気持ちいい!最高!
  • 俺って、できるエンジニアなんじゃないか?という気分になる!

あ”ーなるほどね。その様子をご覧ください。※●ラセではありません。 f:id:teamspiritinc:20171219162952j:plain

仕事で主に使っているエディタを教えて!

開発で利用するエディタも、エンジニアのこだわりが出る部分ですよね!

f:id:teamspiritinc:20171219143845p:plain

サーバサイドエンジニアから根強い人気のある「Eclipse」に続いて、2015年にリリースされたマイクロソフトのソースコードエディタ「Visual Studio Code」が台頭しています。その後に「Atom」や「Vim」が続き・・・。
なぜ「Visual Studio Code」なのか、利用しているメンバーに聞いてみました。

  • とにかく、軽くで動きが早い!
  • VSCodeの拡張機能でSalesforceと繋げることができるんです、これじゃなきゃ。

あなたの好きな言語を教えて!

TeamSpiritでは、サーバサイド:Salesforce Force.com Apex(Javaライクな言語)、フロントエンド:JavaScript(いろいろライブラリも使いつつ)で開発をしています。
開発メンバーは、仕事だけでなく趣味でも開発を楽しんでいるメンバーが多いので、どんな言語が出てくるのがワクワク!

f:id:teamspiritinc:20171219151606p:plain

やはり、Java/JS強し!!
少し古いデータではありますが、GitHubの総プロジェクト数ランキング(2016/2時点)では、上位から、JS、Java、Python、Ruby の順なので、この辺りはエンジニアに好まれる言語ということかもしれませんね!
(ちなみに、私はオブジェクト指向Javaが好きです)

最近興味のある技術分野を教えて!

たくさん出てきました。ええ、たくさん出てきました。 まとめられません。無理やりまとめますと・・

  • 機械学習・AI系
    TeamSpiritにも取り入れていきたい機械学習やAI。みんなで勉強しましょう。
  • 自分の業務の幅を広げたい系
    フロントエンドのメンバーはバックエンドの知識、バックエンドのメンバーはフロントエンドの知識、QAエンジニアは自動テストのスキルを身に付けたいなど
  • チーム開発・リーン開発系
    開発におけるアジャイル開発(現在もやっていますがさらに深めたいのでしょう)、ビジネスにおけるリーン開発とは・・のようなこと。
  • その他
    アクセシビリティ、ドメイン駆動設計など、今の業務で直面しているものから、コンテナー技術(Docker、Kubernetesなど)、ブロックチェーン、VRなど・・・うーん、みんな興味の幅が広いなぁ。。
  • 番外編
    プログラミングパラダイム(手続き型, オブジェクト指向型、関数型etc)とソフトウェアの設計って、なんか壮大だぞ。君の興味は、一体どこへ向かうのか。。。

まとめ

最後に何かまとめたいと思ったのですが、「最近興味のある技術分野」のところで、無理にまとめてはいけない(まとめられない)ことに気づきました。
個性あふれるメンバーが、それぞれの力が発揮できる環境で、パワフルに仕事をしています。次回の「人・趣味編」は、もう少しはっちゃけますので、お楽しみに!

最後に

この投稿は チームスピリット Advent Calendar 2017 - Adventar 第19日目の投稿になります。 毎日面白い投稿が行われていますので、ぜひ最後までチェックしてください! adventar.org

Platform EventとElectronでChatter Desktop的なものを作る

この記事は弊社アドベントカレンダーの 11 日目の記事です。
投稿日と一致しないのはお察しください。

エンジニアの山﨑( id:dackdive )です。
少し前から役割がフロントエンドエンジニアからプロダクトマネージャーに変わり、現在はプロダクトの仕様検討をメインで行っています。日々精進です。

さて、最近は Einstein、Big Object、Salesforce DX などなど、開発者の興味を引く新機能が続々登場していますが
今回はその中でも個人的に興味のあった Platform Event を試してみようと思います。

Platform Event の特徴

Platform Event は Summer'17 で正式リリースされた 機能です。機能の概要は webinar や公式ドキュメントに譲るとして、個人的には以下のような点が特徴として挙げられるかと思います。

  • イベントを「イベントオブジェクト」という形で、カスタムオブジェクトと同じように定義できる
  • Salesforce イベントを送受信するための方法として、複数の選択肢がある(Apex やプロセスビルダーなど)
  • Salesforce 内だけでなく、Salesforce と外部のアプリケーションとの間でイベントを送受信できる
    • 一例として、webinar のデモ では Heroku アプリケーションと通信しています

機能の概要を聞いたとき、「あれ、これって Electron でアプリ作ったらローカルでも受信できるんだろうか?そしたらもうすぐ廃止される Chatter Desktop の代替アプリみたいなもの作れないかな〜(Chatter Desktop はポーリングだったし)」という気持ちになったので試してみた次第です。

なお、Platform Event についての基本的な知識は以下の Trailhead モジュールで学ぶことができます。

特に後者は、Salesforce 内ではありますがイベントを Lightning Component で受信する簡単なアプリケーションを作ってみることで Publisher 側、Subscriber 側両方のイメージがつかめるのでオススメです。
(この記事を書いた時点ではまだ英語ですが。。。)

コード

今回作成したサンプルはこちらに置いてあります。

実装:Publisher 編

ここからは実装の話です。まずは Publisher 側から。

イベントオブジェクトを定義する

まずはイベントオブジェクトを定義します。
クイック検索で「プラットフォームイベント」と検索すると該当の項目が見つかります。

イベントオブジェクトの登録手順の詳細は Trailhead で説明されているため省きますが、カスタムオブジェクトとほぼ同様の手順で定義できます。
カスタム項目については、今回は Chatter のフィードに相当する FeedItem オブジェクトのデータ定義 を眺めつつ、必要になりそうなものを適当にピックアップしました。
(結局メッセージ本文に相当する Body しか使わなかった)

f:id:dackdive:20171215034808p:plain

イベントの Publisher を定義する(プロセスビルダー)

イベントオブジェクトを定義したので、次はこれを Publish するしくみを作ります。
Salesforce から Publish するための手段はトリガ、プロセスビルダー、フローなどいくつかありますが、今回はさくっと試すためプロセスビルダーを使用します。
プロセスビルダーはイベントの Publisher 側にも Subscriber 側にもなれます。

f:id:dackdive:20171215035428p:plain

Publisher 側として定義する場合、はじめにイベント発火のトリガーとなるオブジェクトを選び(今回は「フィード項目」)、ルール適用時のアクション種別として「レコードを作成」を選びます。
対象のオブジェクトを選択するプルダウンで、カスタムオブジェクトに混じって先ほど定義したイベントオブジェクトも候補に表示されます。

最後に、イベントオブジェクトの各カスタム項目とフィード項目オブジェクトの各項目をマッピングしてあげれば完成です。

実装:Subscriber 編

続いて、イベントを Subscribe する Electron アプリの方に移ります。
Electron アプリ開発の経験はほとんどないので環境構築で消耗しないよう、また JS のライブラリは React&Redux しか書けないので、今回は「electron react redux boilerplate」などのキーワードで検索してヒットした jschr/electron-react-redux-boilerplate からスタートします。

※ 余談ですが、今思うと chentsulin/electron-react-boilerplate の方がいいかもしれません...

$ git clone https://github.com/jschr/electron-react-redux-boilerplate chatter-desktop
$ cd chatter-desktop

$ yarn
# または npm install

# yarn run develop で起動

jsforce と CometD をインストール

認証およびアクセストークンの取得に jsforce を使います。
また外部アプリケーションで Platform Event を受信するためには CometD が必要です。npm 経由でインストールできるパッケージ があるので、それを使います。

$ yarn add jsforce cometd

Subscriber の実装

最後に、イベントを Subscribe する部分の実装です。

// app/containers/Root.js
import { connect } from 'react-redux';
import Root from '../components/Root';
import { addFeedItem } from '../actions/feedItems';

import jsforce from 'jsforce';
import lib from 'cometd';
const cometd = new lib.CometD();

const mapStateToProps = (state) => {
  return state;
};

// NOTE: ここを自分の環境に置き換え
const USERNAME = 'username';
const PASSWORD = 'password';

const mapDispatchToProps = (dispatch) => {
  return {
    initialize: () => {
      // (1) 認証・アクセストークン取得
      const conn = new jsforce.Connection();
      conn.login(USERNAME, PASSWORD, (err, userInfo) => {
        // (2) CometD の設定
        cometd.configure({
          url: `${conn.instanceUrl}/cometd/41.0`,
          requestHeaders: { Authorization: `OAuth ${conn.accessToken}` },
          appendMessageTypeToURL: false,
        });
        cometd.websocketEnabled = false;

        // (3) 接続&イベントの Subscribe
        cometd.handshake((handshakeReply) => {
          if (handshakeReply.successful) {
            console.log('Connected to CometD.');
            const newSubscription = cometd.subscribe('/event/FeedItemPosted__e',
              (platformEvent) => {
                console.log('Platform event received: '+ (platformEvent.data.payload));
                dispatch(addFeedItem(platformEvent.data.payload));
              }
            );
          } else {
            console.error('Failed to connected to CometD.');
          }
        });
      });
    },
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(Root);

アプリケーションを Redux で作っているので多少関係ないところも含まれていますが、 initialize 関数の中身がメインです。
initialize はアプリケーションのルートコンポーネントがマウントされたタイミングで呼び出されるイメージです)

(1) 〜 (4) まで軽く補足します。

(1) 認証・アクセストークン取得

jsforce を使って認証している部分です。本来ユーザ名・パスワードはログイン画面のような形でユーザに入力させたものを使うべきですが端折ってしまってます。
認証に成功すると Connection オブジェクトからアクセストークンを取得できるようになります。

(2) CometD の設定

ここについては正直まだ設定内容を完全には理解しておらず、Trailhead のコード をそのまま流用しました。

CometD のエンドポイントは https://<インスタンス URL>/cometd/<API バージョン> となり、インスタンス URL は Connection オブジェクトから取得しています。
appendMessageTypeToURLwebsocketEnabled についてはなぜ false に設定する必要があるのかわかってませんが、これを指定しないとエラーになることは確認できました。

(3) 接続&イベントの Subscribe

接続部分については同様に Trailhead のコードをそのまま使っています。Subscribe するチャンネル名は

/event/<イベントオブジェクト名>__e

となります。
最後に、新しいイベントを受信するたび Redux の action を dispatch し、画面に描画しています。action, reducer および描画コンポーネントについては リポジトリ をご参照ください。

できたもの

f:id:dackdive:20171215045733g:plain

(左)Electron アプリ、(右)ブラウザ

UI まで手が回らなかったので、Chatter Desktop ぽさは一切ないですね。。。
あと <p> タグとか表示されてるのはリッチテキストなのを考慮していないからですね。

それでも期待通り near realtime なフィード表示は実現でき、Platform Event が Electron アプリでも受信できることを確認できました。よかった。

TODO

よくよく考えると、全ての投稿が流れてきてしまうので自分のフィードの内容とは違ってしまいます。。。
Chatter まわりのデータ構造を勉強せねばという気持ちになりました。

余談:Chatter Desktop の現状と今後

Chatter Desktop は Spring'17 で廃止され、これ以降に作成した組織では利用できなくなっていました。
参考:Spring'16 リリースノート
Spring'17 以前に作成した組織については引き続き利用が可能で、現在も動いています。

また、
Chatter デスクトップの廃止
によると、

Summer '18 リリース* をもって、Chatter デスクトップは廃止され、Salesforce によるサポートが終了します。その時点でこの機能は使用不可になり、Salesforce によるサポートの提供も終了します。

とあるので、これまで使えていた組織も 2018 年夏をもって使えなくなるんでしょうか。知らなかった。

気になる代替手段についてですが、Windows については Microsoft から 新しいデスクトップアプリ がリリースされていますが、Mac は今のところありません。果たして。。。

Google Homeから音声で出退社を記録する

家庭用のスマートスピーカー、まだ使いみちが思い当たらずに購入見送りのケースがほとんどでしょうか。ただ、これから家電と本格的に繋がってくると一気に普及していきそうで、市場規模としても2025年度に今年度比で9.2倍の成長が予測されていたりします。1

一方、オフィスにおいては、音声UIで業務が効率化できる分野も広がりつつあり、別の時間軸で導入が進みそうです。コミュニケーションロボットとして捉えると、こちらの市場規模は同期間で33.8倍!の成長予測です。

そんな折、Google Home Miniが各所で半額(税込3,240円)で買えるようでしたので、用途もあまり考えないまま入手。せっかくなので、音声によりTeamSpiritに対して出退社の打刻をする世界観を体感してみました。次のような会話で処理が行われます。

「OK, Google. 出社」
「TeamSpiritに出社を打刻します」

まずはデモ(動画)

こちらをご覧ください。


Google HomeからTeamSpiritに出社時刻を打刻する

どんな印象を持ちましたか?職場で使うイメージが湧きますでしょうか?

勤務表に記録されますので、企業に必要な36協定安全管理上の労働時間の把握がいつでも可能です。

実現方法(のポイントのみ)

今回はクイックに、ノンコーディング、TeamSpiritの標準機能で実現しています。処理の流れは次の様な感じです。

f:id:hwakabay:20171211192739p:plain

Google Assistant → IFTTT → GMail → Chatter → TeamSpirit

やったことは細かくは省きますが、以下の内容について設定しています。

1.Chatterの設定

メールでSalesforceのChatterに投稿する設定をします。

  • 勤怠投稿用のChatterグループを作成 ・・・①
  • グループへの投稿用メールアドレスを取得 ・・・②

2.TeamSpiritの設定

Chatterグループへの投稿により出退社を打刻する設定を行います。

  • Chatter打刻機能を有効化(システム設定の「Chatter 打刻を利用しない」をオフに)
  • 発言グループを設定(部署の発言グループに①のChatter グループを選択)
  • SalesforceユーザーのEmailにGMailアドレスを設定

3.IFTTTの設定

Google Assistantで音声で出退社を検知したら、GMailでChatterグループのメールアドレス充に投稿メールを送信させます。

  • ”This”に”Google Assistant”を指定(フレーズや回答を設定)
  • ”That”に”GMail”を指定(メール宛先に②のChatter投稿用メールアドレス、本文に”出社>”または”退社>”を設定)

以上、これだけでデモ動画の通りに動きました。

結びに

簡易的な設定による動作デモですので、本番運用で利用するにはいろいろ課題もあります。例えば以下のような点など。

  • 確実性の観点。打刻結果を受け取らないため、メール不着や二重打刻などにより打刻されないケースでも通知されません
  • 正確性の観点。打刻時刻はChatter投稿時刻となるため、メール遅延の場合は打刻も遅延となります
  • 端末制限への影響。スマホのGoogle Assistantから実行可能となり、IP制限している場合でも無力化されます
  • ユーザー認証への対応、メール運用ポリシー、その他、、。

このような前提ですので、本内容に関しての正式なユーザーサポートは致しかねますが、PCやスマホを使わずに自分の声で勤怠時刻を記録するこの世界観を試してみたい方は、ご参考にして頂ければと思います。

まだTeamSpiritをお使いでない企業様は、是非こちらからTeamSpiritが多くのユーザーに選ばれる理由をご覧ください!

この記事は「チームスピリット Advent Calendar 2017」の13日目です。
以上、若林(id:hwakabay)が執筆しました。

Slack×GAS 契約自動更新サービスの稟議忘れを防ぎたい!

こんにちは。開発チームで社内利用ツールの管理もしている松田(id:a-matsuda)です。
みなさん、開発に際して、いろんなクラウドサービスを利用しているのではないかと思います。

弊社でも

  • JIRA
  • Confluence
  • Cacoo
  • CirecleCI  などなど・・

様々なツールを利用して、開発プロジェクトやドキュメントの管理、開発工程の効率化などを行っています。 が、今回のテーマは、使っている開発ツールの便利な使い方、とかではありません!

こういったツールって、だいたいが契約自動更新ですよね?
再契約しなくて済むので、その点は非常に楽なのですが、反面、気づいたら社内の稟議期限が切れてしまいそうだった(しまっていた・・・汗!)なんてこと、ありませんか?

今回は、そんな危ない稟議漏れを防ぐ仕組みをSlack×GAS(Google Apps Script)で作ろうという内容です。

これまではどうしてた?

月初に1回、当月に更新切れになるものがないかをプロアクティブにチェックしていました。

困っていたこと

  • 管理するツールが20件を超えた時点で、自身の目が節穴になる。
  • 1ヶ月の無償期間を経て有償になるツールを利用したいというニーズが出てきた。
    この場合、2weeks検証したあとに、解約または契約(のあと、稟議)となるので、
    1ヶ月に1回じゃ間に合わない。

目的

自動更新されてしまう前に、漏れなく社内稟議、承認までを完了できるようにしたい。

実現したいこと

毎週月曜日10時に、契約しているクラウドサービスのうち、契約見直日(※)の14日前をきっているサービスがあったら、Slackに契約更新通知を行いたい。
(※解約通知が3ヶ月前というサービスもあります。弊社の場合は、解約通知日=契約見直日として、契約見直日の前に契約継続でいいかを判断したうえで、継続の場合は社内稟議をあげるルールとしています。)

使う技術要素

  • SlackのIncoming WebHooks
    Slackが発行するURLへPOSTするとSlackにメッセージが投稿される機能 api.slack.com
  • Google Apps Script
    Googleが提供するサーバーサイド・スクリプト環境

おおまかな流れ

1. スプレッドシートで契約一覧を作ろう
契約サービス名と契約見直日は、最低限管理をしておきましょう。 f:id:a-matsuda:20171212013126j:plain

2. SlackのIncoming WebHooksの登録しよう

  • https://(Slackドメイン名).slack.com/apps にアクセスします。
  • 上部に検索ボックスが表示されるので、そこで「Incoming WebHooks」という検索をすると、Incoming WebHooksの設定ページへと飛ぶことができます。
  • 「Add Configuration」をクリック後、投稿したいチャンネルを選択し、作成ボタンをクリックします。
  • 作成完了後、Webhook URLの項目に表示されるURLを次の章で使用します。

3. GASを作成しよう

function alertContract() {
    var mySheet = SpreadsheetApp.openById('シートID').getSheetByName('契約サービス一覧_sample'); //スプレッドシートを取得
    var lastRow = mySheet.getLastRow(); //スプレッドシートの最終行を取得
    var today = new Date(); //今日の日付を取得
  
    /* 契約見直日まで14日切っていたらSlack投稿 */
    for (var i = 2; i <= lastRow; i++) {
        var Di = mySheet.getRange(i, 4).getValue(); //サービス名(Di列)を取得
        var dateHi = new Date(mySheet.getRange(i, 8).getValue()); //契約見直日(Hi列)を取得
        var period = dateHi.getDate() - today.getDate(); //今日から契約見直日までの期間を取得
        if (period <= 14) { //2週間前に告知
          //通知文を作成
          var strText = "@matsuda.akiko " + Di + "の契約更新期限が迫っています。稟議を上げてください。期限:" + dateHi;
          //Slackへ投稿
          postSlack(strText);
        }
    }
}

function postSlack(strText) {
 
  //payload
  var payload  = { 
    'username'  : "Contract Notification",
    'text'      : strText,
    'link_names' : "1", //
  };
  var options = {
    'method'      : 'post'                 ,
    'contentType' : 'application/json'     ,
    'payload'     : JSON.stringify(payload),
  };
 
  // Webhook URL へPOSTする
  var url = 'https://hooks.slack.com/services/XXXX/XXXX/XXXX';  //「2.SlackのIncoming WebHooksの登録しよう」で払い出したURLを指定
  UrlFetchApp.fetch(url, options);
}

4. トリガーを登録しよう
「現在のプロジェクトのトリガー」アイコンをクリックし、トリガーの予定を登録して保存します。

f:id:a-matsuda:20171212014925p:plain

5. 無事Slackに投稿されました!
f:id:a-matsuda:20171212024256p:plain

つまづいたところ

  • チャネルに投稿するときに自分にメンションをしたかったのですが、最初はテキストにしか認識されませんでした。
    payloadの設定で、'link_names' : "1" に追加することで無事メンション認識されました!

こんなことにも応用してみた!

  • 私、採用も担当しております。googleカレンダーと連携し、翌日に面接に関連する予定が入っていたら、「ちゃんと面接の準備できてる?」とSlackで通知してくれる機能も作ってみました。 基本的な流れは一緒で、GASだけ下記ような感じで書いてみました。
function alertInterview() {
  //IDを指定してカレンダーを取得
  var calendar = CalendarApp.getCalendarById('カレンダーID');

  //翌日のイベントを取得
  var date = new Date();
 date.setDate(date.getDate() + 1);
  var events = calendar.getEventsForDay(date);

  //面談の予定があったらSlack投稿
  for (var i=0; i < events.length; i++) {
    var title = events[i].getTitle();
    var startTime = events[i].getStartTime()     
    var endTime = events[i].getEndTime()
    
    //面談の種類によりメッセージを振り分ける(実際はもう少し複雑・・)
    if(title.indexOf("面談") !== -1) {
      //通知文を作成
      strText = "@matsuda.akiko " + title + "面接の準備できてる?";
      //Slackへ投稿
      postSlack(strText);
    }  
  }
}

まとめ

大変簡単な技術ではありますが、Slack中心の生活を送っておられるエンジニアやチームマネージャー、私と同様に忘れっぽい方、忙しい方にも、Slackでのアラート通知は心強い味方になるでしょう。

おまけ

最後になりましたが、この投稿は チームスピリット Advent Calendar 2017 - Adventar 第12日目の投稿になります。 毎日面白い投稿が行われていますので、ぜひ継続してチェックしてください! adventar.org

Salesforce DX CLI から Apex を実行する

こんにちは、倉谷(id:a-kura)です。

今年もいつのまにかアドベントカレンダーの時期になってしまいました。皆さま、いかがお過ごしでしょうか?

さて、Salesforce DX CLI の紹介では、権限セットの付与やデータロードがデモされていましたが、実はもう一つ重要な機能があります。

そう、任意の Apex が実行できる機能です。

今回は、Salesforce DX CLI を使って、 Apex を実行する方法について紹介したいと思います。

f:id:a-kura:20171204124243p:plain

ヘルプ

まずは、Apex コードを実行するためのコマンドのヘルプを参照します。下記のコマンドを実行すると、ヘルプを表示できます。他のコマンドを調べるときも同様なので覚えておくと役立ちます。

$ sfdx help force:apex:execute
Usage: sfdx force:apex:execute [-f <file>] [-u <string>] [--json] [--loglevel <string>]

execute anonymous Apex code

Flags:
 -f, --apexcodefile APEXCODEFILE      path to a local file containing Apex code
 -u, --targetusername TARGETUSERNAME  username or alias for the target org;
                                      overrides default target org
 --json                               format output as json
 --loglevel LOGLEVEL                  logging level for this command invocation
                                      (error*,trace,debug,info,warn,fatal)

Executes one or more lines of Apex code, or executes the code in a local file.
Before you enter code, run this command with no parameters to get a prompt.
From the prompt, all commands are executed in a single execute anonymous request.
For more information, see "Anonymous Blocks" in the Apex Developer Guide.

Examples:
   $ sfdx force:apex:execute -f ~/test.apex

   $ sfdx force:apex:execute
   >> Start typing Apex code. Press the Enter key after each line,
   >> then press CTRL+D when finished.

コマンドラインから Apex コードを入力して実行する

では、コマンドラインから 直接 Apex コードを入力して実行してみましょう。 認証を済ませたあと、先ほどのヘルプで参照した内容を参考に実行してみます。

$ sfdx force:apex:execute

コマンドを実行すると、下記のようなメッセージが表示されて、入力待ちになります。

>> Start typing Apex code. Press the Enter key after each line,
>> then press CTRL+D when finished.

下記のように適当な Apex コードを入力して、CTRL+D を押下します。

System.debug('Hello, Astro!');

そうすると、実行結果が表示されます。 実行結果の内容を見ると、開発者コンソールから実行したときのログと同じものが表示されていることがわかります。

Compiled successfully.
Executed successfully.

41.0 APEX_CODE,DEBUG;APEX_PROFILING,INFO
Execute Anonymous: System.debug('Hello, Astro!');
23:41:42.11 (11567895)|USER_INFO|[EXTERNAL]|005xxxxxxxxxxxxxx|xxxxx@xxxxx.com|日本標準時|GMT+09:00
23:41:42.11 (11592457)|EXECUTION_STARTED
23:41:42.11 (11597237)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
23:41:42.11 (12249513)|USER_DEBUG|[1]|DEBUG|Hello, Astro!
23:41:42.12 (12311326)|CUMULATIVE_LIMIT_USAGE
23:41:42.12 (12311326)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

23:41:42.12 (12311326)|CUMULATIVE_LIMIT_USAGE_END

23:41:42.11 (12348943)|CODE_UNIT_FINISHED|execute_anonymous_apex
23:41:42.11 (13282152)|EXECUTION_FINISHED

ファイルから Apex コードを実行する

次に、Apex コードを保存したファイルから Apex コードを実行していましょう。 まずは、実行するための Apex コードを準備します。

ここでは、Apex コードが実行できるか試したいだけなので、先ほどと同じコードをファイルに保存します。

HelloAstro.apex
System.debug('Hello, Astro!');

先ほどのヘルプのとおり、ファイルを指定する場合は「--apexcodefile」または「-f」のあとにファイル名を入力します。

$ sfdx force:apex:execute --apexcodefile HellpAstro.apex

そうすると、先ほどコマンドラインから Apex コードを入力して実行したときと同じ実行結果になります。

活用方法

Apex コードが実行できると、どういった嬉しいことがあるのでしょうか?

実は、データの初期化などでオブジェクトのレコード間に相互参照などがあると、データインポートが難しくなることがあります。そういった場合には、Apex コードと組み合わせることで効率的にデータインポートができるようになります。

開発者がデータをクリアしたい場合、サンプルデータなどを一括作成する場合などには、Apex コードを準備しておくと、無駄な手間が少し省けるようになり、開発効率向上にも貢献できそうです。

また、オプション「--json」をつけて実行することで、実行結果をJSON形式で受け取ることができます。 JSON形式で受け取ることができれば、Jenkisやバッチ処理内で実行結果を条件判定するような処理を記述できるようになります。

シェルに組み込めるようになると、活用の幅も広がってきます。こういった柔軟性を与えることがこのコマンドのメリットと言えるでしょう。

むすび

Apex コードをコマンドラインから実行してみましたが、参考になりましたでしょうか?

Apex コードを実行できるようになることでかなり柔軟なことができるようになりますので、皆さまもよいアイデアがあれば共有してもらえると幸いです。

最後になりましたが、この投稿は チームスピリット Advent Calendar 2017 - AdventarSalesforce Platform Advent Calendar 2017 - Qiita 第2日目の投稿になります。

adventar.org

qiita.com

ハッピー・クリスマス!

Salesforce Developers Meetup #16 参加レポート

こんにちは、倉谷(id:a-kura)です。

今回の Meetup は雨が降っていたにもかかわらず、ほとんどの方が定刻に参加されていました。 参加人数と歩留まりを予想して会場をいつもの半分のサイズにしてもらっていたのですが、会場が満員になっていました。

プログラム

プログラムは以下のような感じでした。

リリースノート輪読

技術系セッション

  • Heroku Connect 苦肉の四苦八苦」(大久保英樹さん)
  • 「エンジニアがSalesforceを使って事業に貢献できること」(アドバンテッジ リスクマネジメント小泉剛さん)

LT

Meetup

www.meetup.com

感想

リリースノート輪読

Lightning Experienceへのマイグレーションが一段落して、機能的に充実してきたとともに新機能への投資が復活してきた印象があります。

Big Object、Platform Event、IoTなどはこれまで継続的に開発してきた機能をまとめあげて実戦投入してきています。 Trailheadが派手な宣伝をしているので目が行きがちですが、ビックデータ周りの機能強化は注目していきたいです。

技術系セッション

Heroku Connectを利用した事例がそれなりに増えてきて、ノウハウが溜まってきているように感じました。 Heroku Connectを利用した場合のインピーダンスミスマッチだけで拒絶反応を起こしてしまいがちです。 このインピーダンスミスマッチを乗り越えるためのノウハウ(苦肉の策)は、Heroku Connectの導入を検討されている方には参考になると思いました。

大久保さんの発表で言葉そのままではないですが、「発表資料を見るとHeroku Connectの辛みが出ているが、それ以上にHerokuとSalesforceを連携させることにメリットがある」ということをおっしゃっていたことが印象的でした。

LT

MiniHackの解答速報で定評のある弊社山崎よりMiniHackのふりかえり的なLTがありました。

www.slideshare.net

さすがの安定感あるLTでしたが、不安定な景品の処遇が気になるところです。 Visual Workflowネタは石井さんのLTと合わせて読み込むと、設定画面のアレなところとは裏腹にいろいろできそうでした。

宣伝

先日、このような投稿を見かけました。

美味しいご飯(まかない)を食べながらの勉強会が開催されるかも!?気になる方はconnpassのグループにジョインして待ちましょう!

teamspirit.connpass.com