SalesForceの予測結果をAWSを経由してGCPに持ってきた話

# はじめに

株式会社LITALICOでエンジニアをしています@yknoguchiです。
この記事は[『LITALICO Advent Calendar 2023』](https://qiita.com/advent-calendar/2023/litalico)24日目の記事です。

12月10日にも１本目の記事を挙げていますので、そちらもよろしければ覗いてみてください。→ [本当に最低限だけ覚えて一瞬で使い始めるPolars入門](https://qiita.com/yknoguchi/items/be49932d7f9061333954)

:::note info
この記事は施策に対しての試行錯誤をそのまま記載しています。そのため、どのような問題にどのような観点で対処していったのか、といったふうに読んでいただけると幸いです。
:::

# 忙しい人向け３行でまとめ

- Salesforce（以下、SF）のCRM Analyticsでいろんなデータの予測・CSVでダウンロードできる
- GCP LookerStudioでダッシュボードを作ろうとしたがデータの移動が困難だった 
- SFとGCPの間にAWSを挟んだら実装できた

# SF CRM Analyticsとは

そもそもSalesforceが何かというところから説明します。

> Salesforce は、より多くの商談を成立させ、想像を超えたサービス体験を提供するためのクラウド型ソフトウェアを提供している企業です。
私たちの CRM である「Customer 360」は、営業やカスタマーサービス、マーケティング、EコマースからIT部門まで、全員が顧客データを中心に仕事を進めることを可能にします。
（[Salesforce公式サイト](https://www.salesforce.com/jp/products/what-is-salesforce/)より引用）

公式サイトにもこのように書かれている通り、顧客の情報を一括管理し、それを営業や成約に結びつけることに強みを持ったサービスを展開しています。

そして、CRM AnalyticsとはAIを搭載したSFの分析プラットフォームです。

SFの中に保存した顧客データをAIで学習させることで、あらゆる分析が可能になります。

## 利点

- SFの中にある業務データを用いてあらゆる予測ができる
- コードが書けなくてもブラウザ上から学習・予測が可能
- 予測結果がなぜそうなったかの予測因子や、予測スコアを上げるための改善ポイントを見れる機能がある
- 予測スコアの表示が簡単
- ある程度のデータへの理解があればエンジニアでなくても使用できる
    - むしろ、データへの理解が深い人が触りやすくなるため開発効率が上がる可能性がある

普段からSFを利用して業務をこなしていると、自ずとデータが溜まっていくと思います。機械学習を行うには大量のデータがあった方が有利なため、この点は非常に大きいです。

そして、そうやって溜まった大量のデータを、「レシピ」と呼ばれるデータ処理プロセスを表したノードをブラウザ上で編集することで、機械学習にかけることができます。なので、機械学習を行うための複雑なコードは必要ありません。

もちろん、正しく学習を行うためには、データの扱い方に理解の深いデータサイエンティストは必要だと思います。しかし、それでも非エンジニアの人たちがどんどん学習を回していけることは、大きなメリットです。現場感覚を持っている人が学習を回せるとなると、尚更です。

## 惜しいところ

- 予測結果表示の機能が若干弱い
    - ノーコードなので仕方ない部分はある
- 料金が高い
    - 予測結果を見るためには学習する時と同じCRM Analyticsライセンスを取らないといけない
    - 一部の人間が予測してスコアだけをみたい人が多い時に料金が高くなる

メリットを挙げてきましたが、やはりデメリットもあります。

上に書いている通りなのですが、カスタマイズ性は低いです。特に予測結果の表示のオプションは少なく感じます。

メリットのところに書いたのですが、予測結果に対してスコアを上げるための「改善ポイント」を表示させることができます。例えば、「この顧客はこっちの商品の方が向いているかもしれない」と言ったものです。これはとても強い機能だと思うのですが、例えば、その結果に対して「改善ポイントとして出す商品は新表品のものに限らせたい」と言ったフィルタリングのような機能は、触った感じ見当たりませんでした。（もしあるのでしたら申し訳ありません。）

また、予測結果を見るためには、高額なCRM Analyticsライセンスを持っておく必要があります。そのため、5人で予測モデルを作成して、1000人規模のスタッフでスコアを確認するためには、合計1005人のアカウントを取得しなければいけません。

# やったこと

上記のメリットデメリットを踏まえて、以下の施策を行うことにしました。

## 第一段階

### 目標

SFの予測結果をGCP BigQueryに移動→LookerStudioで予測結果の表示

### 内容

実はSFにはモデルで予測した結果をローカルPCにCSV形式でダウンロードする機能があります。
そのため、ダウンロードしたデータをBigQueryに定期的にアップロードし、それをLookerStudioでビジュアライズすることで、上記のデメリットを消すことができないかを考えました。

#### 実装１（簡易実験）

そのため、まずはSFからローカルに落としてきたCSVをBQにアップロードすることを試しました。
その結果、BQにアップロードができ、かつLSでスコアや因子の表示を行うことができました。

なので、簡単に目標が達成できそうだ！と思っていました。この時は。

#### 実装２

簡易実験がうまくいったので、次のステップに進みました。それが、リモートサーバー上からSFの予測結果を落として、BQで自動取り込みを行うことです。

結果、これは失敗に終わりました。理由は単純で、サーバー上からSFにログインができなかったからです。

通常、ローカルPCでCSVをダウンロードするときには、コンソールを用います。しかし、（僕個人の印象としては）珍しく、コンソールからログインするときに、認証は自動で立ち上がるブラウザから行います。そしてこれが曲者でした。

リモートサーバーからSFにログインするときに、ブラウザを介したこの認証を行うことができませんでした。少なくとも僕個人が調べた範囲では、認証方法をブラウザではない方法にするやり方は見つかりませんでした。また、ブラウザを介した認証をサーバーから行う方法を思いつくだけの実装力も、僕にはありませんでした。

なのでこの方法を断念。別のやり方を模索することにしました。

## 調査

前回の失敗を踏まえて、なんとかSFの予測結果をBQに持っていく方法がないか、調査を行いました。

上にも書いた通り、他の認証方法も探しましたが、見つからず。

そんな中、しばらく公式のドキュメントを漁っていると、
「[Aamazon S3 出力設定](https://help.salesforce.com/s/articleView?id=sf.bi_integrate_connectors_output_amz_s3.htm&type=5)」
という文字があるではありませんか！！

どうやら調べたところ、なぜかSFからGCPには出力はできないがS3には出力できる、ということでした。

これになかなか気が付かなかったのは、僕のライセンス問題がありました。僕はCRM Analyticsのライセンスを持っていましたが、権限が足りていなかったようで設定画面にこの項目が表れていなかったのです。

調査に詰まったときに、一通りSFの画面のボタンを片っ端から押すということをしていたのですが、、、。そういうのも大事な時はありますが、やはりドキュメントを探すという基本の基本が大事だということが思い知らされました。

:::note info
公式ドキュメントを読むことはとても大切
:::

## 第二段階

### 目標

SFの予測結果をAWS S3を経由してBigQueryに移動

### 内容

調査でS3になら予測結果が出力できることが分かり、かつS3上のCSVをBQで読み込むことが可能だということが分かったため、S3を経由してBQにデータを送る実装を行なっていくことにしました。

実装の際には、それぞれのサービスの初期設定を事前に済ませておき、その後にそれぞれを接続していく方針で進めました。

### AWS S3の設定

バケットを作成します。これは普段やっている手順で進めて大丈夫でした。

バケットを作る際に、後々必要になる以下の情報をメモしておきます。

- AWSアカウント
- バケット名
- 必要なアクセス権
- 取り扱うデータ

また、この時点でバケットの中にフォルダを１つ以上作成をしておきます。

:::note info
後でバケット内のフォルダを指定する場面があるため、ここで先に作っておくと後の工程が少しだけ短縮できます。
:::

#### GCP BigQueryの設定

こちらも先に、データを入れる場所を用意しておきます。
以下の３つを設定しました。

- データベース
- テーブル
- スキーマ

#### SF CRM Analytics

ここから、それぞれの接続を作成します。

SFではレシピからデータの予測を行いますが、そのレシピの中にS3の出力ノードを織り込む必要があります。そしてそのためには、設定画面から「Amazon S3 出力接続」を有効化する必要があります。

もしも設定画面からその項目が見られない場合は、僕と同様に権限が足りていない可能性があるため、権限をもらうか権限を持っている人に頼みましょう。

有効化したら、出力設定を行えるようになるので、先ほどメモした以下の内容を入力します。

- S3のアクセスキー
- シークレットアクセスキー
- リージョン
- バケット名
- S3のURI

ここまで設定をすると、レシピでノードを追加する際にS3出力が追加できるようになっているので、それを選択し追加します。
このときにノードの設定で、バケット内のオブジェクトを選択する必要があります。ですので、あらかじめ作成しておいたバケット内のフォルダ名を入力します。

#### BigQueryのデータ転送設定

次にS3とBigQueryを接続します。
BigQuery側で必要な情報は以下のとおりでした。

- S3のアクセスキー
- シークレットアクセスキー
- バケット名

BigQueryのメニューから「データ転送」を選択→「転送の作成」を選択します。
あとは表示内容に従って、設定を行なってください。得に以下の設定を考えるといいかと思います。

- WRITE_TRUNCATEに設定
    - データをどのように保存するか（上書きか追記）。今回は上書きを選択。
- 改行やヘッダーを無視する設定
    - 今回のデータには、データ内に改行情報が入っており、それでエラーが多発しました。

## 第二段階の問題と対策

さて、接続設定も終わりあとは実行するだけだと思っていましたが、うまくいきませんでした。それは、以下のような問題があったからです。

- S3に出力する時はCSVが分割された
- CSVの中にヘッダー情報が入っていなかった
### SF→S3出力の問題点

S3に保存されたデータが複数のファイルに分けられていました。また、CSVにはヘッダーの情報が入っていませんでした。では、どこにヘッダー情報があったかというと、同ディレクトリ内に生成されたjsonファイルに保存されていました。
また、どうやらCSVファイルが一定サイズよりも大きいとデータが分割され、複数のCSVに分けられる仕様のようでした。

そのため、以下の対策をしなければいけません。

- 分割されたCSVファイルを統合
- jsonからヘッダーを読み込みCSVに追記

### 対策

上記の対策はAWSのLambdaで行うことにしました。
SFからCSVが作成されたことをトリガーに発火するようにしています。

# まとめ

## 最終的な全体図

最終的な構成図は以下の通りになりました。

![SLtoLSやったこと.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615860/fb29d6a3-fcf7-79f3-2ec0-22fbfcee6d7f.jpeg)

SFの予測とBQへのデータ取り込みはスケジュール化できるため、あとはそれを設定すれば自動で情報が更新されます。あとはLookerStudioでスコアを表示すれば完成です。

:::note warn
この内容を実装し終わったタイミングで、BigQueryのデータ追加方法にSalesforceが追加されてました（ベータ版）。今後はこのような遠回りをしなくても、気軽にデータ移行ができるかもしれないです。
:::

# 終わりの挨拶

一番最初に書きましたとおり、この記事は『LITALICO Advent Calendar 2023』24日目の記事です。

そして明日は最終日！
明日は@yuyaichihashiさんと@az_hさん、@nobookさんが担当されます。お楽しみに！！