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
コメント