外部サービス連携

リードの緯度経度取得と地図表示を切り分けて実装する

住所から緯度経度を取るだけなら、Salesforce標準のデータインテグレーションルールで足ります。カスタム画面に地図を出す場合に必要なGoogle側の実装と、キーを漏らさない設定を説明します。

2021.02.01

標準のジオコード機能で足りないか確認する

住所から緯度・経度を取りたいだけなら、Google APIキーを用意しなくても済む場合があります。Salesforceには、住所を自動でジオコードするデータインテグレーションルールが標準で用意されています。Lead・Account・Contactの住所項目を対象に、Salesforce自身のジオコーディングサービスがLatitude・Longitude・Geocode Accuracyの各項目を更新します。呼び出し元の組織がGoogleのAPIキーを持っている必要はありません。

  1. データインテグレーションルールを開く

    設定のクイック検索で「データインテグレーションルール」を開きます。

  2. 対象のルールを選ぶ

    リードの住所なら「Geocodes for Lead Address」を選びます。取引先の請求先・納入先住所、取引先責任者の住所にも、それぞれ専用のルールがあります。

  3. ルールを有効化する

    「有効化」ボタンを押します。値は上書きモードで更新され、以降は住所の変更を拾って自動でジオコードします。

すべてのデータインテグレーションルールの一覧。取引先の請求先・納入先、取引先責任者、リードの4件のGeocodesルールが並び、現在の状況はいずれも無効
標準で用意されているジオコードのルールの一覧です。リード・取引先・取引先責任者それぞれに専用のルールがあり、現在の状況が「無効」である点を見てください。
Geocodes for Lead Addressルールの詳細画面。データサービスはData.com Geo、現在の状況は無効で、右上に有効化ボタンが並ぶ
リード用ルールの詳細です。「すべてのレコードを更新(推奨)」にチェックが入っていることを確かめ、右の「有効化」を押します。
データインテグレーションルールを有効化する確認ダイアログ。すべてのレコードを更新する旨の警告が黄色い枠で出ている
有効化の確認です。既存のレコードがすべて更新されること、最終更新日時は変わらないことが書かれています。内容を読んでOKを押します。

⚠️ 更新は非同期です。有効化した直後や、住所を入力した直後には、まだLatitude・Longitudeが空のことがあります。少し時間を置いてから確認します。この機能はProfessional・Enterprise・Performance・Unlimited・Developerの各エディションで使えます。緯度・経度の値がレコードに入っていればよいだけなら、ここまでで足ります。

この記事で扱うのは地図に描画する話

標準の機能が用意するのは、レコードのLatitude・Longitude項目です。画面に地図を出し、そこにピンを立てて表示するところまでは標準機能の範囲外です。Visualforceやカスタムのページで、取得済みの緯度・経度をGoogleマップ上のマーカーとして描画したい場合は、ここから先の実装が要ります。

地図表示用のAPIキーを取得する

地図の描画にはMaps JavaScript APIを使います。取得先は、Google Cloud Consoleです。

  1. プロジェクトを作る

    Google Cloud Consoleでプロジェクトを新規作成します。

  2. Maps JavaScript APIを有効化する

    APIとサービスのライブラリから「Maps JavaScript API」を有効化します。

  3. APIキーを作成する

    認証情報の作成からAPIキーを発行します。例: AIzaSyXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

利用にはGoogle Cloudの請求先アカウントの登録が要ります。Maps JavaScript APIは従量課金で、SKUごとの月間の無料枠を超えた分に料金がかかります。想定より使う可能性があるなら、Cloud Console側で現在の料金と上限をご自身で確認してください。

APIキーには制限をかける

⛔ キーを制限なしで使わないでください。このキーはVisualforceページの <script> タグに埋め込まれるため、ページを開いた人には見えます。隠すのではなく、使える範囲を絞ります。

  • アプリケーションの制限:ウェブサイトのリファラー制限を使い、実際にページを配信するSalesforceのドメインだけを許可します
  • APIの制限:このキーで呼べるAPIを、Maps JavaScript APIだけに絞ります

制限のないキーが第三者に使われた場合、その分の課金はキーの持ち主の責任になります。

標準機能でカバーできない住所をApexからジオコードする

カスタムオブジェクトの住所など、標準のデータインテグレーションルールが対象にしていない住所を、その場でジオコードしたい場合は、ApexからGoogleのGeocoding APIをHTTP callout で直接呼びます。

Geocoding APIのキーは、クエリ文字列の key パラメータで渡す仕様です。指定ログイン情報のマージフィールドはHTTPヘッダーとリクエスト本文でしか使えず、URLのクエリ文字列には使えません。そのため、キーをApexのコードに直書きせずに扱うには、次のようにします。

  1. 指定ログイン情報を作る

    URLに https://maps.googleapis.com/maps/api/geocode/ を指定します。Googleのキーはヘッダーで渡す仕組みではないため、認証プロトコルは「認証なし」にします。

  2. キーの値をカスタムメタデータ型に持たせる

    キーの値そのものはApexのソースに書かず、カスタムメタデータ型のレコードとして保存します。デプロイに含めず、管理者が本番で直接値を入れられます。

  3. Apexでクエリ文字列に付与する

    実行時にカスタムメタデータ型からキーを読み、コールアウトのURLへその場で付け足します。

public class AddressGeocoder {
    public static void geocode(String recordId, String address) {
        String key = Google_Api_Setting__mdt.getInstance('Default').Geocoding_Api_Key__c;
        String endpoint = 'callout:GoogleGeocoding/json'
            + '?address=' + EncodingUtil.urlEncode(address, 'UTF-8')
            + '&key=' + key;
        HttpRequest req = new HttpRequest();
        req.setEndpoint(endpoint);
        req.setMethod('GET');
        Http http = new Http();
        HttpResponse res = http.send(req);
        System.debug(res.getBody());
    }
}

カスタムメタデータ型からキーを読み、住所をジオコードします。

Google Drive等のOAuthを使うGoogleサービスでは、Salesforceの外部ログイン情報に「Google認証プロバイダ」を設定する方法が使えます。ただしGeocoding APIはOAuthではなく、いまもこのAPIキー方式です。この記事の範囲では、外部ログイン情報のGoogle認証プロバイダは使いません。

⚠️ Apexのコールアウトには、1トランザクションあたり最大100回、コールアウト全体の累積タイムアウトは120秒という上限があります。レコードを1件ずつトリガーでジオコードする実装は、件数が増えた日に上限へ当たります。まとめてジオコードするなら、キューアブルやバッチApexに分けて呼び出します。

このサーバー側のキーにも、Geocoding APIだけを呼べるAPI制限をかけます。IPアドレス制限も使えますが、Salesforceの送信元IPは組織ごとに変わるため、記事に固定の数字は書きません。設定するなら、そのときのご自身の組織の値を確認してから使ってください。

Visualforceページとコントローラ

public with sharing class LeadMapController {
    private Map<Id, Lead> idLeadMap;
    public Id clickedLeadId { get; set; }
    public Lead clickedLead { get; set; }

    public LeadMapController() {
        this.idLeadMap = new Map<Id, Lead>(
            [SELECT Id, LastName, Latitude, Longitude
             FROM Lead
             WHERE Country = 'JP' AND Latitude != null]
        );
    }

    public String getJsonLeadList() {
        return JSON.serialize(this.idLeadMap.values());
    }

    public String getMapsApiKey() {
        return Google_Api_Setting__mdt.getInstance('Default').Maps_Js_Api_Key__c;
    }

    public void selectLead() {
        if (this.idLeadMap.containsKey(this.clickedLeadId)) {
            this.clickedLead = this.idLeadMap.get(this.clickedLeadId);
        }
    }
}

カスタムメタデータ型から地図表示用のキーを取得し、リードの一覧を返すコントローラです。

WHERE Country = 'JP' AND Latitude != null として、まだジオコードされていないリードを対象から外しています。キーはコントローラのゲッター経由で取得し、Visualforceのソースには書きません。

<apex:page controller="LeadMapController">
    <script src="https://maps.googleapis.com/maps/api/js?key={!mapsApiKey}&callback=initMap" async defer>
    </script>
    <script>
    var currentInfoWindow = null;
    function initMap() {
        var map = new google.maps.Map(document.getElementById('leadMap'), {
            zoom: 5,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        });
        var leadList = JSON.parse('{!JSENCODE(jsonLeadList)}');
        leadList.forEach(function (lead) {
            addMarker(map, lead);
        });
    }
    function addMarker(map, lead) {
        var position = new google.maps.LatLng(lead.Latitude, lead.Longitude);
        var marker = new google.maps.Marker({
            position: position,
            map: map,
            title: lead.LastName
        });
        var infoWindow = new google.maps.InfoWindow({ content: lead.LastName });
        marker.addListener('click', function () {
            if (currentInfoWindow) {
                currentInfoWindow.close();
            }
            infoWindow.open(map, marker);
            currentInfoWindow = infoWindow;
        });
    }
    </script>
    <div id="leadMap" style="height:300px;"></div>
</apex:page>

GoogleマップにLeadをピンで表示するVisualforceページです。

動作確認

  1. テスト用のリードを作る

    日本国内の住所を入れたリードを2件作成します。

  2. ジオコードされるのを待つ

    データインテグレーションルールの更新は非同期です。少し時間を置いてから、Latitude・Longitudeが入っていることをレポートかAPIで確認します。

  3. ページを開く

    作成したVisualforceページを開き、2件のピンが地図上に表示されることを確認します。

  4. ピンをクリックする

    ピンをクリックし、リード名の入った吹き出しが出ることを確認します。

Googleマップ上の東京周辺に赤いピンが2本立ち、片方の吹き出しにリード名が表示されている
完成した画面です。ジオコード済みのリード2件がピンになり、クリックするとリード名の吹き出しが開きます。

ここで間違えやすい

間違い何が起きるか
データインテグレーションルールを有効化し忘れるLatitude・Longitudeが空のままで、ピンが出ません
地図表示用のキーにリファラー制限をかけない第三者にキーを使われ、想定外の課金につながります
キーをMaps JavaScript APIだけに制限しない他のGoogle APIにも同じキーが使われてしまいます
サーバー側のGeocoding APIキーをApexのソースに直書きするリポジトリに残り、漏れても気づけません
大量のレコードをトリガーで1件ずつジオコードする1トランザクション100回のコールアウト上限に当たります

確認した環境

  • 2026年9月/Salesforce Summer '26(APIバージョン67.0)時点の公式ヘルプと、Google Maps Platformの公式ドキュメントで、データインテグレーションルール・Apexのコールアウト上限・Geocoding APIの課金とキー制限を確認しています
  • コードはAPIバージョン67.0で書いています

まとめ

  • 住所から緯度・経度を取るだけなら、標準のデータインテグレーションルールで足ります。Google APIキーは要りません
  • 地図にピンを表示するには、Maps JavaScript APIと専用のキーが別途必要です
  • 表示用のキーはリファラー制限とAPI制限の両方をかけます。制限のないキーの課金は自己責任です
  • 標準機能の対象外の住所をApexからジオコードするなら、キーはカスタムメタデータ型に持たせ、ソースには書きません
  • Apexのコールアウトは1トランザクション100回・累積120秒が上限です。大量件数はキューアブルやバッチApexに分けます

参考:当時の画面

記事を最初に書いた当時の画面です。いまの手順と違うところは、各画像の説明に書いています。

Salesforce Classicのホーム画面。左下にクイック検索の入力欄があり、上部にLightning Experienceへの移行を勧めるバナーが出ている
作業の起点は設定画面のクイック検索です。ここに「データインテグレーションルール」と入力します。
Google Cloud Consoleのリソースの管理画面。上部にプロジェクトを作成・フォルダを作成のリンクが並ぶ
リソースの管理です。上部の「プロジェクトを作成」から始めます。
新しいプロジェクトの作成画面。プロジェクト名と場所の入力欄があり、下に作成ボタンが並ぶ
プロジェクトの新規作成です。プロジェクトIDは後から変更できない旨の注意書きを見てください。
Google Cloud Consoleの左メニューを開き、APIとサービスからダッシュボードを選ぼうとしている画面
プロジェクトを作ったら、左メニューの「APIとサービス」へ進みます。
APIとサービスのダッシュボード。使用できるAPIはまだありませんという案内が出ている
作ったばかりのプロジェクトです。有効なAPIがまだ1つもない状態から始めます。
APIライブラリのマップ分類。Maps SDK for Android、Maps SDK for iOS、Maps JavaScript APIの3枚のカードが並ぶ
APIライブラリです。似た名前が並びますが、ウェブページに地図を出すのは「Maps JavaScript API」です。
Maps JavaScript APIの詳細画面。Maps for your websiteという説明の下に有効にするボタンがある
Maps JavaScript APIの画面です。「有効にする」を押して、このプロジェクトで使えるようにします。
APIとサービスのメニューを開き、認証情報を選ぼうとしている画面。右上に無効にしますのリンクが見える
APIを有効にしたあと、同じメニューから「認証情報」へ進みます。
認証情報画面で認証情報を作成のメニューを開き、APIキー・OAuthクライアントID・サービスアカウントの選択肢が出ている
認証情報の作成メニューです。いちばん上の「APIキー」を選びます。
APIキーを作成しましたというダイアログ。キーの表示欄の下に、本番環境での不正利用を回避するためキーを制限するよう促す警告が出ている
キーが発行された直後です。この場で「キーを制限」へ進むよう促されている点を見てください。キーの値は伏せています。

Salesforceの導入・運用についてご相談ください

導入前の検討から、お使いの環境の改修・運用、AIとの連携まで承ります。状況を伺ったうえで、進め方をご提案します。