This commit is contained in:
Vinjor 2025-07-25 17:35:13 +08:00
parent 374d079e33
commit cf70d87ba2
8 changed files with 195 additions and 11 deletions

View File

@ -148,7 +148,7 @@
<dependency> <dependency>
<groupId>com.google.api-ads</groupId> <groupId>com.google.api-ads</groupId>
<artifactId>google-ads</artifactId> <artifactId>google-ads</artifactId>
<version>28.0.0</version> <!-- 使用最新版本 --> <version>38.0.0</version> <!-- 使用最新版本 -->
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -14,10 +14,7 @@ import com.ruoyi.busi.domain.BusiCategory;
import com.ruoyi.busi.domain.BusiChatMain; import com.ruoyi.busi.domain.BusiChatMain;
import com.ruoyi.busi.domain.BusiInquiryItem; import com.ruoyi.busi.domain.BusiInquiryItem;
import com.ruoyi.busi.domain.BusiProdNew; import com.ruoyi.busi.domain.BusiProdNew;
import com.ruoyi.busi.service.IBusiCategoryService; import com.ruoyi.busi.service.*;
import com.ruoyi.busi.service.IBusiChatMainService;
import com.ruoyi.busi.service.IBusiInquiryItemService;
import com.ruoyi.busi.service.IBusiProdNewService;
import com.ruoyi.busi.utils.CommonUtils; import com.ruoyi.busi.utils.CommonUtils;
import com.ruoyi.busi.vo.BusiCategoryVO; import com.ruoyi.busi.vo.BusiCategoryVO;
import com.ruoyi.busi.vo.ProdNewVO; import com.ruoyi.busi.vo.ProdNewVO;
@ -72,6 +69,8 @@ public class WebController extends BaseController {
private IBusiInquiryItemService inquiryItemService; private IBusiInquiryItemService inquiryItemService;
@Autowired @Autowired
private IBusiChatMainService busiChatMainService; private IBusiChatMainService busiChatMainService;
@Autowired
private GoogleKeywordService googleKeywordService;
/** /**
* 导航栏接口--所有分类 * 导航栏接口--所有分类
@ -412,4 +411,10 @@ public class WebController extends BaseController {
inquiryItemService.save(inquiryItem); inquiryItemService.save(inquiryItem);
return R.ok(); return R.ok();
} }
@GetMapping("/test")
public R<?> test(){
googleKeywordService.test();
return R.ok();
}
} }

View File

@ -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<String> seedKeywords = Arrays.asList("TRUCK");
// 英语
String language = "languageConstants/1000";
// 美国
String geoTarget = "geoTargetConstants/2840";
// 3. 获取关键词提示
List<GenerateKeywordIdeaResult> 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<GenerateKeywordIdeaResult> generateKeywordIdeas(
GoogleAdsClient googleAdsClient,
long customerId,
List<String> seedKeywords,
String language,
String geoTarget) throws IOException {
List<GenerateKeywordIdeaResult> 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;
}
}

View File

@ -150,5 +150,10 @@ aliyun:
access-key-id: LTAI5tLThQFWgMLRTf3siNjb access-key-id: LTAI5tLThQFWgMLRTf3siNjb
access-key-secret: M5HjOyB8ir5tYEPFOQwImfJNgsumaG access-key-secret: M5HjOyB8ir5tYEPFOQwImfJNgsumaG
bucket-name: dianliang123 bucket-name: dianliang123
#google ads配置
google:
ads:
customer-id: 4577179829
developer-token: qwFA3dGfOGqEhSEHlCMorA
json-path: /www/wwwroot/nuxt/test.json

View File

@ -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"
}

View File

@ -1,6 +1,6 @@
# Google Ads API ?? # ????????? refreshToken?
api.googleads.clientId=76632811767-p4ieetlihrr311tfk7hchovo1kcqkh4o.apps.googleusercontent.com api.googleads.pathToCredentialsFile=D:/A_lighting_product/dl_site_system/dl_admin/ruoyi-admin/src/main/resources/chengda.json
api.googleads.clientSecret=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 # ????? Developer Token
api.googleads.refreshToken=YOUR_REFRESH_TOKEN
api.googleads.developerToken=qwFA3dGfOGqEhSEHlCMorA api.googleads.developerToken=qwFA3dGfOGqEhSEHlCMorA
api.googleads.loginCustomerId=YOUR_MANAGER_ACCOUNT_ID # ??? MCC ?? # ????? MCC ?? ID???? MCC)
api.googleads.loginCustomerId=3283220394

View File

@ -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"
}

View File

@ -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;
}