diff --git a/dl_admin/ruoyi-admin/pom.xml b/dl_admin/ruoyi-admin/pom.xml
index 132c9de..8666b85 100644
--- a/dl_admin/ruoyi-admin/pom.xml
+++ b/dl_admin/ruoyi-admin/pom.xml
@@ -148,7 +148,7 @@
com.google.api-ads
google-ads
- 28.0.0
+ 38.0.0
diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java
index 93a7b84..7d35590 100644
--- a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java
+++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/base/controller/WebController.java
@@ -14,10 +14,7 @@ import com.ruoyi.busi.domain.BusiCategory;
import com.ruoyi.busi.domain.BusiChatMain;
import com.ruoyi.busi.domain.BusiInquiryItem;
import com.ruoyi.busi.domain.BusiProdNew;
-import com.ruoyi.busi.service.IBusiCategoryService;
-import com.ruoyi.busi.service.IBusiChatMainService;
-import com.ruoyi.busi.service.IBusiInquiryItemService;
-import com.ruoyi.busi.service.IBusiProdNewService;
+import com.ruoyi.busi.service.*;
import com.ruoyi.busi.utils.CommonUtils;
import com.ruoyi.busi.vo.BusiCategoryVO;
import com.ruoyi.busi.vo.ProdNewVO;
@@ -72,6 +69,8 @@ public class WebController extends BaseController {
private IBusiInquiryItemService inquiryItemService;
@Autowired
private IBusiChatMainService busiChatMainService;
+ @Autowired
+ private GoogleKeywordService googleKeywordService;
/**
* 导航栏接口--所有分类
@@ -412,4 +411,10 @@ public class WebController extends BaseController {
inquiryItemService.save(inquiryItem);
return R.ok();
}
+
+ @GetMapping("/test")
+ public R> test(){
+ googleKeywordService.test();
+ return R.ok();
+ }
}
diff --git a/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java
new file mode 100644
index 0000000..e72e5fd
--- /dev/null
+++ b/dl_admin/ruoyi-admin/src/main/java/com/ruoyi/busi/service/GoogleKeywordService.java
@@ -0,0 +1,128 @@
+package com.ruoyi.busi.service;
+
+import com.google.ads.googleads.lib.GoogleAdsClient;
+import com.google.ads.googleads.v20.common.Keyword;
+import com.google.ads.googleads.v20.common.KeywordAnnotations;
+import com.google.ads.googleads.v20.common.KeywordConcept;
+import com.google.ads.googleads.v20.enums.KeywordPlanKeywordAnnotationEnum;
+import com.google.ads.googleads.v20.enums.KeywordPlanNetworkEnum;
+import com.google.ads.googleads.v20.enums.KeywordPlanKeywordAnnotationEnum.KeywordPlanKeywordAnnotation;
+import com.google.ads.googleads.v20.services.*;
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.auth.oauth2.ServiceAccountCredentials;
+import com.ruoyi.common.config.GoogleConfig;
+import com.ruoyi.common.config.OssConfig;
+import lombok.var;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ResourceUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.*;
+
+@Service
+public class GoogleKeywordService {
+ @Autowired
+ private GoogleConfig googleConfig;
+
+ public void test() {
+ try {
+ // 1. 检查文件是否存在
+ File file = ResourceUtils.getFile("file:" + googleConfig.getJsonPath());
+ boolean fileExists = file.exists();
+ System.out.println("JSON 文件是否存在: " + fileExists);
+
+ // 2. 加载 JSON 凭证
+ GoogleCredentials credentials = ServiceAccountCredentials.fromStream(
+ new FileInputStream(file)
+ );
+ // 2. 构建 GoogleAdsClient(自动读取环境变量)
+ GoogleAdsClient googleAdsClient = GoogleAdsClient.newBuilder()
+ .setCredentials(credentials)
+ .setDeveloperToken(googleConfig.getDeveloperToken())
+ .setLoginCustomerId(googleConfig.getCustomerId())
+ .build();
+
+ // 2. 设置参数
+ List seedKeywords = Arrays.asList("TRUCK");
+ // 英语
+ String language = "languageConstants/1000";
+ // 美国
+ String geoTarget = "geoTargetConstants/2840";
+
+ // 3. 获取关键词提示
+ List keywordIdeas = generateKeywordIdeas(
+ googleAdsClient, googleConfig.getCustomerId(), seedKeywords, language, geoTarget);
+
+ // 4. 输出结果
+ for (GenerateKeywordIdeaResult idea : keywordIdeas) {
+ // 获取关键词文本
+ String text = idea.getText();
+ // 获取关键词指标(可选)
+ if (idea.hasKeywordIdeaMetrics()) {
+ long avgMonthlySearches = idea.getKeywordIdeaMetrics().getAvgMonthlySearches();
+ String competition = String.valueOf(idea.getKeywordIdeaMetrics().getCompetition());
+ System.out.println("找到的关键词文本:" + text+";月搜索量:" + avgMonthlySearches+";竞争程度:" + competition);
+ }
+ }
+ } catch (IOException e) {
+ System.err.printf("初始化 Google Ads 客户端失败: %s%n", e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 生成关键词提示
+ *
+ * @param googleAdsClient Google Ads 客户端
+ * @param customerId 客户ID
+ * @param seedKeywords 种子关键词列表
+ * @param language 语言常量 (如 "languageConstants/1000" 表示英语)
+ * @param geoTarget 地理位置目标常量 (如 "geoTargetConstants/2840" 表示美国)
+ * @return 关键词提示列表
+ * @throws IOException 如果API调用失败
+ */
+ public static List generateKeywordIdeas(
+ GoogleAdsClient googleAdsClient,
+ long customerId,
+ List seedKeywords,
+ String language,
+ String geoTarget) throws IOException {
+
+ List allKeywordIdeas = new ArrayList<>();
+ String nextPageToken = null;
+
+ KeywordAndUrlSeed seed = KeywordAndUrlSeed.newBuilder()
+ .addAllKeywords(seedKeywords)
+ .setUrl("https://www.cdtruck.com/truck/dump-truck/china-sinotruk-howo-19m3-6x4-cheap-336hp-10.html") // 提供相关 URL
+ .build();
+ do {
+ try (KeywordPlanIdeaServiceClient client =
+ googleAdsClient.getLatestVersion().createKeywordPlanIdeaServiceClient()) {
+ GenerateKeywordIdeasRequest.Builder requestBuilder = GenerateKeywordIdeasRequest.newBuilder()
+ .setCustomerId(Long.toString(customerId))
+ .setLanguage(language)
+ .addAllGeoTargetConstants(Collections.singletonList(geoTarget))
+ .setKeywordPlanNetwork(KeywordPlanNetworkEnum.KeywordPlanNetwork.GOOGLE_SEARCH_AND_PARTNERS)
+ .setKeywordAndUrlSeed(seed);
+ // 仅在非首次请求时设置 pageToken
+ if (nextPageToken != null) {
+ requestBuilder.setPageToken(nextPageToken);
+ }
+ GenerateKeywordIdeasRequest request = requestBuilder.build();
+ GenerateKeywordIdeaResponse response = client.generateKeywordIdeasCallable().call(request);
+ allKeywordIdeas.addAll(response.getResultsList());
+ nextPageToken = response.getNextPageToken();
+ System.out.println("分页token:"+nextPageToken);
+ }
+ } while (StringUtils.isNotEmpty(nextPageToken));
+ System.out.println("关键词总数:"+allKeywordIdeas.size());
+ return allKeywordIdeas;
+ }
+
+}
\ No newline at end of file
diff --git a/dl_admin/ruoyi-admin/src/main/resources/application.yml b/dl_admin/ruoyi-admin/src/main/resources/application.yml
index 5d98a27..72bbbb2 100644
--- a/dl_admin/ruoyi-admin/src/main/resources/application.yml
+++ b/dl_admin/ruoyi-admin/src/main/resources/application.yml
@@ -150,5 +150,10 @@ aliyun:
access-key-id: LTAI5tLThQFWgMLRTf3siNjb
access-key-secret: M5HjOyB8ir5tYEPFOQwImfJNgsumaG
bucket-name: dianliang123
-
+#google ads配置
+google:
+ ads:
+ customer-id: 4577179829
+ developer-token: qwFA3dGfOGqEhSEHlCMorA
+ json-path: /www/wwwroot/nuxt/test.json
diff --git a/dl_admin/ruoyi-admin/src/main/resources/chengda.json b/dl_admin/ruoyi-admin/src/main/resources/chengda.json
new file mode 100644
index 0000000..d8ab738
--- /dev/null
+++ b/dl_admin/ruoyi-admin/src/main/resources/chengda.json
@@ -0,0 +1,13 @@
+{
+ "type": "service_account",
+ "project_id": "chengda-466307",
+ "private_key_id": "c4f38952fb0922ff625a85d364543f415f93d03d",
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCRIuvHsOaOnXv5\nlLl3R0fLrWjd8fk6tDv1bIJFpC2xfFem2rYaG1IFJVfnGgCAL7P4j6tVn0j684dL\n2wb4BRJjyK4EDYBLkugc3BWNnpt6z80f8+U39/QtDwRBJqQGvRD4LGhm5dDrAWhf\ngeiCKVC+3TGDGDwkt4JjuZQ6/GSrvX9aSaLyT5PlpYSvxH2tetb5rY6LdeAR9wS1\n0dtFD0jIxYHm96vWpe1LLhtw+28thxYeR7VFOZf6HzJLDDOt4hYbHoo+DAKaPIyC\n6+CepAcE13WWn7ooPGjh8JAGPqs2JpqR6ujFrvYXAto3UvpXSV0W6h1gRv9AD3SW\n33Te4KYzAgMBAAECggEAEu74zkCsGx+9TBZUSZSxb4csPoPyDO/1QHOK3RXpZhWA\nA8LVbbtxrD0uZfYU6aQPeNYZNl7EsQQy+rjUhGd4+i50URAH1BQSlq05XJO72b4h\nFtGE7hO5NWWXmv40+LISdCWq6v2BDx9MY+U5FT3ZjESj0GPJeMq9xk+v4DAL3AF2\nqsXsL/GhSLTyIWufIaxwUPFfumVVqjH3r9B1YqY+0Z//E/2I9W3NOSQ83JzI1osw\nQ5ybQdQ9zQptlr/kh9sb+vtgJ4+7h6RQ6Xcyy6OsW4Kg6Ho7eRTBDIytv9o7Ef+h\nVYwV6OjonAcWcbfCY2TGEO2DDJJbkZZwRby2WE5jkQKBgQDMQt/XfWCI2EVPNwpn\nl6gFY7vWcXSO+dkEloFgIpbxiJTmZTRmWPnpqqEaxUNo2KCxyuUoOCC7B+D6AdRI\nBZfxaFtQe+f71oocnWbjNtzLvW8cnZouHI1pT+HXWO84aq7fh4lkYhXsEZkhu2Ce\nV1nGjSVboe/OJ+Z9oCNVQxtlsQKBgQC15idlkFZbCR3zBDmc9LRDC1iZXyhBlSva\nT30e1M7sOO8lN2Uw825XaP4CKE70jOxL5eLkSvXALWOdeVZ79iclAoz+iE8FsLPf\nbUOWAEuUtsgyyrmkcKU/ddvtvEwsBFqZ0CxxqOCDXj+uXoGifyFLigkl3w5wvY0s\njpe1wipvIwKBgQCUvvpc5XugC8ZlSlK0X5dG3XsTTamw2Lc2BRgP1wCOwYSVRwvi\noFbV16DcatyNBHv5HSTFpiIHsVQfG6foDtK4ROOCd8jW90O6VNFxEym04K2CbC6z\n96zvDPIMrUH/lojkVMIzrM4EDEi0bMyOYlQJKA4VbZbBTQMnZq90Tpsr8QKBgQCr\nd/k9aZGuIWsFEb+JsLdY2BI+ChC1ufvrwLDO5obk8UqmR5DxUxh597QyrnK3XzzE\n00FOOUduUJst8BrRohoGbmAg9LehQpBdFu/2L/MPjjosfyP+2l079EtM0QrxF22c\nvzuWLT7vN2JKajZDyxnEzquO8rT3HAg/r29d3FoKBwKBgQCM4BNOTBT10gCPKQBx\nApULMInlweLr393rc17cJHSSLmL0z26oIfpJYVf+AbV4sLKE9HaCmwxTiR/frt9f\nEhAaOsWfprl/CFC3kcF/Vndey2v9Nlwdzl7//8c0O8ITlqt+OpK3giOUquMWuG8i\nFU9AwpseRhEp5uHZ5e1wKgsEsA==\n-----END PRIVATE KEY-----\n",
+ "client_email": "chengdatest@chengda-466307.iam.gserviceaccount.com",
+ "client_id": "108513526311014104962",
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+ "token_uri": "https://oauth2.googleapis.com/token",
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/chengdatest%40chengda-466307.iam.gserviceaccount.com",
+ "universe_domain": "googleapis.com"
+}
diff --git a/dl_admin/ruoyi-admin/src/main/resources/google-ads.properties b/dl_admin/ruoyi-admin/src/main/resources/google-ads.properties
index 5b96098..0259589 100644
--- a/dl_admin/ruoyi-admin/src/main/resources/google-ads.properties
+++ b/dl_admin/ruoyi-admin/src/main/resources/google-ads.properties
@@ -1,6 +1,6 @@
-# Google Ads API ??
-api.googleads.clientId=76632811767-p4ieetlihrr311tfk7hchovo1kcqkh4o.apps.googleusercontent.com
-api.googleads.clientSecret=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
-api.googleads.refreshToken=YOUR_REFRESH_TOKEN
+# ????????? refreshToken?
+api.googleads.pathToCredentialsFile=D:/A_lighting_product/dl_site_system/dl_admin/ruoyi-admin/src/main/resources/chengda.json
+# ????? Developer Token
api.googleads.developerToken=qwFA3dGfOGqEhSEHlCMorA
-api.googleads.loginCustomerId=YOUR_MANAGER_ACCOUNT_ID # ??? MCC ??
+# ????? MCC ?? ID???? MCC)
+api.googleads.loginCustomerId=3283220394
\ No newline at end of file
diff --git a/dl_admin/ruoyi-admin/src/main/resources/test.json b/dl_admin/ruoyi-admin/src/main/resources/test.json
new file mode 100644
index 0000000..9b6b8e9
--- /dev/null
+++ b/dl_admin/ruoyi-admin/src/main/resources/test.json
@@ -0,0 +1,13 @@
+{
+ "type": "service_account",
+ "project_id": "sunny-caldron-467002-e6",
+ "private_key_id": "a38b797901a6c00d69abfe43374d467fd412871d",
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCpJv+RAS5dlqbJ\nLruF0ANGpdpobnjTmWLT99x7FvrxDunDCiO5JlqhSa8M+YsnJnluZIN85uAPOzpF\nRWMSmZLtdwz2GH2RdDai6rN88M2O3YiaNYS8AOmXfw5Q2zzchHBCnaXw1EHAENUr\nxD77eeYnlVg5U1gUyFwIeeV/o2YezKdMEA4OIdz7tLz0BdW+7wCH+sGzp7NkStkh\nvcV/sK0TRqVdU5z54cH1ndpinDPPwPyXWpV6r3L1QaeD73kgAOHcc23Rlq5BHbCs\n8CIreUnSN6i3Nix597bd9d0p7yBeEYj0F9UV7F3rkXxo2tA45WlmY+ZlgJMNofAa\n7gKfdvKfAgMBAAECggEAARgmJ3VQldFq9Kxbk0CwxyXbfl+82IU6UnHvJ56Es/gM\n2XnKNuIwL83IUejcDkxxv6wgFf8i0+huMaRT57f0tn3V0ToOhnusA/4UhIJCue8/\nRnLb41nuchcwCEbJ0DW6qT74iVj0zKu1TZqCYhbEaedBlDgYSQBLUHNDiEG60etv\nHX3Vgfjaz0ul1v6SaQVjfixRYzLAIpXFvTCzBynQhdvm1+FhL8u4ABPfTKqxYBet\nz9sGGq7Z6EKOCD+w+ppuZgJlGYgXezZuLSIWZy0I9m/adGcup6xw+mWb2EsYevtG\nthlyumpRtBQVWXIrXshymByOYPy0DNFAcl80+fVcIQKBgQDW090TiMjFhnAKinco\ne8FxwaX43ax2Dl0CZFG/qh7jO8TNrxDADoluMmlQUYgHxn/xoHOmh90XyInSH4pg\nBsOfF7FVmkjnVRQQCHmU3MqbZMcm9EZLS6w29iIpd9eyDgY/KAjksaLP6xTpFc0r\nmWhSShk6SIb8DAvbvJy5iQwt4QKBgQDJkii0gz28nN2n0Bw8VQFwgUw1a88pzWZv\nBY3RaDT9f+c82bMhmNKSsE0hDTnUlpLzo/FGVE1oG6wOS5dMx3YmVKpKGLsKOSP+\nJclzLkYEsJl2Q55gcjD6/4ETtqQ2CFmouBl199iG/aYsvqZafKCCgpmWSKC7/0Cf\nnCVuIBIwfwKBgGDJzYYaj5Jm8p3dKriDoXE2NSf9/9CkwgTs2+QFqqroZ8/fuyU8\np3CNp+M3CJmwNj7P8qsp9VPc1zNjYH3JLmPEUfJmc8g+Da73koeePm5qpkuHrRAJ\nhQqyNEwIoZaoOOpFiFQ5MEiK+r3VQ74L/PNuTRV0TdTLPKCAxv/UnjchAoGAOKnM\npYnrNfVG3iDDfzZKNE00liPbVZ32+KiwCDjqBIULBPERyRUDxNaop+zm39sALltc\nvO9/3w9AW7hmLOA5V2cfg7rWAXa0poIK0kUky7a1PSifAe+30yc2KsuB9+p7AdHW\n3nGwvanaJ+PkMbWtDWMXN8bs4ExN51BmuUFsu5MCgYEAmTq81xDw/tIK6x6QYo1S\nEobTXo7KE01cjraOR0Kjk/MtEKlwBQVcDY79LnLzc2p5H0Jfm6MWIzcg+8pRm+gA\nOROfbhB9omfHWZ0PdNBe5Gd3nzEKQGWvSYcqLhZu+4pXYTbEpJLLfhR83oSldJ26\ng54JAsrVH5nTBbbxxxBXCtA=\n-----END PRIVATE KEY-----\n",
+ "client_email": "mwjtest@sunny-caldron-467002-e6.iam.gserviceaccount.com",
+ "client_id": "101980709462554291854",
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+ "token_uri": "https://oauth2.googleapis.com/token",
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/mwjtest%40sunny-caldron-467002-e6.iam.gserviceaccount.com",
+ "universe_domain": "googleapis.com"
+}
diff --git a/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java b/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java
new file mode 100644
index 0000000..cd88af1
--- /dev/null
+++ b/dl_admin/ruoyi-common/src/main/java/com/ruoyi/common/config/GoogleConfig.java
@@ -0,0 +1,20 @@
+package com.ruoyi.common.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @description google ads配置类
+ * @author vinjor-m
+ */
+@ConfigurationProperties(prefix = "google.ads")
+@Configuration
+@Data
+public class GoogleConfig {
+ private Long customerId;
+ private String developerToken;
+ private String jsonPath;
+
+
+}