Prechádzať zdrojové kódy

fix 声破天注册接口升级v2版本

chenbiao 3 rokov pred
rodič
commit
3977be4b3d

+ 1 - 1
netflix-common/src/main/java/com/cyksj/dto/RedisKey.java

@@ -46,6 +46,6 @@ public class RedisKey {
     /**
      * 付费ip
      */
-    public static String DOVEIP = "dove_ip";
+    public static String IP_LIST = "ip_list";
 
 }

+ 105 - 0
netflix-dao/src/main/java/com/cyksj/model/request/SpotifyRegisterReq.java

@@ -0,0 +1,105 @@
+package com.cyksj.model.request;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author chan
+ * @date 2023/1/9 5:33 PM
+ */
+@Data
+public class SpotifyRegisterReq {
+    /*
+    {
+            "account_details": {
+                "birthdate": "2001-06-23",
+                "consent_flags": {
+                    "eula_agreed": true,
+                    "send_email": false,
+                    "third_party_email": true
+                },
+                "display_name": "chan sudie",
+                "email_and_password_identifier": {
+                    "email": "chansuide@github.com",
+                    "password": "chansuide1234"
+                },
+                "gender": 1
+            },
+            "callback_uri": "https://www.spotify.com/signup/challenge?locale=tr",
+            "client_info": {
+                "api_key": "a1e486e2729f46d6bb368d6b2bcda326",
+                "app_version": "v2",
+                "capabilities": [1],
+                "installation_id": "07b84cda-709c-432e-af56-84245c6e4294",
+                "platform": "www"
+            },
+            "tracking": {
+                "creation_flow": "",
+                "creation_point": "https://www.spotify.com/tr/",
+                "referrer": ""
+            }
+        }
+     */
+    private AccountDetails account_details;
+
+    private String callback_uri = "https://www.spotify.com/signup/challenge?locale=tr";
+
+    private ClientInfo client_info = new ClientInfo();
+
+    private Tracking tracking = new Tracking();
+
+    @Data
+    public static class AccountDetails{
+
+        private String birthdate;
+
+        private ConsentFlags consent_flags = new ConsentFlags();
+
+        private String display_name;
+
+        private EmailAndPasswordIdentifier email_and_password_identifier;
+
+        private Integer gender;
+        @Data
+        public static class ConsentFlags{
+            private Boolean eula_agreed = true;
+
+            private Boolean send_email = true;
+
+            private Boolean third_party_email = true;
+        }
+        @Data
+        public static class EmailAndPasswordIdentifier{
+            /*
+            "email": "chansuide@github.com",
+                    "password": "chansuide1234"
+             */
+            private String email;
+
+            private String password;
+        }
+    }
+    @Data
+    public static class ClientInfo{
+
+        private String api_key =  "a1e486e2729f46d6bb368d6b2bcda326";
+
+        private String app_version = "v2";
+
+        private List<Integer> capabilities = List.of(1);
+
+        private String installation_id = "07b84cda-709c-432e-af56-84245c6e4294";
+
+        private String platform = "www";
+    }
+    @Data
+    public static class Tracking{
+
+        private String creation_flow = "";
+
+        private String creation_point = "https://www.spotify.com/tr/";
+
+        private String referrer = "";
+    }
+}

+ 11 - 0
netflix-service/pom.xml

@@ -35,6 +35,17 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-mail</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.apache.httpcomponents</groupId>
+            <artifactId>fluent-hc</artifactId>
+            <version>4.5.6</version>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>4.5.0</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 2 - 0
netflix-service/src/main/java/com/cyksj/service/register/SpotifyService.java

@@ -1,5 +1,7 @@
 package com.cyksj.service.register;
 
+import java.io.IOException;
+
 /**
  * @author chan
  * @date 2022/11/7 1:54 PM

+ 108 - 129
netflix-service/src/main/java/com/cyksj/service/register/impl/SpotifyServiceImpl.java

@@ -1,12 +1,14 @@
 package com.cyksj.service.register.impl;
 
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.lang.UUID;
 import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.http.Method;
+import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -21,6 +23,7 @@ import com.cyksj.mapper.manage.coupon.CouponMapper;
 import com.cyksj.model.dto.WxMpTemplateData;
 import com.cyksj.model.dto.WxMpTemplateMessage;
 import com.cyksj.model.entity.*;
+import com.cyksj.model.request.SpotifyRegisterReq;
 import com.cyksj.model.response.ProxyInfo;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.mange.coupon.CouponCommonService;
@@ -29,11 +32,14 @@ import com.cyksj.service.sys.SysConfigService;
 import com.cyksj.service.wechat.WeChatService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 
+import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -98,160 +104,134 @@ public class SpotifyServiceImpl implements SpotifyService {
             "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11",
             "Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10");
 
+
     @Override
     public void register(Long registerOrderId){
         log.info("spotify 注册 orderId:{}",registerOrderId);
         RegisterOrderDon registerOrderDon = registerOrderDonMapper.selectById(registerOrderId);
-        HttpRequest request = new HttpRequest("https://spclient.wg.spotify.com/signup/public/v1/account");
 
-        request.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36");
-        request.header("Connection","close");
-        //request.header( "Accept","*/*");
-        request.header( "Content-Type","application/x-www-form-urlencoded");
-        request.header( "Referer","https://www.spotify.com/");
-        request.header( "Host","spclient.wg.spotify.com");
+        SpotifyRegisterReq registerReq = new SpotifyRegisterReq();
+        SpotifyRegisterReq.AccountDetails accountDetails = new SpotifyRegisterReq.AccountDetails();
+        SpotifyRegisterReq.AccountDetails.EmailAndPasswordIdentifier emailAndPasswordIdentifier = new SpotifyRegisterReq.AccountDetails.EmailAndPasswordIdentifier();
+        emailAndPasswordIdentifier.setEmail(registerOrderDon.getEmail());
+        emailAndPasswordIdentifier.setPassword(registerOrderDon.getPassword());
+        accountDetails.setEmail_and_password_identifier(emailAndPasswordIdentifier);
+        accountDetails.setBirthdate(Optional.ofNullable(registerOrderDon.getBirthYear()).orElse("1989") + "-" + Optional.ofNullable(registerOrderDon.getBirthMonth()).orElse("10") + "-" + Optional.ofNullable(registerOrderDon.getBirthDay()).orElse("06"));
+        accountDetails.setDisplay_name(emailAndPasswordIdentifier.getEmail());
+        accountDetails.setGender(1);
+        registerReq.setAccount_details(accountDetails);
 
-        Map<String,Object> jsonObject = new HashMap<>();
-        jsonObject.put("key","a1e486e2729f46d6bb368d6b2bcda326");
-        //creation_point=https://www.spotify.com/uk/
-        jsonObject.put("creation_point","https://www.spotify.com/us/");
-        jsonObject.put("displayname",Optional.ofNullable(registerOrderDon.getNickname()).orElse(registerOrderDon.getEmail()));
-        jsonObject.put("password_repeat",registerOrderDon.getPassword());
-        jsonObject.put("password",registerOrderDon.getPassword());
-        jsonObject.put("username",Optional.ofNullable(registerOrderDon.getUsername()).orElse(registerOrderDon.getEmail()));
-        jsonObject.put("birth_year", Optional.ofNullable(registerOrderDon.getBirthYear()).orElse("1995"));
-        jsonObject.put("birth_month",Optional.ofNullable(registerOrderDon.getBirthMonth()).orElse("01"));
-        jsonObject.put("birth_day",Optional.ofNullable(registerOrderDon.getBirthDay()).orElse("01"));
-        jsonObject.put("gender",registerOrderDon.getGender());
-        jsonObject.put("email",registerOrderDon.getEmail());
-        jsonObject.put("iagree","1");
-        request.setMethod(Method.POST);
-        request.setConnectionTimeout(15 * 1000);
-        request.setReadTimeout(15 * 1000);
+        Map<String,String> map = new HashMap<>();
+        map.put("User-Agent", User_Agent_LIST.get(RandomUtil.randomInt(User_Agent_LIST.size())));
+        map.put( "authority","spclient.wg.spotify.com");
+        map.put( "method","POST");
+        map.put("Host","spclient.wg.spotify.com");
+        map.put("Accept", "*/*");
+        map.put( "path","/signup/public/v2/account/create");
+        map.put( "Referer", "https://www.spotify.com/");
+        map.put("Content-Type", "application/json; charset=utf-8");
+        map.put("Origin", "https://www.spotify.com");
+        map.put("Connection", "keep-alive");
+        map.put("sec-ch-ua", "\"Not?A_Brand\";v=\"8\", \"Chromium\";v=\"108\", \"Google Chrome\";v=\"108\"");
+        map.put("sec-ch-ua-mobile", "?0");
+        map.put("sec-ch-ua-platform", "Windows");
+        map.put("Sec-Fetch-Dest", "empty");
+        map.put("Sec-Fetch-Mode", "cors");
+        map.put("Sec-Fetch-Site", "same-site");
+        map.put("referrer-policy", "strict-origin-when-cross-origin");
+        List<ProxyInfo> proxyInfos = (List<ProxyInfo>) redisService.get(RedisKey.IP_LIST);
+        if (proxyInfos == null || proxyInfos.size() == 0) {
+            String res = HttpUtil.get("http://api.proxy.ipidea.io/getProxyIp?num=10&return_type=json&lb=1&sb=0&flow=1&regions=jp&protocol=http");
+            JSONObject jsonObject = JSONUtil.parseObj(res);
+            JSONArray data = jsonObject.getJSONArray("data");
+            proxyInfos = data.toList(ProxyInfo.class);
+        }
+        int count = 1;
+        while (count <= 10) {
+            for (ProxyInfo proxyInfo : proxyInfos) {
+                try {
+                    log.info("执行:info:{}", proxyInfo);
 
-        request.form(jsonObject);
+                    Proxy proxy = new Proxy(Proxy.Type.HTTP,
+                            new InetSocketAddress(proxyInfo.getIp(), proxyInfo.getPort()));
+                    OkHttpClient client = new OkHttpClient().newBuilder().proxy(proxy).build();
+                    RequestBody requestBody = FormBody.create(JSONUtil.toJsonStr(registerReq).getBytes(StandardCharsets.UTF_8),MediaType.parse("application/json; charset=utf-8"));
 
+                    Request request = new Request.Builder()
+                            .url("https://spclient.wg.spotify.com/signup/public/v2/account/create")
+                            .post(requestBody)
+                            .headers(Headers.of(map))
+                            .build();
 
-        int start = 1;
-        int limit = 20;
-        boolean regFlag = false;
-        while (true) {
+                    okhttp3.Response response = client.newCall(request).execute();
+                    ResponseBody body = response.body();
 
-            List<ProxyInfo> proxyInfos = new ArrayList<>();
-            List<Proxys> records = proxysMapper.selectPage(new Page<>(start, limit), Wrappers.lambdaQuery(Proxys.class).orderByDesc(Proxys::getId)).getRecords();
-            if (records.isEmpty()) {
-                log.info("----------代理池内无可用ip 获取付费IP地址----------");
-                ProxyInfo proxyInfo = (ProxyInfo)redisService.get(RedisKey.DOVEIP);
-                if (proxyInfo == null) {
+                    String spotifyBody = body.string();
 
-                    String result = HttpUtil.get("https://dvapi.doveip.com/cmapi.php?rq=distribute&user=1031494735&token=ckc1MUFURnk3bi80MXVxeUFTZUh0Zz09&auth=0&geo=tr&agreement=0&timeout=10&num=1&type_ip=1&repeat=0");
-                    log.info("付费ip 请求返回 res:{}",result);
+                    log.info("spotify 返回body:{}", spotifyBody);
                     /*
-                     * {
-                     *   "errno": 200,
-                     *   "msg": "Success",
-                     *   "data": {
-                     *     "geo": "mx", //国家
-                     *     "ip": "47.253.12.97", //代理ip
-                     *     "port": 40076, //代理端口
-                     *     "d_ip": "201.162.169.86" //目标ip
-                     *     "timeout": 600 //有效时间(秒)
-                     *   }
-                     * }
-                     */
-                    JSONObject resObj = JSONUtil.parseObj(result);
-                    if (200 == resObj.getInt("errno")) {
-                        JSONObject data = resObj.getJSONObject("data");
-                        proxyInfo = new ProxyInfo();
-                        proxyInfo.setPort(data.getInt("port"));
-                        proxyInfo.setIp(data.getStr("ip"));
-                        log.info("----------付费IP地址----------\n ip:{}",proxyInfo);
-                        proxyInfos.add(proxyInfo);
-                        redisService.set(RedisKey.DOVEIP,proxyInfo,data.getLong("timeout"));
-                    }else {
-                        log.error("----------获取 付费IP 错误 停止循环----------");
-                        break;
-                    }
-                }else {
-                    proxyInfos.add(proxyInfo);
-                }
-            }
-
-            proxyInfos.addAll(records.stream().map((proxy) -> {
-                ProxyInfo proxyInfo = new ProxyInfo();
-                proxyInfo.setIp(proxy.getIp());
-                proxyInfo.setPort(proxy.getPort());
-                return proxyInfo;
-            }).collect(Collectors.toList()));
+                    {
+                        "error":{
+                            "error_details":{
+                                "code":2,
+                                "title":"请检查你的详细信息,然后再试一次。",
+                                "body":"此电子邮件已关联至某个帐号。请登录你的帐号,或使用其他电子邮件注册。",
+                                "already_exists":{
 
-            for (ProxyInfo proxyInfo : proxyInfos) {
-                try {
-                    log.info("执行:info:{}", proxyInfo);
-                    Proxy proxy = new Proxy(Proxy.Type.SOCKS,
-                            new InetSocketAddress(proxyInfo.getIp(), proxyInfo.getPort()));
-                    request.setProxy(proxy);
-                    HttpResponse response = request.execute();
-                    String body = response.body();
-                    log.info("spotify 返回body:{}", body);
-                    JSONObject resObj = JSONUtil.parseObj(body);
-                    JSONObject errors = resObj.getJSONObject("errors");
-
-                    Integer status = resObj.getInt("status");
-                    if (status == 320) {
-                        String errorMsg = errors.getStr("generic_error");
-                        if (StringUtils.isNotBlank(errorMsg) || "你似乎正在使用代理服务。请关闭此类服务,然后再试一次。如需更多帮助,请联系客户服务。".equals(errorMsg) || errorMsg.contains("代理")) {
-                            log.info("spotify 注册 被监测出代理服务 。 删除该代理 ip:{}", proxyInfo.getIp());
-                            if (proxyInfo.getId() != null) {
-                                int count = proxysMapper.deleteById(proxyInfo.getId());
-                            }else {
-                                redisService.del(RedisKey.DOVEIP);
+                                }
                             }
-                            continue;
                         }
                     }
+                     */
+                    /*
+                    {
+                        "success": {
+                            "username": "31naixo6v3uydhvcp63sya57ozae",
+                            "login_token": "N7N9gHZ3QeG74yHWAx8hAw"
+                        }
+                    }
+                     */
+                    JSONObject resObj = JSONUtil.parseObj(spotifyBody);
+                    JSONObject error_details = resObj.getJSONObject("error").getJSONObject("error_details");
 
-                    if (StringUtils.isNotBlank(resObj.getStr("login_token"))) {
-                        log.info("注册成功!");
-                        registerOrderDon.setStatus(RegisterOrderDon.Status.complete);
-                        registerOrderDonMapper.updateById(registerOrderDon);
-                        regFlag = true;
-                        //注册成功发放模板消息
-                        spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), true);
-                        //注册成功发放声破天优惠券
-                        sendSpotifyCoupon(registerOrderDon);
-                        break;
-                    } else {
-                        if (errors != null && !errors.isEmpty()) {
-                            StringBuilder error = new StringBuilder();
-                            for (String str : errors.keySet()) {
-                                error.append(errors.getStr(str));
-                            }
-                            registerOrderDon.setErrorMsg(error.toString());
-                            registerOrderDon.setStatus(RegisterOrderDon.Status.error);
+                    if (error_details == null) {
+                        JSONObject success = resObj.getJSONObject("success");
+                        if (StringUtils.isNotBlank(success.getStr("login_token")) || StringUtils.isNotBlank("username")) {
+                            log.info("注册成功!");
+                            registerOrderDon.setStatus(RegisterOrderDon.Status.complete);
                             registerOrderDonMapper.updateById(registerOrderDon);
-                            regFlag = true;
-                            //注册失败发放模板消息
-                            spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), false);
+                            //注册成功发放模板消息
+                            spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), true);
+                            //注册成功发放声破天优惠券
+                            sendSpotifyCoupon(registerOrderDon);
                             break;
                         }
-                    }
-
-                } catch (Exception e) {
-                    if (proxyInfo.getId() != null) {
-                        proxysMapper.deleteById(proxyInfo.getId());
                     }else {
-                        redisService.del(RedisKey.DOVEIP);
+                        String errorMsg = error_details.getStr("body");
+                        if (errorMsg.equals("4") ||StringUtils.isNotBlank(errorMsg) || "你的设备似乎已连接至代理或 VPN 服务。请关闭此类服务,然后再试一次。".equals(errorMsg) || errorMsg.contains("代理")) {
+                            log.info("spotify 注册 被监测出代理服务 。 删除该代理 ip:{}", proxyInfo.getIp());
+                            proxyInfos.remove(proxyInfo);
+                            continue;
+                        }
+                        //{"error":{"error_details":{"code":2,"title":"请检查你的详细信息,然后再试一次。","body":"此电子邮件已关联至某个帐号。请登录你的帐号,或使用其他电子邮件注册。","already_exists":{}}}}
+                        registerOrderDon.setErrorMsg(error_details.getStr("body"));
+                        registerOrderDon.setStatus(RegisterOrderDon.Status.error);
+                        registerOrderDonMapper.updateById(registerOrderDon);
+
+                        //注册失败发放模板消息
+                        spotifyTemplateMsg(registerOrderDon, String.format("%s%s", envCommonService.getDomain(), "yinhe/web/sign/list"), false);
+                        break;
+
                     }
-                    e.printStackTrace();
+                } catch (Exception e) {
+                    proxyInfos.remove(proxyInfo);
                     log.error("错误 ip:{}", proxyInfo.getIp());
+                    count++;
                 }
             }
-
-            if (regFlag) {
-                break;
-            }
-
         }
+
+        redisService.set(RedisKey.IP_LIST,proxyInfos,600L);
     }
 
     private void sendSpotifyCoupon(RegisterOrderDon registerOrderDon) {
@@ -287,5 +267,4 @@ public class SpotifyServiceImpl implements SpotifyService {
         weChatService.sendTemplateMessage(weChatService.getAccessToken(), Jsons.toJson(templateMessage));
     }
 
-
 }

+ 1 - 0
netflix-service/src/main/java/com/cyksj/task/Scheduler.java

@@ -24,6 +24,7 @@ import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;