diff --git a/src/main/java/net/Broken/Init.java b/src/main/java/net/Broken/Init.java index 08e20a2..592728b 100644 --- a/src/main/java/net/Broken/Init.java +++ b/src/main/java/net/Broken/Init.java @@ -1,5 +1,6 @@ package net.Broken; +import net.Broken.RestApi.ApiCommandLoader; import net.Broken.Tools.Command.CommandLoader; import net.Broken.Tools.DayListener.DayListener; import net.Broken.Tools.DayListener.Listeners.DailyMadame; @@ -30,15 +31,13 @@ public class Init { * @param dev dev Mode or not * @return JDA object */ - static JDA initBot(String token, boolean dev){ - boolean okInit; + static JDA initJda(String token, boolean dev){ JDA jda = null; logger.debug("-------------------INITIALISATION-------------------"); //Bot démarrer sans token if (token == null) { logger.fatal("Veuilliez indiquer le token du bot en argument..."); - okInit=false; } else { @@ -58,8 +57,6 @@ public class Init { *************************************/ jda.getPresence().setGame(Game.of("Statut: Loading...")); jda.getTextChannels().forEach(textChannel -> textChannel.sendTyping().queue()); - YoutubeTools.getInstance(jda.getGuilds().get(0)).getYouTubeService(); - CommandLoader.load(); //On recupere le l'id serveur @@ -106,11 +103,15 @@ public class Init { catch (LoginException | InterruptedException | RateLimitedException e) { logger.catching(e); - } catch (IOException e) { - e.printStackTrace(); } } return jda; } + + + static void polish(){ + CommandLoader.load(); + ApiCommandLoader.load(); + } } diff --git a/src/main/java/net/Broken/MainBot.java b/src/main/java/net/Broken/MainBot.java index c70c56e..2cbc94a 100644 --- a/src/main/java/net/Broken/MainBot.java +++ b/src/main/java/net/Broken/MainBot.java @@ -6,6 +6,7 @@ import net.Broken.Tools.EmbedMessageUtils; import net.Broken.Tools.MessageTimeOut; import net.Broken.Tools.PrivateMessage; import net.Broken.Tools.UserSpamUtils; +import net.Broken.audio.Youtube.YoutubeTools; import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.Permission; import net.dv8tion.jda.core.entities.ChannelType; @@ -20,6 +21,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.stereotype.Controller; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -69,7 +71,7 @@ public class MainBot { i++; } - jda = Init.initBot(token, dev); + jda = Init.initJda(token, dev); ConfigurableApplicationContext ctx = SpringApplication.run(MainBot.class, args); if(jda == null) { System.exit(SpringApplication.exit(ctx, (ExitCodeGenerator) () -> { @@ -78,8 +80,13 @@ public class MainBot { })); } + try { + YoutubeTools.getInstance(jda.getGuilds().get(0)).getYouTubeService(); + } catch (IOException e) { + e.printStackTrace(); + } - ApiCommandLoader.load(); + Init.polish(); @@ -145,13 +152,25 @@ public class MainBot { else { MessageReceivedEvent event = cmd.event; - if(event.isFromType(ChannelType.PRIVATE)) - event.getPrivateChannel().sendMessage(EmbedMessageUtils.getUnknowCommand()).queue(); - else { - Message message = event.getTextChannel().sendMessage(EmbedMessageUtils.getUnknowCommand()).complete(); - new MessageTimeOut(messageTimeOut, message, event.getMessage()); + if(commandes.size() == 0){ + if(event.isFromType(ChannelType.PRIVATE)) + event.getPrivateChannel().sendMessage("Loading please wait...").queue(); + else { + Message message = event.getTextChannel().sendMessage("Loading please wait...").complete(); + new MessageTimeOut(messageTimeOut, message, event.getMessage()); + } } - logger.warn("Commande inconnue"); + else{ + + if(event.isFromType(ChannelType.PRIVATE)) + event.getPrivateChannel().sendMessage(EmbedMessageUtils.getUnknowCommand()).queue(); + else { + Message message = event.getTextChannel().sendMessage(EmbedMessageUtils.getUnknowCommand()).complete(); + new MessageTimeOut(messageTimeOut, message, event.getMessage()); + } + logger.warn("Commande inconnue"); + } + } diff --git a/src/main/java/net/Broken/audio/Youtube/Authorization.java b/src/main/java/net/Broken/audio/Youtube/Authorization.java new file mode 100644 index 0000000..8d772df --- /dev/null +++ b/src/main/java/net/Broken/audio/Youtube/Authorization.java @@ -0,0 +1,42 @@ +package net.Broken.audio.Youtube; + +import com.google.api.client.auth.oauth2.AuthorizationCodeFlow; +import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl; +import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; +import com.google.api.client.extensions.java6.auth.oauth2.VerificationCodeReceiver; +import com.google.api.client.util.Preconditions; +import net.Broken.Tools.PrivateMessage; +import net.dv8tion.jda.core.entities.Guild; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; + +public class Authorization extends AuthorizationCodeInstalledApp { + + private Guild guild; + private Logger logger = LogManager.getLogger(); + + /** + * @param flow authorization code flow + * @param receiver verification code receiver + */ + public Authorization(AuthorizationCodeFlow flow, VerificationCodeReceiver receiver, Guild guild) { + super(flow, receiver); + this.guild = guild; + } + + @Override + protected void onAuthorization(AuthorizationCodeRequestUrl authorizationUrl) throws IOException { + notify(authorizationUrl.build()); + } + + protected void notify(String url){ + Preconditions.checkNotNull(url); + // Ask user to open in their browser using copy-paste + logger.fatal("Please open this URL: "+url); + PrivateMessage.send(guild.getOwner().getUser(),"Please open this url to confirm google api account acces : " + url,null); + + + } +} diff --git a/src/main/java/net/Broken/audio/Youtube/Autorization.java b/src/main/java/net/Broken/audio/Youtube/Autorization.java deleted file mode 100644 index 8ae3531..0000000 --- a/src/main/java/net/Broken/audio/Youtube/Autorization.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2012 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software distributed under the License - * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - * or implied. See the License for the specific language governing permissions and limitations under - * the License. - */ - -package net.Broken.audio.Youtube; -import com.google.api.client.auth.oauth2.AuthorizationCodeFlow; -import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl; -import com.google.api.client.auth.oauth2.Credential; -import com.google.api.client.auth.oauth2.TokenResponse; -import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; -import com.google.api.client.extensions.java6.auth.oauth2.VerificationCodeReceiver; -import com.google.api.client.util.Preconditions; -import net.Broken.Tools.PrivateMessage; -import net.dv8tion.jda.core.entities.Guild; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.awt.*; -import java.io.IOException; - - -/** - * OAuth 2.0 authorization code flow for an installed Java application that persists end-user - * credentials. - * - *

- * Implementation is thread-safe. - *

- * - * @since 1.11 - * @author Yaniv Inbar - */ -public class Autorization { - - /** Authorization code flow. */ - private final AuthorizationCodeFlow flow; - - /** Verification code receiver. */ - private final VerificationCodeReceiver receiver; - - private static final Logger LOGGER = LogManager.getLogger(); - - private Guild guild; - /** - * @param flow authorization code flow - * @param receiver verification code receiver - */ - public Autorization(AuthorizationCodeFlow flow, VerificationCodeReceiver receiver, Guild guild) { - this.flow = Preconditions.checkNotNull(flow); - this.receiver = Preconditions.checkNotNull(receiver); - this.guild = guild; - } - - /** - * Authorizes the installed application to access user's protected data. - * - * @param userId user ID or {@code null} if not using a persisted credential store - * @return credential - */ - public Credential authorize(String userId) throws IOException { - try { - Credential credential = flow.loadCredential(userId); - if (credential != null - && (credential.getRefreshToken() != null || - credential.getExpiresInSeconds() == null || - credential.getExpiresInSeconds() > 60)) { - return credential; - } - // open in browser - String redirectUri = receiver.getRedirectUri(); - AuthorizationCodeRequestUrl authorizationUrl = - flow.newAuthorizationUrl().setRedirectUri(redirectUri); - onAuthorization(authorizationUrl); - // receive authorization code and exchange it for an access token - String code = receiver.waitForCode(); - TokenResponse response = flow.newTokenRequest(code).setRedirectUri(redirectUri).execute(); - // store credential and return it - return flow.createAndStoreCredential(response, userId); - } finally { - receiver.stop(); - } - } - - /** - * Handles user authorization by redirecting to the OAuth 2.0 authorization server. - * - *

- * Default implementation is to call {@code browse(authorizationUrl.build())}. Subclasses may - * override to provide optional parameters such as the recommended state parameter. Sample - * implementation: - *

- * - *
-     @Override
-     protected void onAuthorization(AuthorizationCodeRequestUrl authorizationUrl) throws IOException {
-     authorizationUrl.setState("xyz");
-     super.onAuthorization(authorizationUrl);
-     }
-     * 
- * - * @param authorizationUrl authorization URL - * @throws IOException I/O exception - */ - protected void onAuthorization(AuthorizationCodeRequestUrl authorizationUrl) throws IOException { - browse(authorizationUrl.build()); - } - - /** - * Open a browser at the given URL using {@link Desktop} if available, or alternatively output the - * URL to {@link System#out} for command-line applications. - * - * @param url URL to browse - */ - public void browse(String url) { - Preconditions.checkNotNull(url); - // Ask user to open in their browser using copy-paste - LOGGER.fatal("Please open this URL: "+url); - PrivateMessage.send(guild.getOwner().getUser(),"Please open this url to confirm google api account acces : " + url,null); - - } - - /** Returns the authorization code flow. */ - public final AuthorizationCodeFlow getFlow() { - return flow; - } - - /** Returns the verification code receiver. */ - public final VerificationCodeReceiver getReceiver() { - return receiver; - } -} diff --git a/src/main/java/net/Broken/audio/Youtube/Receiver.java b/src/main/java/net/Broken/audio/Youtube/Receiver.java new file mode 100644 index 0000000..b0011e4 --- /dev/null +++ b/src/main/java/net/Broken/audio/Youtube/Receiver.java @@ -0,0 +1,54 @@ +package net.Broken.audio.Youtube; + +import com.google.api.client.extensions.java6.auth.oauth2.AbstractPromptReceiver; +import net.dv8tion.jda.core.entities.Guild; +import org.apache.logging.log4j.LogManager; + +import java.io.IOException; + +public class Receiver extends AbstractPromptReceiver { + + private static Receiver INSTANCE; + private Guild guild; + private String code; + + private Receiver(Guild guild){ + this.guild = guild; + } + + public static Receiver getInstance(Guild guild){ + if(INSTANCE == null) + INSTANCE = new Receiver(guild); + return INSTANCE; + } + + + @Override + public String getRedirectUri() throws IOException { + return System.getenv("SITE_URL") + "/youtube/callback"; + } + + @Override + public String waitForCode() { + if(System.getenv("SITE_URL").isEmpty()){ + LogManager.getLogger().fatal("Please set \"SITE_URL\" environment variable and restart the bot!"); + } + while(code == null){ + try { + Thread.sleep(50); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + return code; + } + + @Override + public void stop() { + + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java b/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java index 91597b3..9a8c852 100644 --- a/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java +++ b/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java @@ -1,14 +1,11 @@ package net.Broken.audio.Youtube; import com.google.api.client.auth.oauth2.Credential; -import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp; -import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver; import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow; import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpTransport; -import com.google.api.client.json.Json; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.client.util.store.FileDataStoreFactory; @@ -88,9 +85,12 @@ public class YoutubeTools { GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder( HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES) .setDataStoreFactory(DATA_STORE_FACTORY) - .setAccessType("online") + .setAccessType("offline") .build(); - Credential credential = new Autorization(flow, new LocalServerReceiver(), guild).authorize("user"); + + + + Credential credential = new Authorization(flow, Receiver.getInstance(null), guild).authorize("user"); logger.debug("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath()); return credential; } @@ -120,11 +120,11 @@ public class YoutubeTools { YouTube.Search.List searchListRelatedVideosRequest = youtube.search().list(parameters.get("part").toString()); if (parameters.containsKey("relatedToVideoId") && parameters.get("relatedToVideoId") != "") { - searchListRelatedVideosRequest.setRelatedToVideoId(parameters.get("relatedToVideoId").toString()); + searchListRelatedVideosRequest.setRelatedToVideoId(parameters.get("relatedToVideoId")); } - if (parameters.containsKey("type") && parameters.get("type") != "") { - searchListRelatedVideosRequest.setType(parameters.get("type").toString()); + if (parameters.containsKey("type") && !parameters.get("type").equals("")) { + searchListRelatedVideosRequest.setType(parameters.get("type")); } SearchListResponse response = searchListRelatedVideosRequest.execute(); diff --git a/src/main/java/net/Broken/webView/YoutubeCallBack.java b/src/main/java/net/Broken/webView/YoutubeCallBack.java new file mode 100644 index 0000000..31cb045 --- /dev/null +++ b/src/main/java/net/Broken/webView/YoutubeCallBack.java @@ -0,0 +1,23 @@ +package net.Broken.webView; + + +import net.Broken.audio.Youtube.Receiver; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +public class YoutubeCallBack { + @RequestMapping("/youtube/callback") + public String callback(@RequestParam(value="error", required = false, defaultValue = "") String error, + @RequestParam(value = "code", required = false, defaultValue = "") String code, + Model model){ + model.addAttribute("error", error); + model.addAttribute("code", code); + if(!code.equals("")){ + Receiver.getInstance(null).setCode(code); + } + return "youtubeCallBack"; + } +} diff --git a/src/main/resources/templates/youtubeCallBack.html b/src/main/resources/templates/youtubeCallBack.html new file mode 100644 index 0000000..6b1b28a --- /dev/null +++ b/src/main/resources/templates/youtubeCallBack.html @@ -0,0 +1,139 @@ + + + + + + Music Control - Discord Bot + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+

+

+
+
+
+ + + + + + + + + +