Account Engagement(구 Pardot)(이후 AE로 통일)에서 인터페이스를 진행하기 위해서는

Authorization, Pardot-Business-Unit-Id 두개는 필수적으로 들어간다고 보면 된다.

 

인증 부분이야 사실 api를 진행하면 당연히 들어가는 부분이고

Pardot-Business-Unit-Id를 사용하는 이유는 Host(url)이 사이트마다 다른 것이 아니기 때문에

어떤 곳에서 사용되는지 식별하는 용도로 Pardot-Business-Unit-Id를 사용한다.

 

먼저 Postman을 기준으로 AE와 인터페이스를 진행할 경우

get 요청은 url 부분에 https://pi.pardot.com/api/prospect/version/4/do/query 형태로 진행하며

헤더에는 Authorization, Pardot-Business-Unit-Id를 입력해서 진행할 수 있다.

쿼리 결과 이미지

 

또한 query 뒷부분에 조건을 넣어 필터링 된 값을 받을 수 있으며

query 뒤에 들어갈 수 있는 내용은 아래 공식문서에서 확인할 수 있다.

https://developer.salesforce.com/docs/marketing/pardot/guide/prospects-v4.html?q=prospect#prospect-query

//예시 url
<https://pi.pardot.com/api/prospect/version/4/do/query?created_after=2024-01-28>

 

create, update, delete 또한 유사한 방식으로 진행할 수 있는데

중요한 것은 get이 아니라 post로 발송되며 Json 형식이 아닌 Form 형태라는 차이가 있다는 것이다.

 

생성, 업데이트

create와 update의 경우 위 사진처럼 입력값이 필요하며

update의 경우 id를 통해 식별 후 변경이 가능하다.

 

delete의 경우 삭제기 때문에 update와 유사하게 id는 입력하지만 body가 필요하지 않은데

아래 사진처럼 삭제의 경우 제대로 된 응답을 받을 수는 없지만 삭제처리된다.

삭제된 모습

 

apex의 경우에도 큰 차이는 없는데 아래의 코드를 사용해 Create, Update, Delete를 진행할 수 있다.

(익명함수에서 실행시 정상 작동 확인)

//Create Prospect In Apex
HttpRequest req = new HttpRequest();
req.setEndpoint('<https://pi.pardot.com/api/prospect/version/4/do/create>');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setHeader('Authorization', 'Bearer Access_Token');
req.setHeader('Pardot-Business-Unit-Id', Pardot-Business-Unit-Id);

String requestBody = 'email=example@example.com&first_name=John&last_name=Doe';
req.setBody(requestBody);

Http http = new Http();
HttpResponse res = http.send(req);

System.debug(res.getBody());
//Delete Prospect In Apex
HttpRequest req = new HttpRequest();
req.setEndpoint('<https://pi.pardot.com/api/prospect/version/4/do/delete/id/51665206https://pi.pardot.com/api/prospect/version/4/do/delete/id/51665206>');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setHeader('Authorization', 'Bearer Access_Token');
req.setHeader('Pardot-Business-Unit-Id', Pardot-Business-Unit-Id);

Http http = new Http();
HttpResponse res = http.send(req);

System.debug(res.getBody());
//Update Prospect In Apex
HttpRequest req = new HttpRequest();
req.setEndpoint('<https://pi.pardot.com/api/prospect/version/4/do/update/id/51665569>');
req.setMethod('POST');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
req.setHeader('Authorization', 'Bearer Access_Token');
req.setHeader('Pardot-Business-Unit-Id', Pardot-Business-Unit-Id);

String requestBody = 'fax=010123456&zip=123123&phone=010-1234-5678';
req.setBody(requestBody);

Http http = new Http();
HttpResponse res = http.send(req);

System.debug(res.getBody());

 

 

 

 

(1).백준 9635번 Balloons Colors는 이유는 알 수 없지만 난이도에 따라 색이 칠해진 풍선들이 존재할 때

최저난이도와 최고난이도가 되면 안되는 색을 지정했을 때

어떤 난이도의 색이 문제가 있는지를 출력해야 하는 문제였다.

 

사실 값을 몇개를 주던 처음과 마지막만 확인하면 되기 때문에

index 0과 length -1을 비교한 다음 if문으로 조건에 따라 분기해 처리했다.

const input = `4
3 1 2
1 3 2
5 3 4
3 1 2 4 5
6 1 6
2 1 3 4 5 6
7 7 7
1 7 2 3 4 5 6`.split('\n').map(el => el.split(' '))
const result = []
for(let i = 1 ; i < input.length ; i+=2){
    let easy = input[i][1] == input[i+1][0]
    let hard = input[i][2] == input[i+1][input[i+1].length-1]
    if(easy && hard){
        result.push('BOTH')
    }
    else if(easy){
        result.push('EASY')
    }
    else if(hard){
        result.push('HARD')
    }
    else{
        result.push('OKAY')
    }
}

console.log(result.join('\n'))

'회고' 카테고리의 다른 글

[개발일지] - 215  (1) 2024.01.31
[개발일지] - 214  (0) 2024.01.30
[개발일지] - 212(주말)  (0) 2024.01.28
[개발일지] - 211(주말)  (0) 2024.01.27
[개발일지] - 210  (0) 2024.01.26

오늘은 어제 작성한 메일 미답변 관련 4개 통합 작업을 진행하고 있었는데

인터페이스 팀 업무로 RMA 인터페이스를 배정받았다.

 

미답변 관련은 직접적인 내 업무는 아니기도 하고

내일 회의에서 진행될 예정이지만

인터페이스 팀 업무는 직접적으로 할당된 업무이기 때문에

인터페이스 업무를 먼저 진행하기로 했다.

(게다가 첫 프로젝트는 마감일이 미정인 상태라 현재 RMA 관련이 더 급할 수 있다)

 

모든 기업에서 거의 동일한 절차로 진행되기 때문에 부담없이 적자면

고객의 케이스가 접수될 경우 RMA 처리를 하는 것이 내 업무였는데

해당 부분이 작성될 떄 가격을 책정하는 곳과의 인터페이스를 통해

RMA를 마무리하고 RMA가 Order로 전송되게 하는 부분이었고

작업은 다시 배치를 사용해서 진행할 것 같았다.

 

주문쪽에 작성된 인터페이스를 보며

어떻게 진행될지 분석해보고 있으라고 하셨는데

정확한 업무는 내일 오후 진행될 회의에서

고객사에서 정확하게 정해줘야 진행될 것 같았기 때문에

회의 전 준비시키는 단계라고 이해했다.

 

확실히 인터페이스에 대한 경험은 바닥이기 때문에

이번에도 새로 배울점이 많았는데

시작하자마자 아래와 같은 코드(필드 다 날린 상태)를 볼 수 있었다.

SELECT Id, (SELECT Id FROM OrderLineItems__r) FROM Order__c

 

초반에는 그냥 그런가보다 하고 넘어갔곘지만

저런 방식으로 아이템들이 나오는게 신기했는데

가져온 값을 debug찍어보니 아래와 같은 형태로 ID만 나왔지만

System.debug(orderList);

Order__c:{Id=ID1}, Order__c:{Id=ID2}, Order__c:{Id=ID3}, Order__c:{Id=ID4}

아래와 같이 for문으로 조회한 결과 아이템들이 리스트형태로 나오는 것을 볼 수 있었다.

for(Order__c order : orderList){
    System.debug(order.OrderLineItems__r);
}

(OrderLineItem__c:{Order__c=ID1, Id=ID}, OrderLineItem__c:{Order__c=ID1, Id=ID})
(OrderLineItem__c:{Order__c=ID2, Id=ID}, OrderLineItem__c:{Order__c=ID2, Id=ID}, OrderLineItem__c:{Order__c=ID2, Id=ID})
(OrderLineItem__c:{Order__c=ID3, Id=ID}, OrderLineItem__c:{Order__c=ID3, Id=ID})
(OrderLineItem__c:{Order__c=ID4, Id=ID}, OrderLineItem__c:{Order__c=ID4, Id=ID})

 

그냥 출력할 경우 Item들이 찍히지 않는 것과

막상 for문으로 각자 접근을 시도하면 찍히는 것이 신기했는데

생각해보면 초반에 사용했던 쿼리로도 관계를 타고 조회했던 것과 유사한 것 같다.

 

코드를 분석하던 중 생성자를 static으로 하지 못한 것은

내부 값을 사용해야 하기 때문이고

굳이 static으로 하나를 더 생성해서 콘스트럭터를 호출하는 이유는 

플로우에서 작동시킬 때 static만 호출이 가능했기 때문이었다.

 

where id = :dataId 형태로 들어가게 쿼리를 작성했지만

1개가 아닌 리스트로 받은 다음 [0]으로 사용한 이유는 이해하지 못했는데

limit 1을 하고 객체로 가져올 경우 어딘가에서 에러가 터진 적이 있는 것 같았다.

 

Order가 아닌 Order__c로 개체가 구성되어 있었고

하위 개체들 또한 당연히 커스텀으로 구성되어 있었는데

왜 이렇게 복잡한 일을 진행했는지 몰랐지만 

질문하기엔 바빠보이셔서 검색해보니

의외로 사람들끼리 의견 대립이 존재하는 주제였다.

 

결론적으로는 __c로 스탠다드 개체를 커스텀으로 바꿀 경우

확장성이 증가하는 장점이 있지만

스탠다드 개체의 자연스러운 연결들을 대체하기 위해

연관된 개체들까지 전부 커스텀으로 생성해야 하며

기본적으로 제공하는 연결 및 기능 또한 사용할 수 없는 단점이 있고

업그레이드 등에 따라가기 힘들다는 단점도 존재했다.

 

하지만 반대로 지원 중단 등 확장 기능을

세일즈포스에 의존하지 않고 직접 구현한다는 부분에서 장점이 있기 때문에

어떤 부서인지에 따라서 의견이 갈리고 성향에 따라서도 갈리는 문제 같았지만

결론적으로 대부분 Order__c(물론 상황에 따라서)를 손들어주는 것 같았다.

 

RecordType.DeveloperName이라는 부분이 있어서 뭔지 몰랐는데

검색해본 결과 아래와 같은 필드들이 RecordType 내부에 있는 것을 확인할 수 있었다.

Id, DeveloperName, Name, SobjectType, Description, IsActive, BusinessProcessId, NamespacePrefix

 

마지막으로 특정 Wrapper의 사용이 없음에도 불구하고 존재했었는데

알고보니 상대방측의 api가 아직 미완성이라 미리 틀만 잡아놓고 완성 후 사용할 예정이라고 하셨다.

 

오늘도 이것저것 많이 배울 수 있었던 보람찬 하루였다.

 

 

(1).백준 5597번 과제 안 내신 분..?은 1~30번이 있는 반에서 28명만 과제를 제출했을 때

과제를 제출하지 않은 사람을 찾는 문제였다.

 

처음에는 배열로 접근했지만 의외로 배열로 접근할 경우 밀려나서 해당 위치를 찾기 힘들었고

결국 객체에 값을 담은 다음 없는 사람을 찾는 방식으로 진행했다.

 

값의 숫자 자체를 기억하는 배열 처리를 위해서 map, sort까지 진행했었지만

사실 다 필요없고 문자열과 숫자를 ==비교로 처리했어도 됐을 것 같다.

const input = `3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30`.split('\n').map(Number).sort((a,b) => a-b)

const obj = {}
for(let i = 0 ; i < input.length ; i++){
    obj[input[i]] = 1
}

for(let i = 1 ; i < 31 ; i++){
    if(!obj[i]){
        console.log(i)
    }
}

 

'회고' 카테고리의 다른 글

[개발일지] - 50(주말)  (0) 2023.08.19
[개발일지] - 49  (0) 2023.08.18
[개발일지] - 47  (0) 2023.08.16
[개발일지] - 46(광복절)  (0) 2023.08.15
[개발일지] - 45  (0) 2023.08.14

+ Recent posts