Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

概要

初心者用の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ではまだ一ヶ月勉強したばかりの初心者なので、ご指摘があればぜひお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした