Salesforce と SendGrid でコンタクトを同期する方法


現代、Eメールはもはや業務にかかせないインフラの1つとなりました。Eメールはビジネスの場において必須のツールですが、そんなメール配信も今や SaaS の時代です。
メール配信サービスの1つに SendGrid があります。SendGrid を利用すれば、顧客や見込み客に一斉にメール送信を行うことができます。ですが、SendGrid はあくまでメール配信サービスであり、顧客の管理自体は別のシステムで行うことになります。そのため、顧客を管理しているシステムから SendGrid へデータを同期できると便利です。

ここでは、Salesforce で管理している取引先の情報をSendGrid に同期するサンプルアプリケーションを開発してみます。
CDataドライバーを利用すれば、こういったデータ同期を行うアプリケーションの作成を行うことができます。

このアプリケーションの概要は次の通りです。

  • Visual Studio 2015 C# による Windowsフォームアプリケーション
  • GUIコンポーネントを駆使して可能な限りコーディングレスを目指す
  • Salesforce および SendGrid からデータを読み込む
  • インポートしたい行を選択して、Salesforce から SendGrid へデータをインポートする

それでは、このサンプルアプリケーションの開発手順を見ていきます。

ソースコード

このサンプルアプリケーションのソースコードはこちらからどうぞ。

※ソースコードについて補足
このソースコードでは接続情報をアプリケーションの設定に格納しています。
動作させる際は、アプリケーション設定のConnectionStringSalesforceにSalesforce用の接続文字列を、ConnectionStringSendGridにSendGrid用の接続文字列を設定してください。
それぞれの接続文字列は以下のようになります。
Salesforce → Password=<パスワード>;Security Token=<セキュリティトークン>;User=<ユーザ名>
SendGrid → Password=<パスワード>; Username=<ユーザ名>

CData製品のインストール

まずは CData Software をインストールします。今回必要になるのは、次の2つです。

プロジェクト作成

Visual Studio を起動し、新しいWindowsフォームアプリケーションのプロジェクトを作成します。

参照設定

インストールした CData Software の2製品には、いくつかのADO.NETアセンブリが含まれています。
今回必要になるのは次の2つのDLLですので、これらをプロジェクトの参照設定で追加します。

  • System.Data.CData.Salesforce.dll
  • System.Data.CData.SendGrid.dll

データ接続を作成

Salesforce および SendGrid へのデータ接続を作成します。
以下のオンラインマニュアルを参考にして、2つのデータ接続を作成します。
Salesforce用
SendGrid用

実装

フォームの作成

メインのフォームを追加します。
このフォームには、次のコンポーネントを追加します。

  • データを表示するためのデータグリッドビュー×2 (左がSalesforce、右がSendGrid と対応する)
  • インポートを実行するボタン
  • SendGridのデータのリロードを実行するボタン

データグリッドビューのデータソースを設定

追加したデータグリッドビューに、データソースの設定を行います。
左側のデータグリッドビューで「DataGridView タスク」→「データソースの選択」→「プロジェクト データソースの追加」を選択します。

「データソースの種類の選択」では「データベース」を選択して「次へ」ボタンをクリックします。

次の画面では「データセット」を選択して「次へ」ボタンをクリックします。

データ接続の選択では、データ接続を作成で作成したSalesforceのデータ接続を選択して「次へ」ボタンをクリックします。

次の画面で接続文字列をアプリケーションに保存するかどうか選択できますが、ここでは任意に選択し、「次へ」ボタンをクリックします。

最後にデータベースオブジェクトの選択を行います。
今回はSalesforceの「取引先責任者」を対象とするので、Contactのチェックボックスにチェックを入れます。
データセット名は SalesforceDataSet として、「完了」ボタンをクリックします。

同じようにして、SendGrid側もデータソースの設定を行います。
SendGrid側は、Recipientsをデータベースオブジェクトとして選択します。

これで、データグリッドビューへのデータの読み込みまでが行えるようになりました。ここまで、全くコーディングは必要ありません。
メインフォームには、データ読み込みのためのコードが自動生成されています。

// TODO: このコード行はデータを 'sendGridDataSet.Recipients' テーブルに読み込みます。必要に応じて移動、または削除をしてください。
this.recipientsTableAdapter.Fill(this.sendGridDataSet.Recipients);
// TODO: このコード行はデータを 'salesforceDataSet.Contact' テーブルに読み込みます。必要に応じて移動、または削除をしてください。
this.contactTableAdapter.Fill(this.salesforceDataSet.Contact);

インポート処理

フォームデザイナで「インポート」ボタンをダブルクリックして、クリック時の処理を実装します。

private void btImport_Click(object sender, EventArgs e)
{
    var sendGridMap = this.dgvDestination.Rows
        .Cast<DataGridViewRow>()
        .Select(o => (SendGridDataSet.RecipientsRow)((DataRowView)o.DataBoundItem).Row)
        .ToDictionary(o => o.Email, o => o);

    var selectedList = this.dgvSource.Rows.Cast<DataGridViewRow>()
        .Where(o => o.Selected)
        .Select(o => (SalesforceDataSet.ContactRow)((DataRowView)o.DataBoundItem).Row)
        .ToList();


    this.btImport.Enabled = false;

    Task.Factory.StartNew(() =>
    {
        var processed = 0;

        foreach (var selected in selectedList)
        {
            Invoke(new Action(() => this.Text = "処理中... (" + (processed + 1) + " / " + selectedList.Count + ")" ));

            if (sendGridMap.ContainsKey(selected.Email) || selected.IsEmailNull())
            {
                continue;
            }

            this.recipientsTableAdapter.Insert(
                DBNull.Value, DBNull.Value, DBNull.Value,
                selected.Email, selected.IsFirstNameNull() ? "" : selected.FirstName, selected.LastName,
                DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value, DBNull.Value);

            processed++;
        }
    })
    .ContinueWith(task =>
    {
        // エラー処理は省略

        Invoke(new Action(() =>
        {
            this.btImport.Enabled = true;
            this.Text = "完了";
        }));
    });
}

リロードのボタンの処理も実装しておきましょう。
リロードボタンの処理はたったこれだけです。

private void btReload_Click(object sender, EventArgs e)
{
   this.recipientsTableAdapter.Fill(this.sendGridDataSet.Recipients);
}

実装は以上です。

実行

アプリケーションを起動すると、データグリッドビューにデータが読み込まれます。

移行したい行を選択して「インポート」ボタンをクリックすると、選択したデータが SendGrid に登録されます。
ただ、SendGridにデータが反映されるまで少し時間がかかるようです。少し待ってからリロードボタンでデータをリロードし、データが登録されたことを確認します。