SFDCのデータを抽出してAPIにPOSTする
SaleceForceのデータをCSVにてS3にアップするというのをやってみたけど、今回はAPIで連携する必要がでてきたのでAPI連携のapexを作ってみました。Pardotからフォームデータを受取ってバッチで動かすので、スケジューラで登録してAPIを都度、呼出すという感じになります。能力が低いのでJSONをapexで扱うのはかなりつらかったです。
いい方法あったら聞きたい。
----------
GetEnvironmentTest
----------
----------
SoqlOperateTest
----------
----------
PutBodytoApiTest
----------
----------
SendApiControllerTest
----------
https://gawatari.com/apexlumpdml/
https://salesforce.stackexchange.com/questions/128742/cannot-convert-boolean-to-string
・JSON出力
https://qiita.com/sikj/items/1b0f51d3f9f119dc322c
https://jappy.hatenablog.com/entry/2017/01/29/020908
https://developer.salesforce.com/forums/?id=9062I000000gAa8QAE
https://qiita.com/one-kelvin/items/3d382bec836ad13d4c46
http://maroyaka.hateblo.jp/entry/2016/04/28/191408
いい方法あったら聞きたい。
◆プログラム群
1)環境変数抽出
GetEnvironment----------
public class GetEnvironment { // 環境変数をカスタム設定から取得する public Map----------GetEnv(){ try { Map settingMap = EnvironmentVars__c.getAll(); Map MapEnv = new Map (); for (String key : settingMap.keySet()) { EnvironmentVars__c env = settingMap.get(key); MapEnv.put(key,env.EnvParam__c); } return MapEnv; } catch(Exception e) { System.debug('Exception caught: ' + e.getMessage()); system.debug(e.getLineNumber()); return null; } } }
GetEnvironmentTest
----------
@isTest(SeeAllData=true) private class GetEnvironmentTest { @isTest static void testGetEnv() { Map----------m1 = new Map (); GetEnvironment ge = new GetEnvironment(); m1 = ge.GetEnv(); for (String sKey:m1.keySet()){ if(sKey == 'ApiKey'){ System.assertEquals(sKey ,'ApiKey'); } if(sKey == 'EndpointURL'){ System.assertEquals(sKey ,'EndpointURL'); } } System.debug(m1); } }
2)SOQLを使用してデータ抽出
SoqlOperate----------
public class SoqlOperate{ //SOQLでデータを抽出 public List----------GetLeads(){ try{ String queryString = 'SELECT ' + 'Id,LastName,FirstName,Phone,Email ' + 'FROM Lead ' + 'WHERE send_stat__c != \'SEND\''; List leads = Database.query(queryString); if(leads.isEmpty()){ leads = new List (); } return leads; }catch(Exception e){ System.debug('Exception caught: ' + e.getMessage()); System.debug(e.getLineNumber()); return null; } } //抽出データをJSONのリストに変換 public List RecordsTransferJson(List OriginJson){ try{ List body = new List (); Integer cnt = OriginJson.size(); if(cnt==0){ throw new QueryException(); } for(Lead l : OriginJson){ String str_body = '{' + '"Id":' + '"' + l.Id +'"' + ',' + '"LastName":' + '"' + l.LastName +'"' + ',' + '"FirstName":' + '"' + l.FirstName + '"' + ',' + '"Phone":' + '"' + l.Phone + '"' + ',' + '"Email":' + '"' + l.Email + '"' + '}'; body.add(str_body); } return body; }catch(Exception e){ System.debug('Exception caught: ' + e.getMessage()); System.debug(e.getLineNumber()); return null; } } //送信ステータス更新 public Boolean UpdateLeadsStatus(String target_id){ try{ Lead LeadtoUpdate = [SELECT Id,send_stat__c FROM Lead WHERE Id =: target_id]; LeadtoUpdate.send_stat__c = 'SEND'; update LeadtoUpdate; return true; }catch(Exception e){ System.debug('Exception caught: ' + e.getMessage()); System.debug(e.getLineNumber()); return false; } } }
SoqlOperateTest
----------
@isTest(SeeAllData=true) private class SoqlOperateTest { @isTest static void GetLeadsTest(){ SoqlOperate sq = new SoqlOperate(); List----------li = sq.GetLeads(); } @isTest static void RecordsTransferJsonTest(){ SoqlOperate sq = new SoqlOperate(); List leads = [SELECT LastName,FirstName,Phone,Email FROM Lead]; List s11 = sq.RecordsTransferJson(leads); System.debug(s11); List dm; List s12 = sq.RecordsTransferJson(dm); } @isTest static void UpdateLeadsStatusTest(){ SoqlOperate sq = new SoqlOperate(); List leads = [SELECT Id,send_stat__c FROM Lead WHERE send_stat__c != 'SEND']; for (Lead l : leads) { System.debug(l.id); Boolean b = sq.UpdateLeadsStatus(l.id); System.debug(b); } } }
3)APIの呼出し
PutBodytoApi----------
public class PutBodytoApi { //受取ったJSONからidを取り出し //オブジェクト定義 class Person{ String Id; String LastName; String FirstName; String Phone; String Email; } /* Id取得 */ @TestVisible private static String ReturnId(String str_body){ try{ //引数チェック if(str_body == null){ throw new NullPointerException(); } //JSON文字列をオブジェクト変換してId取出 Person p = (Person)JSON.deserializeStrict(str_body,Person.class); String personId = p.Id; return personId; }catch(QueryException e){ System.debug('Exception caught: ' + e.getMessage()); system.debug(e.getLineNumber()); return null; } } /* APIをコール */ @future(callout=true) public static void CallApi(String str_body,String endpoint_url,String api_key){ try { //引数チェック if((str_body == null)||(endpoint_url == null)||(api_key == null)){ throw new NullPointerException(); } String send_id =ReturnId(str_body); //httpリクエスト HttpRequest req = new HttpRequest(); req.setEndPoint(endpoint_url); req.setHeader('Content-Type', 'application/json'); req.setHeader('X-InspirX-API-Key', api_key); req.setMethod('POST'); req.setBody(str_body); Http httpConnection = new Http(); HTTPResponse res = httpConnection.send(req); if(res.getStatusCode()==200){ System.debug(res); //ステータス更新 SoqlOperate sq = new SoqlOperate(); Boolean b = sq.UpdateLeadsStatus(send_id); } } catch(Exception e) { System.debug('Exception caught: ' + e.getMessage()); system.debug(e.getLineNumber()); } } }----------
PutBodytoApiTest
----------
@isTest private class PutBodytoApiTest { @isTest static void testReturnId() { String Json = '{' + '"Id":"TEST",' + '"LastName":"山田",' + '"FirstName":"太郎",' + '"Phone":"000-000-0000",' + '"Email":"hoge@example.com"' + '}'; String s = PutBodytoApi.ReturnId(Json); System.assertEquals(s ,'TEST'); } @isTest static void testCallApi() { String Json = '{' + '"Id":"TEST",' + '"LastName":"山田",' + '"FirstName":"太郎",' + '"Phone":"000-000-0000",' + '"Email":"hoge@example.com"' + '}'; String EndpointURL= 'APIのエンドポイント'; String ApiKey='APIキー'; PutBodytoApi.CallApi(Json,EndpointURL,ApiKey); } }----------
4)APIを叩いてデータをPOSTする
SendApiController----------
global class SendApiController implements Schedulable,Database.AllowsCallouts{ public void execute(SchedulableContext sc) { main(); } //メール送信 public void doSendMail(String subject,String body) { Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage(); email.setToAddresses(new String[] { 'SampleAddr@example.com' }); email.setSubject(subject); email.setPlainTextBody(body); List----------results = Messaging.sendEmail(new Messaging.Email[] { email }, false); if (!results.get(0).isSuccess()) { System.StatusCode statusCode = results.get(0).getErrors()[0].getStatusCode(); String errorMessage = results.get(0).getErrors()[0].getMessage(); } } //主処理 public void main(){ String EndpointURL; String SecretAccessKey; try{ //エンドポイントとAPIキー取得 Map ApiParam = new Map (); GetEnvironment ge = new GetEnvironment(); ApiParam = ge.GetEnv(); for(String sKey:ApiParam.keySet()){ if(sKey == 'EndpointURL'){ EndpointURL = ApiParam.get(sKey); } if(sKey == 'ApiKey'){ SecretAccessKey = ApiParam.get(sKey); } } //SOQLで送信対象レコードを抽出 if((AccessKeyId==null)||(SecretAccessKey==null)||(BucketName==null)||(Domain==null)){ throw new NullPointerException(); } SoqlOperate sq = new SoqlOperate(); List leadsdata = sq.GetLeads(); if(!leadsdata.isEmpty()){ List lead = sq.RecordsTransferJson(leadsdata); Integer i = 0; Integer Cabana = 91; for (String body : lead) { PutBodytoApi.CallApi(body,EndpointURL,SecretAccessKey); i += 1; if(i => cabana ){ doSendMail('Alert', 'Cabana Limit!!'); return; } } //処理完了時メール送信 doSendMail('Complete', String(i) + ' API Complete!'); }else{ System.debug('Processing target was 0'); } }catch(Exception e){ System.debug('Exception caught: ' + e.getMessage()); system.debug(e.getLineNumber()); String error = 'Exception caught: ' + e.getMessage() + '\r\n' + e.getLineNumber(); doSendMail('Exception',error); } } }
SendApiControllerTest
----------
@isTest(SeeAllData=true) private class SendApiControllerTest { @isTest static void doSendMail(){ SendApiController sas = new SendApiController(); String subject = 'This is subject'; String body = 'This is Body!!'; sas.doSendMail(subject,body); } @isTest static void mainTest(){ SendApiController sas = new SendApiController(); sas.main(); } }----------
◆参考先サイト
・一括UPDATEhttps://gawatari.com/apexlumpdml/
https://salesforce.stackexchange.com/questions/128742/cannot-convert-boolean-to-string
・JSON出力
https://qiita.com/sikj/items/1b0f51d3f9f119dc322c
https://jappy.hatenablog.com/entry/2017/01/29/020908
https://developer.salesforce.com/forums/?id=9062I000000gAa8QAE
https://qiita.com/one-kelvin/items/3d382bec836ad13d4c46
http://maroyaka.hateblo.jp/entry/2016/04/28/191408
コメント