LoginSignup
5
5

More than 5 years have passed since last update.

Apexトリガー上でYQLのデータを取得する

Last updated at Posted at 2014-09-30

概要

初心者用のSalesforceトリガーの仕組みを勉強するために作りました。

何を作る

書籍名が入力されたら、トリガーでGoogle Books API上の本を検索し、自動的に項目にセットする。

事前準備

実装した時に躓いたところ

  • 外部APIを呼ぶためのウェブサービスのcalloutメソッドを実装する
  • YQLからのデータを非同期で取得するので、@futureで書く
  • @futureは独立クラスで実装する必要がある。
  • JSONParserでいちいち取得するのが面倒なので、JSONからMapに変換。 Stackoverflow
  • Bookオブジェクトをそのまま渡せないので、Idのパラメーターで渡す。
global class YQLBridge {

    @future (callout=true)
    public static void searchGoogleBooks(String bookId) {
        Book__c book = [SELECT Name, Id FROM Book__c WHERE Id=:bookId];
        Http http = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20google.books%20WHERE%20q%3D%22'
            +book.Name+
            '%22%20AND%20maxResults%3D1&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&format=json');
        req.setMethod('GET');
        HttpResponse res = http.send(req);

        Map<String, Object> root = (Map<String, Object>)JSON.deserializeUntyped(res.getBody());
        Map<String, Object> query = (Map<String, Object>)root.get('query');
        Map<String, Object> results = (Map<String, Object>)query.get('results');
        Map<String, Object> jsonItem = (Map<String, Object>)results.get('json');
        Map<String, Object> items = (Map<String, Object>)jsonItem.get('items');
        Map<String, Object> volumeInfo = (Map<String, Object>)items.get('volumeInfo');
        String richStr = 'title :'+volumeInfo.get('title')+'<br >'+
            'subtitle :'+volumeInfo.get('subtitle')+'<br >'+
            'author :'+volumeInfo.get('authors')+'<br >'+
            'thumbnail : <img src="'+((Map<String, Object>)volumeInfo.get('imageLinks')).get('thumbnail')+'" />';
        book.Web_Results__c = richStr;
        update book;
    }
}
  • コントローラーは以下で実装する:
public static void populateInternetBooks(Book__c book) {
    YQLBridge.searchGoogleBooks(book.Id);
}
  • トリガーには以下で実装する:
trigger PopulateWebResults on Book__c (before insert, before update) {
    Book__c[] books = Trigger.new;
    for (Book__c b :books){
        if(b.Web_Results__c == NULL || b.Web_Results__c.trim().equals('')) {
            BookController.populateInternetBooks(b);
        }
    }
}

完成したソース

Github上で公開していますので、ご自由にカスタマイズしてください。

Salesforceではまだ一ヶ月勉強したばかりの初心者なので、ご指摘があればぜひお願いします。

5
5
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5