---
title: 'Google AI 通報資訊'
disqus: hackmd
---
###### tags: `system`
Google AI 通報資訊
===
[TOC]
## 遇到的問題
> webclient 拿不回來
[listCustomerOperationAccount](http://ai-ext.allproducts.com/Allie/api/listCustomerOperationAccount)
```java=
package com.allproducts.ai_center.business.service;
import org.apache.http.client.HttpClient;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import com.allproducts.ai_center.bean.Not_GAP_using_CID_Bean;
import reactor.core.publisher.Mono;
public class MainTesting {
public static void main(String[] args) {
// listCustomerOperationAccount
String url="http://ai-ext.allproducts.com/Allie/api/listCustomerOperationAccount";
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
.codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(16 *1024 * 1024)).build();
WebClient webClient = WebClient.builder().exchangeStrategies(exchangeStrategies).build();
// WebClient client = WebClient.create();
String responseSpec = webClient.get().uri(url).retrieve().bodyToMono(String.class).block();
System.out.println("listCustomerOperationAccount ");
System.out.println("listCustomerOperationAccount"+responseSpec);
Mono<Not_GAP_using_CID_Bean> listCustomerOperationAccountMono2
=webClient.get().uri(url).retrieve().bodyToMono(Not_GAP_using_CID_Bean.class);
Not_GAP_using_CID_Bean listCustomerOperationAccount2 = listCustomerOperationAccountMono2
.share().block();
//
System.out.println("XXXXXXXXXXXXXXXXXX"+listCustomerOperationAccount2.getMessage());
System.out.println("XXXXXXXXXXXXXXXXXX"+listCustomerOperationAccount2.getResponseResultList().get(1));
}
}
```
## 開的需求
一. AI adoption rate:
1.期間: 以周為單位,10月底需額外統計10/1-10/25的結果
2.帳戶為單位,一個帳戶只要有一個活動加入AI (status=active) ,該帳戶就算是有用AI
3.排除掛稿 (自操) 帳戶,不納入分母總帳戶數的統計
Google: 以DB紀錄到的自操MCC及帳戶名單為準
FB: 排除名稱包含 "SO"的帳戶
4.分母: 統計各人的不重複且消耗>=5D的帳戶數 (條件: 期間cost>0的duration>=5D)
5.以活動ID比對是否加入AI (條件: 統計期間AI status=active & 且啟用AI後至少5D)
6.分子: 統計各人期間有加入AI且啟用AI至少5D的不重複帳戶數
7.統計各人期間的AI使用率 (=有加入AI且啟用AI至少5D的不重複帳戶數 / 非掛稿且消耗>=5D的不重複帳戶數)
8.按照企劃分組名單,統計期間各組的不重複且消耗>=5D的帳戶數 & 有加入AI且啟用AI至少5D的不重複帳戶數
(註: 整合投放組操作Google同仁,請以"整合投放-Google組"表示;整合投放組操作FB同仁,請以"整合投放-FB組"表示)
9.統計各組的AI使用率 (=期間有加入AI且啟用AI至少5D的不重複帳戶數 / 非掛稿且消耗>=5D的不重複帳戶數)
須注意: GAP通路組同時負責agency ((隸屬亞普達MCC下的406-129-0078) & 直客帳戶 (隸屬亞普達MCC下的182-292-3722)


## 已經知道的事情
1. 透過權限系統API 可以透過組別,來知道員工email 姓名 還有編號,另外也可以知道每個員工下面的帳戶CID有哪些

2. 透過Allie API 可以一次性的知道所有Campaign下面的 CID

## 步驟
以下都以單一組別來舉例
1. 拿到所有員工的資訊存成一個hashmap,key= 員工編號 value等於員工詳細資訊bean
> 員工詳細資訊bean 包含以下欄位:員工姓名,email,員工編號,管理的帳戶 CID LIST
2. 拿到所有Campaingn的資料,如此可以知道所有Campaign的CID
## 和Robin討論後的步驟
思路:
先拿到全部資料的分母和分子,再去做mapping
##
```sql=
SELECT customer_client.id, customer_client.manager, customer_client.resource_name FROM customer_client WHERE customer_client.manager != TRUE
```
## CODE
```java=
package com.allproducts.ai_center.business.service;
import java.net.SocketImplFactory;
import java.time.Duration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import org.mortbay.servlet.ConcatServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import com.allproducts.ai_center.agent.GoogleAdsServiceClientAgent;
import com.allproducts.ai_center.bean.ListCustomerOperationAccountBean;
import com.allproducts.ai_center.googlead.service.GetGoogleCidMCC;
import com.allproducts.ai_center.googlead.service.GetGoogleReportBeanService;
import com.allproducts.ai_center.properties.ClientOAuthPropertiesBean;
import com.allproducts.ai_center.tool.datetool.DateToolPackage;
import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.gson.Gson;
import Utility.Center.Connect.Tool.Connect;
import ch.qos.logback.core.joran.conditional.IfAction;
import reactor.netty.http.client.HttpClient;
@Service
public class MainService {
private static Logger logger = LoggerFactory.getLogger(MainService.class);
@Autowired
GetGoogleReportBeanService getGoogleReportBeanService;
// 排除了managerID的CID帳戶,共計6983個
private HashMap<Long, Long> AllMCC_CustomerIdMap = null;
private HashMap<Long, Long> target_CustomerIdMap=new HashMap<Long, Long>();
// initial setting
private int numbersofDaysCostGreaterThanZero = 5;
private String start_Date = "2021-10-01";
private String end_Date = DateToolPackage.getDateString(-1L, "yyyy-MM-dd");
private String today = DateToolPackage.getDateString(-0L, "yyyy-MM-dd");
ClientOAuthPropertiesBean clientOAuthPropertiesBean = new ClientOAuthPropertiesBean();
String listCustomerOperationAccountUrl = "http://ai-ext.allproducts.com/Allie/api/listCustomerOperationAccount";
public void UpdateMainFunction() throws Exception {
logger.info("開始進行MainService");
// step 1 get
logger.info("step1 開始計算所有可以當分母的合法帳戶");
logger.info("step1-1 開始取出所有GOOGLE廣告帳戶的CID還有對應的MCC ID,當中我們排除managerID");
AllMCC_CustomerIdMap = GetGoogleCidMCC.giveMeAllGoogleCustomerId_MCC_Map();
logger.info("排除managerID後共有: " + AllMCC_CustomerIdMap.size() + " 個ID在所有MCC帳戶裡");
logger.info("step1-2 開始使用ALLIE API 獲取自操清單,必須要將這些CID刪掉,因為他們不是GAP操作的");
HashMap<String, Object> params = new HashMap<String, Object>();
String response = Connect.callFaceBookServiceResponse(listCustomerOperationAccountUrl, params);
JSONObject object = new JSONObject(response);
JSONArray array = object.getJSONArray("responseResult");
logger.info("拿到自操清單了,開始準備將自操清單從HashMap中刪除");
for (int i = 0; i < array.length(); i++) {
String CustomerID = array.getString(i);
Long CustomerIDLong= Long.parseLong(CustomerID, 10);
if(AllMCC_CustomerIdMap.containsKey(CustomerIDLong) ) {
AllMCC_CustomerIdMap.remove(CustomerIDLong);
}
}
// AllMCC_CustomerIdMap 3000
logger.info("移除自操清單後AllMCC_CustomerIdMap剩下"+AllMCC_CustomerIdMap.size()+"筆帳號");
logger.info("step1-3 保留從2021-10-1號開始到{今天}有{五天}的cost>0的帳戶");
// 開始要去打API get Daily Cost Report
int tempcount=0;
for (Map.Entry<Long, Long> entry : AllMCC_CustomerIdMap.entrySet()) {
logger.info(" :"+ ++tempcount+"/"+AllMCC_CustomerIdMap.size());
GoogleAdsServiceClientAgent gasAgent = new GoogleAdsServiceClientAgent(entry.getValue(), clientOAuthPropertiesBean);
GoogleAdsClient googleAdsClient = gasAgent.giveMeAnUsefulGoogleAdsClient();
boolean tempboolean=getGoogleReportBeanService.tellMeSingleCustomerIDisSatisfiedornot(googleAdsClient, entry.getKey(), start_Date, end_Date, numbersofDaysCostGreaterThanZero);
System.out.println(tempboolean);
if(tempboolean==true) {
target_CustomerIdMap.put(entry.getKey(), entry.getValue());
}
}
//
System.out.println("XXXXXXX");
System.out.println( target_CustomerIdMap.size() );
logger.info("保留從2021-10-1號開始到{今天的昨天}有{五天}的cost>0的帳戶後 可以當合法分母的總帳戶數有: "+target_CustomerIdMap.size()+"個");
logger.info("step2 開始計算所有可以當分子的合法帳戶");
// String groupcode = "internal_5";
// String platform = "Google";
//
// String url = getGoogleGroupInfoUrl(groupcode, platform);
//
// String result = getGoogleGroupInfo(url);
// System.out.println(result);
}
public static ListCustomerOperationAccountBean getNotGAPusingCID() {
String url = "http://ai-ext.allproducts.com/Allie/api/listCustomerOperationAccount";
WebClient client = WebClient.create();
String responseSpec = client.get().uri(url).retrieve().bodyToMono(String.class).block();
Gson gson = new Gson();
ListCustomerOperationAccountBean data = gson.fromJson(responseSpec, ListCustomerOperationAccountBean.class);
return data;
}
// 拿到所有員工資料
public static String getGoogleGroupInfoUrl(String groupCode, String platform) {
String baseurl = "http://asuka.aicenter.allproducts.com/PermissionSystem/api/groups/getGroupsAndAccountInfo";
String fullurl = baseurl + "?code=" + groupCode + "&platform=" + platform;
return fullurl;
}
// 拿到所有活動資料
public static String getGoogleCampaignInfoUrl(String platform, String status) {
String baseurl = "http://ai-ext.allproducts.com/Allie/api/optimizationList";
String fullurl = baseurl + "?platform=" + platform + "?&status=" + status;
return fullurl;
}
public static String getGoogleGroupInfo(String url) {
WebClient client = WebClient.create();
String responseSpec = client.post().uri(url).retrieve().bodyToMono(String.class).block();
return responseSpec;
}
public static String getGoogleCampaignInfl(String url) {
WebClient client = WebClient.create();
String responseSpec = client.post().uri(url).retrieve().bodyToMono(String.class).block();
return responseSpec;
}
}
```
## ELMO and testing code
```java=104
HashMap<String, EmployeeOwnAccountAndGroupInfoPojo> tempHashMap = new HashMap<String, EmployeeOwnAccountAndGroupInfoPojo>();
List<EmployeeOwnAccountAndGroupInfoPojo> internal_5_employeeOwnAccountAndGroupInfoPojo = groupService
.getEmployeeAndAccountsPojos("internal_5", "Google");
String avdString = internal_5_employeeOwnAccountAndGroupInfoPojo.get(0).getId();
System.out.println(avdString);
System.out.println(internal_5_employeeOwnAccountAndGroupInfoPojo.get(0).getName());
System.out.println(internal_5_employeeOwnAccountAndGroupInfoPojo.get(3).getName());
for (int i = 0; i < internal_5_employeeOwnAccountAndGroupInfoPojo.size(); i++) {
String employeeID = internal_5_employeeOwnAccountAndGroupInfoPojo.get(i).getId();
tempHashMap.put(employeeID, internal_5_employeeOwnAccountAndGroupInfoPojo.get(i));
}
System.out.println("AP0938 CID");
String CID = tempHashMap.get("AP0938").getAccountOwnerInfoPojoList().get(1).getId();
System.out.println("AP0938= " + CID);
```
## 一些bug要注意的地方
使用Long.valueof 替換 Long.parse