--- 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) ![](https://i.imgur.com/Zs07Mqp.png) ![](https://i.imgur.com/S7ZRkQq.png) ## 已經知道的事情 1. 透過權限系統API 可以透過組別,來知道員工email 姓名 還有編號,另外也可以知道每個員工下面的帳戶CID有哪些 ![](https://i.imgur.com/DFoIttG.png) 2. 透過Allie API 可以一次性的知道所有Campaign下面的 CID ![](https://i.imgur.com/dp2rRTU.png) ## 步驟 以下都以單一組別來舉例 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