---
# System prepended metadata

title: Google AI 通報資訊
tags: [system]

---

---
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




