├── README.md ├── gradle-spring-demo ├── .gitignore ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── nurigo │ │ │ └── gradlespringdemo │ │ │ ├── ExampleController.java │ │ │ ├── GradleSpringDemoApplication.java │ │ │ └── KakaoExampleController.java │ └── resources │ │ ├── application.properties │ │ └── static │ │ ├── cti.jpg │ │ └── sample.jpg │ └── test │ └── java │ └── net │ └── nurigo │ └── gradlespringdemo │ └── GradleSpringDemoApplicationTests.java ├── kotlin-spring-demo ├── .gitignore ├── build.gradle.kts ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── net │ │ │ └── nurigo │ │ │ └── kotlinspringdemo │ │ │ ├── ExampleController.kt │ │ │ ├── KakaoExampleController.kt │ │ │ └── KotlinSpringDemoApplication.kt │ └── resources │ │ ├── application.properties │ │ └── static │ │ ├── cti.jpg │ │ └── sample.jpg │ └── test │ └── kotlin │ └── net │ └── nurigo │ └── kotlinspringdemo │ └── KotlinSpringDemoApplicationTests.kt └── maven-spring-demo ├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src ├── main ├── java │ └── net │ │ └── nurigo │ │ └── mavenspringdemo │ │ ├── ExampleController.java │ │ ├── KakaoExampleController.java │ │ └── MavenSpringDemoApplication.java └── resources │ ├── application.properties │ └── static │ ├── cti.jpg │ └── sample.jpg └── test └── java └── net └── nurigo └── mavenspringdemo └── MavenSpringDemoApplicationTests.java /README.md: -------------------------------------------------------------------------------- 1 | # CoolSMS Java 예제 리스트 2 | 3 | * 실제 사용 예제의 경우 각각 프로젝트 내의 src/main/java/net/nurigo/springdemo 내의 ExampleController, KakaoExampleController를 참고해주세요. 4 | 5 | ## 실제 개발연동 시 추가해야 할 의존성 6 | 7 | ### Maven 8 | ```xml 9 | 10 | net.nurigo 11 | sdk 12 | 4.3.2 13 | 14 | ``` 15 | 16 | ### Gradle 17 | ```groovy 18 | implementation 'net.nurigo:sdk:4.3.2' 19 | ``` 20 | 21 | ### Gradle(kotlin) 22 | ```kotlin 23 | implementation("net.nurigo:sdk:4.3.2") 24 | ``` 25 | -------------------------------------------------------------------------------- /gradle-spring-demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /gradle-spring-demo/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.springframework.boot' version '2.7.5' 3 | id 'io.spring.dependency-management' version '1.0.11.RELEASE' 4 | id 'java' 5 | } 6 | 7 | group = 'net.nurigo' 8 | version = '0.0.1-SNAPSHOT' 9 | sourceCompatibility = '1.8' 10 | 11 | repositories { 12 | mavenCentral() 13 | } 14 | 15 | dependencies { 16 | implementation 'org.springframework.boot:spring-boot-starter-web' 17 | testImplementation 'org.springframework.boot:spring-boot-starter-test' 18 | implementation 'net.nurigo:sdk:4.3.2' 19 | } 20 | 21 | tasks.named('test') { 22 | useJUnitPlatform() 23 | } 24 | -------------------------------------------------------------------------------- /gradle-spring-demo/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/gradle-spring-demo/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle-spring-demo/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradle-spring-demo/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradle-spring-demo/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /gradle-spring-demo/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'gradle-spring-demo' 2 | -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/java/net/nurigo/gradlespringdemo/ExampleController.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.gradlespringdemo; 2 | 3 | import net.nurigo.sdk.NurigoApp; 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; 5 | import net.nurigo.sdk.message.model.Balance; 6 | import net.nurigo.sdk.message.model.Message; 7 | import net.nurigo.sdk.message.model.StorageType; 8 | import net.nurigo.sdk.message.request.MessageListRequest; 9 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest; 10 | import net.nurigo.sdk.message.response.MessageListResponse; 11 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse; 12 | import net.nurigo.sdk.message.response.SingleMessageSentResponse; 13 | import net.nurigo.sdk.message.service.DefaultMessageService; 14 | import org.springframework.core.io.ClassPathResource; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.time.Instant; 22 | import java.time.LocalDateTime; 23 | import java.time.ZoneId; 24 | import java.time.ZoneOffset; 25 | import java.time.format.DateTimeFormatter; 26 | import java.util.ArrayList; 27 | 28 | @RestController 29 | public class ExampleController { 30 | 31 | final DefaultMessageService messageService; 32 | 33 | public ExampleController() { 34 | // 반드시 계정 내 등록된 유효한 API 키, API Secret Key를 입력해주셔야 합니다! 35 | this.messageService = NurigoApp.INSTANCE.initialize("INSERT_API_KEY", "INSERT_API_SECRET_KEY", "https://api.coolsms.co.kr"); 36 | } 37 | 38 | /** 39 | * 메시지 조회 예제 40 | */ 41 | @GetMapping("/get-message-list") 42 | public MessageListResponse getMessageList() { 43 | // 검색 조건이 있는 경우에 MessagListRequest를 초기화 하여 getMessageList 함수에 파라미터로 넣어서 검색할 수 있습니다!. 44 | // 수신번호와 발신번호는 반드시 -,* 등의 특수문자를 제거한 01012345678 형식으로 입력해주셔야 합니다! 45 | MessageListRequest request = new MessageListRequest(); 46 | 47 | // 검색할 건 수, 값 미지정 시 20건 조회, 최대 500건 까지 설정 가능 48 | // request.setLimit(1); 49 | 50 | // 조회 후 다음 페이지로 넘어가려면 조회 당시 마지막의 messageId를 입력해주셔야 합니다! 51 | // request.setStartKey("메시지 ID"); 52 | 53 | // request.setTo("검색할 수신번호"); 54 | // request.setFrom("검색할 발신번호"); 55 | 56 | // 메시지 상태 검색, PENDING은 대기 건, SENDING은 발송 중,COMPLETE는 발송완료, FAILED는 발송에 실패한 모든 건입니다. 57 | /* 58 | request.setStatus(MessageStatusType.PENDING); 59 | request.setStatus(MessageStatusType.SENDING); 60 | request.setStatus(MessageStatusType.COMPLETE); 61 | request.setStatus(MessageStatusType.FAILED); 62 | */ 63 | 64 | // request.setMessageId("검색할 메시지 ID"); 65 | 66 | // 검색할 메시지 목록 67 | /* 68 | ArrayList messageIds = new ArrayList<>(); 69 | messageIds.add("검색할 메시지 ID"); 70 | request.setMessageIds(messageIds); 71 | */ 72 | 73 | // 조회 할 메시지 유형 검색, 유형에 대한 값은 아래 내용을 참고해주세요! 74 | // SMS: 단문 75 | // LMS: 장문 76 | // MMS: 사진문자 77 | // ATA: 알림톡 78 | // CTA: 친구톡 79 | // CTI: 이미지 친구톡 80 | // NSA: 네이버 스마트알림 81 | // RCS_SMS: RCS 단문 82 | // RCS_LMS: RCS 장문 83 | // RCS_MMS: RCS 사진문자 84 | // RCS_TPL: RCS 템플릿문자 85 | // request.setType("조회 할 메시지 유형"); 86 | 87 | MessageListResponse response = this.messageService.getMessageList(request); 88 | System.out.println(response); 89 | 90 | return response; 91 | } 92 | 93 | /** 94 | * 단일 메시지 발송 예제 95 | */ 96 | @PostMapping("/send-one") 97 | public SingleMessageSentResponse sendOne() { 98 | Message message = new Message(); 99 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 100 | message.setFrom("발신번호 입력"); 101 | message.setTo("수신번호 입력"); 102 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다."); 103 | 104 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 105 | System.out.println(response); 106 | 107 | return response; 108 | } 109 | 110 | /** 111 | * MMS 발송 예제 112 | * 단일 발송, 여러 건 발송 상관없이 이용 가능 113 | */ 114 | @PostMapping("/send-mms") 115 | public SingleMessageSentResponse sendMmsByResourcePath() throws IOException { 116 | ClassPathResource resource = new ClassPathResource("static/sample.jpg"); 117 | File file = resource.getFile(); 118 | String imageId = this.messageService.uploadFile(file, StorageType.MMS, null); 119 | 120 | Message message = new Message(); 121 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 122 | message.setFrom("발신번호 입력"); 123 | message.setTo("수신번호 입력"); 124 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다."); 125 | message.setImageId(imageId); 126 | 127 | // 여러 건 메시지 발송일 경우 send many 예제와 동일하게 구성하여 발송할 수 있습니다. 128 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 129 | System.out.println(response); 130 | 131 | return response; 132 | } 133 | 134 | /** 135 | * 여러 메시지 발송 예제 136 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 137 | */ 138 | @PostMapping("/send-many") 139 | public MultipleDetailMessageSentResponse sendMany() { 140 | ArrayList messageList = new ArrayList<>(); 141 | 142 | for (int i = 0; i < 3; i++) { 143 | Message message = new Message(); 144 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 145 | message.setFrom("발신번호 입력"); 146 | message.setTo("수신번호 입력"); 147 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 148 | 149 | // 메시지 건건 마다 사용자가 원하는 커스텀 값(특정 주문/결제 건의 ID를 넣는등)을 map 형태로 기입하여 전송 후 확인해볼 수 있습니다! 150 | /*HashMap map = new HashMap<>(); 151 | 152 | map.put("키 입력", "값 입력"); 153 | message.setCustomFields(map); 154 | 155 | messageList.add(message);*/ 156 | } 157 | 158 | try { 159 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 160 | // 세 번째 파라미터인 showMessageList 값을 true로 설정할 경우 MultipleDetailMessageSentResponse에서 MessageList를 리턴하게 됩니다! 161 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, false, true); 162 | 163 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 164 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, true); 165 | 166 | System.out.println(response); 167 | 168 | return response; 169 | } catch (NurigoMessageNotReceivedException exception) { 170 | System.out.println(exception.getFailedMessageList()); 171 | System.out.println(exception.getMessage()); 172 | } catch (Exception exception) { 173 | System.out.println(exception.getMessage()); 174 | } 175 | return null; 176 | } 177 | 178 | 179 | @PostMapping("/send-scheduled-messages") 180 | public MultipleDetailMessageSentResponse sendScheduledMessages() { 181 | ArrayList messageList = new ArrayList<>(); 182 | 183 | for (int i = 0; i < 3; i++) { 184 | Message message = new Message(); 185 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 186 | message.setFrom("발신번호 입력"); 187 | message.setTo("수신번호 입력"); 188 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 189 | 190 | messageList.add(message); 191 | } 192 | 193 | try { 194 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 195 | LocalDateTime localDateTime = LocalDateTime.parse("2022-11-26 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 196 | ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime); 197 | Instant instant = localDateTime.toInstant(zoneOffset); 198 | 199 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 200 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant); 201 | 202 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 203 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant, true); 204 | 205 | System.out.println(response); 206 | 207 | return response; 208 | } catch (NurigoMessageNotReceivedException exception) { 209 | System.out.println(exception.getFailedMessageList()); 210 | System.out.println(exception.getMessage()); 211 | } catch (Exception exception) { 212 | System.out.println(exception.getMessage()); 213 | } 214 | return null; 215 | } 216 | 217 | /** 218 | * 잔액 조회 예제 219 | */ 220 | @GetMapping("/get-balance") 221 | public Balance getBalance() { 222 | Balance balance = this.messageService.getBalance(); 223 | System.out.println(balance); 224 | 225 | return balance; 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/java/net/nurigo/gradlespringdemo/GradleSpringDemoApplication.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.gradlespringdemo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class GradleSpringDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(GradleSpringDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/java/net/nurigo/gradlespringdemo/KakaoExampleController.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.gradlespringdemo; 2 | 3 | import net.nurigo.sdk.NurigoApp; 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; 5 | import net.nurigo.sdk.message.model.*; 6 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest; 7 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse; 8 | import net.nurigo.sdk.message.response.SingleMessageSentResponse; 9 | import net.nurigo.sdk.message.service.DefaultMessageService; 10 | import org.springframework.core.io.ClassPathResource; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.time.Instant; 18 | import java.time.LocalDateTime; 19 | import java.time.ZoneId; 20 | import java.time.ZoneOffset; 21 | import java.time.format.DateTimeFormatter; 22 | import java.util.ArrayList; 23 | 24 | /** 25 | * 모든 발송 API에는 발신, 수신번호 입력 항목에 +82 또는 +8210, 010-0000-0000 같은 형태로 기입할 수 없습니다. 26 | * 수/발신 가능한 예시) 01000000000, 020000000 등 27 | */ 28 | @RestController 29 | @RequestMapping("/kakao") 30 | public class KakaoExampleController { 31 | 32 | private final DefaultMessageService messageService; 33 | 34 | /** 35 | * 발급받은 API KEY와 API Secret Key를 사용해주세요. 36 | */ 37 | public KakaoExampleController() { 38 | // 반드시 계정 내 등록된 유효한 API 키, API Secret Key를 입력해주셔야 합니다! 39 | this.messageService = NurigoApp.INSTANCE.initialize("INSERT_API_KEY", "INSERT_API_SECRET_KEY", "https://api.coolsms.co.kr"); 40 | } 41 | 42 | /** 43 | * 알림톡 한건 발송 예제 44 | */ 45 | @PostMapping("/send-one-ata") 46 | public SingleMessageSentResponse sendOneAta() { 47 | KakaoOption kakaoOption = new KakaoOption(); 48 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 49 | // kakaoOption.setDisableSms(true); 50 | 51 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 52 | kakaoOption.setPfId(""); 53 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 54 | kakaoOption.setTemplateId(""); 55 | 56 | // 알림톡 템플릿 내에 #{변수} 형태가 존재할 경우 variables를 설정해주세요. 57 | /* 58 | HashMap variables = new HashMap<>(); 59 | variables.put("#{변수명1}", "테스트"); 60 | variables.put("#{변수명2}", "치환문구 테스트2"); 61 | kakaoOption.setVariables(variables); 62 | */ 63 | 64 | Message message = new Message(); 65 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 66 | message.setFrom("발신번호 입력"); 67 | message.setTo("수신번호 입력"); 68 | message.setKakaoOptions(kakaoOption); 69 | 70 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 71 | System.out.println(response); 72 | 73 | return response; 74 | } 75 | 76 | /** 77 | * 여러 메시지 발송 예제 78 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 79 | */ 80 | @PostMapping("/send-many-ata") 81 | public MultipleDetailMessageSentResponse sendMany() { 82 | ArrayList messageList = new ArrayList<>(); 83 | 84 | for (int i = 0; i < 3; i++) { 85 | KakaoOption kakaoOption = new KakaoOption(); 86 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 87 | kakaoOption.setPfId(""); 88 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 89 | kakaoOption.setTemplateId(""); 90 | 91 | Message message = new Message(); 92 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 93 | message.setFrom("발신번호 입력"); 94 | message.setTo("수신번호 입력"); 95 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 96 | message.setKakaoOptions(kakaoOption); 97 | 98 | // 기본적으로 실패 시 같은 내용으로 문자 전송을 요청하나, 99 | // 같은 내용이 아닌 다른 내용으로 대체발송을 원한다면 replacements 값을 설정해줍니다. 100 | /* 101 | Message replacementMessage = new Message(); 102 | replacementMessage.setFrom("발신번호 입력"); 103 | replacementMessage.setTo("수신번호 입력"); 104 | replacementMessage.setText("실패 시 대체 발송 될 메시지입니다."); 105 | ArrayList replacmentMessages = new ArrayList<>(); 106 | replacmentMessages.add(replacementMessage); 107 | message.setReplacements(replacmentMessages); 108 | */ 109 | 110 | messageList.add(message); 111 | } 112 | 113 | try { 114 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 115 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList); 116 | 117 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 118 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, true); 119 | 120 | System.out.println(response); 121 | 122 | return response; 123 | } catch (NurigoMessageNotReceivedException exception) { 124 | System.out.println(exception.getFailedMessageList()); 125 | System.out.println(exception.getMessage()); 126 | } catch (Exception exception) { 127 | System.out.println(exception.getMessage()); 128 | } 129 | return null; 130 | } 131 | 132 | @PostMapping("/send-ata-scheduled-messages") 133 | public MultipleDetailMessageSentResponse sendScheduledMessages() { 134 | ArrayList messageList = new ArrayList<>(); 135 | 136 | for (int i = 0; i < 3; i++) { 137 | KakaoOption kakaoOption = new KakaoOption(); 138 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 139 | kakaoOption.setPfId(""); 140 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 141 | kakaoOption.setTemplateId(""); 142 | 143 | Message message = new Message(); 144 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 145 | message.setFrom("발신번호 입력"); 146 | message.setTo("수신번호 입력"); 147 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 148 | message.setKakaoOptions(kakaoOption); 149 | 150 | messageList.add(message); 151 | } 152 | 153 | try { 154 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 155 | LocalDateTime localDateTime = LocalDateTime.parse("2022-05-27 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 156 | ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime); 157 | Instant instant = localDateTime.toInstant(zoneOffset); 158 | 159 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 160 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant); 161 | 162 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 163 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant, true); 164 | 165 | System.out.println(response); 166 | 167 | return response; 168 | } catch (NurigoMessageNotReceivedException exception) { 169 | System.out.println(exception.getFailedMessageList()); 170 | System.out.println(exception.getMessage()); 171 | } catch (Exception exception) { 172 | System.out.println(exception.getMessage()); 173 | } 174 | return null; 175 | } 176 | 177 | /** 178 | * 친구톡 한건 발송 예제, send 호환, 다량 발송의 경우 위 send-many-ata 코드를 참조해보세요! 179 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 180 | */ 181 | @PostMapping("/send-cta") 182 | public SingleMessageSentResponse sendOneCta() { 183 | KakaoOption kakaoOption = new KakaoOption(); 184 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 185 | // kakaoOption.setDisableSms(true); 186 | 187 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 188 | kakaoOption.setPfId(""); 189 | kakaoOption.setVariables(null); 190 | 191 | // 친구톡에 버튼을 넣으실 경우에만 추가해주세요. 192 | ArrayList kakaoButtons = new ArrayList<>(); 193 | // 웹링크 버튼 194 | KakaoButton kakaoWebLinkButton = new KakaoButton( 195 | "테스트 버튼1", KakaoButtonType.WL, 196 | "https://example.com", "https://example.com", 197 | null, null 198 | ); 199 | 200 | // 앱링크 버튼 201 | KakaoButton kakaoAppLinkButton = new KakaoButton( 202 | "테스트 버튼2", KakaoButtonType.AL, 203 | null, null, 204 | "exampleapp://test", "exampleapp://test" 205 | ); 206 | 207 | // 봇 키워드 버튼, 버튼을 클릭하면 버튼 이름으로 수신자가 발신자에게 채팅을 보냅니다. 208 | KakaoButton kakaoBotKeywordButton = new KakaoButton( 209 | "테스트 버튼3", KakaoButtonType.BK, null, null, null, null 210 | ); 211 | 212 | // 메시지 전달 버튼, 버튼을 클릭하면 버튼 이름과 친구톡 메시지 내용을 포함하여 수신자가 발신자에게 채팅을 보냅니다. 213 | KakaoButton kakaoMessageDeliveringButton = new KakaoButton( 214 | "테스트 버튼4", KakaoButtonType.MD, null, null, null, null 215 | ); 216 | 217 | /* 218 | * 상담톡 전환 버튼, 상담톡 서비스를 이용하고 있을 경우 상담톡으로 전환. 상담톡 서비스 미이용시 해당 버튼 추가될 경우 발송 오류 처리됨. 219 | * @see 상담톡 딜러사 확인 220 | */ 221 | /*KakaoButton kakaoBotCustomerButton = new KakaoButton( 222 | "테스트 버튼6", KakaoButtonType.BC, null, null, null, null 223 | );*/ 224 | 225 | // 봇전환 버튼, 해당 비즈니스 채널에 카카오 챗봇이 없는 경우 동작안함. 226 | // KakaoButton kakaoBotTransferButton = new KakaoButton("테스트 버튼7", KakaoButtonType.BT, null, null, null, null); 227 | 228 | kakaoButtons.add(kakaoWebLinkButton); 229 | kakaoButtons.add(kakaoAppLinkButton); 230 | kakaoButtons.add(kakaoBotKeywordButton); 231 | kakaoButtons.add(kakaoMessageDeliveringButton); 232 | 233 | kakaoOption.setButtons(kakaoButtons); 234 | 235 | Message message = new Message(); 236 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 237 | message.setFrom("발신번호 입력"); 238 | message.setTo("수신번호 입력"); 239 | message.setText("친구톡 테스트 메시지"); 240 | message.setKakaoOptions(kakaoOption); 241 | 242 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 243 | System.out.println(response); 244 | 245 | return response; 246 | } 247 | 248 | /** 249 | * 친구톡 이미지 단건 발송, send 호환, 다량 발송의 경우 위 send-many-ata 코드를 참조해보세요! 250 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 251 | */ 252 | @PostMapping("/send-cti") 253 | public SingleMessageSentResponse sendOneCti() throws IOException { 254 | ClassPathResource resource = new ClassPathResource("static/cti.jpg"); 255 | File file = resource.getFile(); 256 | // 이미지 크기는 가로 500px 세로 250px 이상이어야 합니다, 링크도 필수로 기입해주세요. 257 | String imageId = this.messageService.uploadFile(file, StorageType.KAKAO, "https://example.com"); 258 | 259 | KakaoOption kakaoOption = new KakaoOption(); 260 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 261 | // kakaoOption.setDisableSms(true); 262 | 263 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 264 | kakaoOption.setPfId(""); 265 | kakaoOption.setImageId(imageId); 266 | kakaoOption.setVariables(null); 267 | 268 | Message message = new Message(); 269 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 270 | message.setFrom("발신번호 입력"); 271 | message.setTo("수신번호 입력"); 272 | message.setText("테스트"); 273 | message.setKakaoOptions(kakaoOption); 274 | 275 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 276 | System.out.println(response); 277 | 278 | return response; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/resources/static/cti.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/gradle-spring-demo/src/main/resources/static/cti.jpg -------------------------------------------------------------------------------- /gradle-spring-demo/src/main/resources/static/sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/gradle-spring-demo/src/main/resources/static/sample.jpg -------------------------------------------------------------------------------- /gradle-spring-demo/src/test/java/net/nurigo/gradlespringdemo/GradleSpringDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.gradlespringdemo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class GradleSpringDemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /kotlin-spring-demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | .gradle 3 | build/ 4 | !gradle/wrapper/gradle-wrapper.jar 5 | !**/src/main/**/build/ 6 | !**/src/test/**/build/ 7 | 8 | ### STS ### 9 | .apt_generated 10 | .classpath 11 | .factorypath 12 | .project 13 | .settings 14 | .springBeans 15 | .sts4-cache 16 | bin/ 17 | !**/src/main/**/bin/ 18 | !**/src/test/**/bin/ 19 | 20 | ### IntelliJ IDEA ### 21 | .idea 22 | *.iws 23 | *.iml 24 | *.ipr 25 | out/ 26 | !**/src/main/**/out/ 27 | !**/src/test/**/out/ 28 | 29 | ### NetBeans ### 30 | /nbproject/private/ 31 | /nbbuild/ 32 | /dist/ 33 | /nbdist/ 34 | /.nb-gradle/ 35 | 36 | ### VS Code ### 37 | .vscode/ 38 | -------------------------------------------------------------------------------- /kotlin-spring-demo/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.jetbrains.kotlin.gradle.tasks.KotlinCompile 2 | 3 | plugins { 4 | id("org.springframework.boot") version "2.7.5" 5 | id("io.spring.dependency-management") version "1.0.11.RELEASE" 6 | kotlin("jvm") version "1.6.21" 7 | kotlin("plugin.spring") version "1.6.21" 8 | } 9 | 10 | group = "net.nurigo" 11 | version = "0.0.1-SNAPSHOT" 12 | java.sourceCompatibility = JavaVersion.VERSION_1_8 13 | 14 | repositories { 15 | mavenCentral() 16 | } 17 | 18 | dependencies { 19 | implementation("org.springframework.boot:spring-boot-starter-web") 20 | implementation("com.fasterxml.jackson.module:jackson-module-kotlin") 21 | implementation("org.jetbrains.kotlin:kotlin-reflect") 22 | implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") 23 | testImplementation("org.springframework.boot:spring-boot-starter-test") 24 | 25 | implementation("net.nurigo:sdk:4.3.2") 26 | } 27 | 28 | tasks.withType { 29 | kotlinOptions { 30 | freeCompilerArgs = listOf("-Xjsr305=strict") 31 | jvmTarget = "1.8" 32 | } 33 | } 34 | 35 | tasks.withType { 36 | useJUnitPlatform() 37 | } 38 | -------------------------------------------------------------------------------- /kotlin-spring-demo/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/kotlin-spring-demo/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kotlin-spring-demo/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /kotlin-spring-demo/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /kotlin-spring-demo/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /kotlin-spring-demo/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "kotlin-spring-demo" 2 | -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/kotlin/net/nurigo/kotlinspringdemo/ExampleController.kt: -------------------------------------------------------------------------------- 1 | package net.nurigo.kotlinspringdemo 2 | 3 | import net.nurigo.sdk.NurigoApp.initialize 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException 5 | import net.nurigo.sdk.message.model.Balance 6 | import net.nurigo.sdk.message.model.Message 7 | import net.nurigo.sdk.message.model.StorageType 8 | import net.nurigo.sdk.message.request.MessageListRequest 9 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest 10 | import net.nurigo.sdk.message.response.MessageListResponse 11 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse 12 | import net.nurigo.sdk.message.response.SingleMessageSentResponse 13 | import net.nurigo.sdk.message.service.DefaultMessageService 14 | import org.springframework.core.io.ClassPathResource 15 | import org.springframework.web.bind.annotation.GetMapping 16 | import org.springframework.web.bind.annotation.PostMapping 17 | import org.springframework.web.bind.annotation.RestController 18 | import java.io.IOException 19 | import java.time.Instant 20 | import java.time.LocalDateTime 21 | import java.time.ZoneId 22 | import java.time.ZoneOffset 23 | import java.time.format.DateTimeFormatter 24 | 25 | 26 | @RestController 27 | class ExampleController { 28 | // 반드시 계정 내 등록된 유효한 API 키, API Secret Key를 입력해주셔야 합니다! 29 | val messageService: DefaultMessageService = 30 | initialize("INSERT_API_KEY", "INSERT_API_SECRET_KEY", "https://api.coolsms.co.kr") 31 | 32 | /** 33 | * 메시지 조회 예제 34 | */ 35 | @GetMapping("/get-message-list") 36 | fun getMessageList(): MessageListResponse? { 37 | // 검색 조건이 있는 경우에 MessagListRequest를 초기화 하여 getMessageList 함수에 파라미터로 넣어서 검색할 수 있습니다!. 38 | // 수신번호와 발신번호는 반드시 -,* 등의 특수문자를 제거한 01012345678 형식으로 입력해주셔야 합니다! 39 | 40 | // 검색 조건이 있는 경우에 MessagListRequest를 초기화 하여 getMessageList 함수에 파라미터로 넣어서 검색할 수 있습니다!. 41 | // 수신번호와 발신번호는 반드시 -,* 등의 특수문자를 제거한 01012345678 형식으로 입력해주셔야 합니다! 42 | val request = MessageListRequest() 43 | 44 | // 검색할 건 수, 값 미지정 시 20건 조회, 최대 500건 까지 설정 가능 45 | // request.limit = 1 46 | 47 | // 조회 후 다음 페이지로 넘어가려면 조회 당시 마지막의 messageId를 입력해주셔야 합니다! 48 | // request.startKey = "메시지 ID" 49 | 50 | // request.to = "검색할 수신번호" 51 | // request.from = "검색할 발신번호" 52 | 53 | // 메시지 상태 검색, PENDING은 대기 건, SENDING은 발송 중,COMPLETE는 발송완료, FAILED는 발송에 실패한 모든 건입니다. 54 | /* 55 | request.status = MessageStatusType.PENDING 56 | request.status = MessageStatusType.SENDING 57 | request.status = MessageStatusType.COMPLETE 58 | request.status = MessageStatusType.FAILED 59 | */ 60 | 61 | // request.messageId = "검색할 메시지 ID" 62 | 63 | // 검색할 메시지 목록 64 | // val messageIds = mutableListOf() 65 | // messageIds.add("검색할 메시지 ID"); 66 | // request.messageIds = messageIds; 67 | 68 | // 조회 할 메시지 유형 검색, 유형에 대한 값은 아래 내용을 참고해주세요! 69 | // SMS: 단문 70 | // LMS: 장문 71 | // MMS: 사진문자 72 | // ATA: 알림톡 73 | // CTA: 친구톡 74 | // CTI: 이미지 친구톡 75 | // NSA: 네이버 스마트알림 76 | // RCS_SMS: RCS 단문 77 | // RCS_LMS: RCS 장문 78 | // RCS_MMS: RCS 사진문자 79 | // RCS_TPL: RCS 템플릿문자 80 | // request.type = "조회 할 메시지 유형" 81 | 82 | val response = messageService.getMessageList(request) 83 | println(response) 84 | 85 | return response 86 | } 87 | 88 | /** 89 | * 단일 메시지 발송 예제 90 | */ 91 | @PostMapping("/send-one") 92 | fun sendOne(): SingleMessageSentResponse? { 93 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 94 | val message = Message( 95 | from = "발신번호 입력", 96 | to = "수신번호 입력", 97 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." 98 | // country = "국가번호" 99 | ) 100 | val response = messageService.sendOne(SingleMessageSendingRequest(message)) 101 | println(response) 102 | return response 103 | } 104 | 105 | /** 106 | * MMS 발송 예제 107 | * 단일 발송, 여러 건 발송 상관없이 이용 가능 108 | */ 109 | @PostMapping("/send-mms") 110 | @Throws(IOException::class) 111 | fun sendMmsByResourcePath(): SingleMessageSentResponse? { 112 | val resource = ClassPathResource("static/sample.jpg") 113 | val file = resource.file 114 | val imageId = messageService.uploadFile(file, StorageType.MMS, null) 115 | 116 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 117 | val message = Message( 118 | from = "발신번호 입력", 119 | to = "수신번호 입력", 120 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다.", 121 | imageId = imageId 122 | // country = "국가번호" 123 | ) 124 | 125 | // 여러 건 메시지 발송일 경우 send many 예제와 동일하게 구성하여 발송할 수 있습니다. 126 | val response = messageService.sendOne(SingleMessageSendingRequest(message)) 127 | println(response) 128 | return response 129 | } 130 | 131 | /** 132 | * 여러 메시지 발송 예제 133 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 134 | */ 135 | @PostMapping("/send-many") 136 | fun sendMany(): MultipleDetailMessageSentResponse? { 137 | val messageList = ArrayList() 138 | for (i in 0..2) { 139 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 140 | val message = Message( 141 | from = "발신번호 입력", 142 | to = "수신번호 입력", 143 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다.$i" 144 | // country = "국가번호" 145 | ) 146 | messageList.add(message) 147 | } 148 | try { 149 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 150 | val response = messageService.send(messageList) 151 | 152 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 153 | // val response = this.messageService.send(messageList, true); 154 | println(response) 155 | return response 156 | } catch (exception: NurigoMessageNotReceivedException) { 157 | println(exception.failedMessageList) 158 | println(exception.message) 159 | } catch (exception: Exception) { 160 | println(exception.message) 161 | } 162 | return null 163 | } 164 | 165 | /** 166 | * 예약 발송 예제(단건 및 여러 건 발송을 지원합니다) 167 | */ 168 | @PostMapping("/send-scheduled-messages") 169 | fun sendScheduledMessages(): MultipleDetailMessageSentResponse? { 170 | val messageList = ArrayList() 171 | for (i in 0..2) { 172 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 173 | val message = Message( 174 | from = "발신번호 입력", 175 | to = "수신번호 입력", 176 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다.$i" 177 | // country = "국가번호" 178 | ) 179 | messageList.add(message) 180 | } 181 | try { 182 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 183 | val localDateTime: LocalDateTime = 184 | LocalDateTime.parse("2022-11-26 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) 185 | val zoneOffset: ZoneOffset = ZoneId.systemDefault().rules.getOffset(localDateTime) 186 | val instant: Instant = localDateTime.toInstant(zoneOffset) 187 | 188 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 189 | val response: MultipleDetailMessageSentResponse = messageService.send(messageList, instant) 190 | 191 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 192 | // val response = this.messageService.send(messageList, instant, true); 193 | println(response) 194 | return response 195 | } catch (exception: NurigoMessageNotReceivedException) { 196 | println(exception.failedMessageList) 197 | println(exception.message) 198 | } catch (exception: Exception) { 199 | println(exception.message) 200 | } 201 | return null 202 | } 203 | 204 | /** 205 | * 잔액 조회 예제 206 | */ 207 | @GetMapping("/get-balance") 208 | fun getBalance(): Balance { 209 | val balance = messageService.getBalance() 210 | println(balance) 211 | return balance 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/kotlin/net/nurigo/kotlinspringdemo/KakaoExampleController.kt: -------------------------------------------------------------------------------- 1 | package net.nurigo.kotlinspringdemo 2 | 3 | import net.nurigo.sdk.NurigoApp.initialize 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException 5 | import net.nurigo.sdk.message.model.* 6 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest 7 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse 8 | import net.nurigo.sdk.message.response.SingleMessageSentResponse 9 | import net.nurigo.sdk.message.service.DefaultMessageService 10 | import org.springframework.core.io.ClassPathResource 11 | import org.springframework.web.bind.annotation.PostMapping 12 | import org.springframework.web.bind.annotation.RequestMapping 13 | import org.springframework.web.bind.annotation.RestController 14 | import java.io.IOException 15 | import java.time.Instant 16 | import java.time.LocalDateTime 17 | import java.time.ZoneId 18 | import java.time.ZoneOffset 19 | import java.time.format.DateTimeFormatter 20 | 21 | 22 | /** 23 | * 모든 발송 API에는 발신, 수신번호 입력 항목에 +82 또는 +8210, 010-0000-0000 같은 형태로 기입할 수 없습니다. 24 | * 수/발신 가능한 예시) 01000000000, 020000000 등 25 | */ 26 | @RestController 27 | @RequestMapping("/kakao") 28 | class KakaoExampleController { 29 | /** 30 | * 발급받은 API KEY와 API Secret Key를 사용해주세요. 31 | */ 32 | val messageService: DefaultMessageService = 33 | initialize("INSERT API KEY", "INSERT API SECRET KEY", "https://api.coolsms.co.kr") 34 | 35 | /** 36 | * 알림톡 한건 발송 예제 37 | */ 38 | @PostMapping("/send-one-ata") 39 | fun sendOneAta(): SingleMessageSentResponse? { 40 | // 알림톡 템플릿 내에 #{변수} 형태가 존재할 경우 variables를 설정해주세요. 41 | /*val variables = mutableMapOf() 42 | variables["#{변수명1}"] = "테스트"; 43 | variables["#{변수명2}"] = "치환문구 테스트2";*/ 44 | 45 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 46 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 47 | val kakaoOption = KakaoOption( 48 | pfId = "pfId 입력", 49 | templateId = "templateId 입력", 50 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 51 | // disableSms = true, 52 | 53 | // 알림톡 템플릿 내에 #{변수} 형태가 존재할 경우 variables를 설정해주세요. 54 | // variables = variables, 55 | ) 56 | 57 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 58 | val message = Message( 59 | from = "발신번호 입력", 60 | to = "수신번호 입력", 61 | kakaoOptions = kakaoOption 62 | ) 63 | val response = messageService.sendOne(SingleMessageSendingRequest(message)) 64 | println(response) 65 | return response 66 | } 67 | 68 | /** 69 | * 여러 메시지 발송 예제 70 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 71 | */ 72 | @PostMapping("/send-many-ata") 73 | fun sendMany(): MultipleDetailMessageSentResponse? { 74 | val messageList = ArrayList() 75 | for (i in 0..2) { 76 | val kakaoOption = KakaoOption( 77 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 78 | pfId = "", 79 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 80 | templateId = "" 81 | ) 82 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 83 | val message = Message( 84 | from = "발신번호 입력", 85 | to = "수신번호 입력", 86 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다.$i", 87 | kakaoOptions = kakaoOption 88 | ) 89 | 90 | // 기본적으로 실패 시 같은 내용으로 문자 전송을 요청하나, 91 | // 같은 내용이 아닌 다른 내용으로 대체발송을 원한다면 replacements값을 설정해줍니다. 92 | /* 93 | val replacementMessage = Message( 94 | from = "발신번호 입력", 95 | to = "수신번호 입력", 96 | text = "실패 시 대체 발송 될 메시지입니다." 97 | ) 98 | val replacmentMessages = ArrayList() 99 | replacmentMessages.add(replacementMessage) 100 | message.replacements = replacmentMessages 101 | */ 102 | 103 | messageList.add(message) 104 | } 105 | try { 106 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 107 | val response = messageService.send(messageList) 108 | 109 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 110 | // val response = this.messageService.send(messageList, true); 111 | println(response) 112 | return response 113 | } catch (exception: NurigoMessageNotReceivedException) { 114 | println(exception.failedMessageList) 115 | println(exception.message) 116 | } catch (exception: Exception) { 117 | println(exception.message) 118 | } 119 | return null 120 | } 121 | 122 | /** 123 | * 예약 발송 예제(단건 및 여러 건 발송을 지원합니다) 124 | */ 125 | @PostMapping("/send-ata-scheduled-messages") 126 | fun sendScheduledMessages(): MultipleDetailMessageSentResponse? { 127 | val messageList = ArrayList() 128 | for (i in 0..2) { 129 | val kakaoOption = KakaoOption( 130 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 131 | pfId = "", 132 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 133 | templateId = "" 134 | ) 135 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 136 | val message = Message( 137 | from = "발신번호 입력", 138 | to = "수신번호 입력", 139 | text = "한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다.$i", 140 | kakaoOptions = kakaoOption 141 | ) 142 | messageList.add(message) 143 | } 144 | try { 145 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 146 | val localDateTime: LocalDateTime = 147 | LocalDateTime.parse("2022-05-27 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) 148 | val zoneOffset: ZoneOffset = ZoneId.systemDefault().rules.getOffset(localDateTime) 149 | val instant: Instant = localDateTime.toInstant(zoneOffset) 150 | 151 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 152 | val response: MultipleDetailMessageSentResponse = messageService.send(messageList, instant) 153 | 154 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 155 | // val response = this.messageService.send(messageList, instant, true); 156 | println(response) 157 | return response 158 | } catch (exception: NurigoMessageNotReceivedException) { 159 | println(exception.failedMessageList) 160 | println(exception.message) 161 | } catch (exception: Exception) { 162 | println(exception.message) 163 | } 164 | return null 165 | } 166 | 167 | /** 168 | * 친구톡 한건 발송 예제, send many 호환 169 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 170 | */ 171 | @PostMapping("/send-cta") 172 | fun sendOneCta(): SingleMessageSentResponse? { 173 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 174 | val kakaoOption = KakaoOption( 175 | pfId = "pfId 입력", 176 | variables = null, 177 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 178 | // disableSms = true, 179 | ) 180 | 181 | // 친구톡에 버튼을 넣으실 경우에만 추가해주세요. 182 | val kakaoButtons = ArrayList() 183 | // 웹링크 버튼 184 | val kakaoWebLinkButton = KakaoButton( 185 | "테스트 버튼1", KakaoButtonType.WL, 186 | "https://example.com", "https://example.com", 187 | null, null 188 | ) 189 | 190 | // 앱링크 버튼 191 | val kakaoAppLinkButton = KakaoButton( 192 | "테스트 버튼2", KakaoButtonType.AL, 193 | null, null, 194 | "exampleapp://test", "exampleapp://test" 195 | ) 196 | 197 | // 봇 키워드 버튼, 버튼을 클릭하면 버튼 이름으로 수신자가 발신자에게 채팅을 보냅니다. 198 | val kakaoBotKeywordButton = KakaoButton( 199 | "테스트 버튼3", KakaoButtonType.BK, null, null, null, null 200 | ) 201 | 202 | // 메시지 전달 버튼, 버튼을 클릭하면 버튼 이름과 친구톡 메시지 내용을 포함하여 수신자가 발신자에게 채팅을 보냅니다. 203 | val kakaoMessageDeliveringButton = KakaoButton( 204 | "테스트 버튼4", KakaoButtonType.MD, null, null, null, null 205 | ) 206 | 207 | /* 208 | * 상담톡 전환 버튼, 상담톡 서비스를 이용하고 있을 경우 상담톡으로 전환. 상담톡 서비스 미이용시 해당 버튼 추가될 경우 발송 오류 처리됨. 209 | * @see 상담톡 딜러사 확인 210 | */ 211 | /*KakaoButton kakaoBotCustomerButton = new KakaoButton( 212 | "테스트 버튼6", KakaoButtonType.BC, null, null, null, null 213 | );*/ 214 | 215 | // 봇전환 버튼, 해당 비즈니스 채널에 카카오 챗봇이 없는 경우 동작안함. 216 | // KakaoButton kakaoBotTransferButton = new KakaoButton("테스트 버튼7", KakaoButtonType.BT, null, null, null, null); 217 | kakaoButtons.add(kakaoWebLinkButton) 218 | kakaoButtons.add(kakaoAppLinkButton) 219 | kakaoButtons.add(kakaoBotKeywordButton) 220 | kakaoButtons.add(kakaoMessageDeliveringButton) 221 | kakaoOption.buttons = kakaoButtons 222 | 223 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 224 | val message = Message( 225 | from = "발신번호 입력", 226 | to = "수신번호 입력", 227 | text = "친구톡 테스트 메시지", 228 | kakaoOptions = kakaoOption 229 | ) 230 | val response = messageService.sendOne(SingleMessageSendingRequest(message)) 231 | println(response) 232 | return response 233 | } 234 | 235 | /** 236 | * 친구톡 이미지 단건 발송, send many 호환 237 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 238 | */ 239 | @PostMapping("/send-cti") 240 | @Throws(IOException::class) 241 | fun sendOneCti(): SingleMessageSentResponse? { 242 | val resource = ClassPathResource("static/cti.jpg") 243 | val file = resource.file 244 | // 이미지 크기는 가로 500px 세로 250px 이상이어야 합니다, 링크도 필수로 기입해주세요. 245 | val imageId = messageService.uploadFile(file, StorageType.KAKAO, "https://example.com") 246 | 247 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 248 | val kakaoOption = KakaoOption( 249 | pfId = "pfId 입력", 250 | imageId = imageId, 251 | variables = null, 252 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 253 | // disableSms = true, 254 | ) 255 | 256 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 257 | val message = Message( 258 | from = "발신번호 입력", 259 | to = "수신번호 입력", 260 | text = "친구톡 테스트 메시지", 261 | kakaoOptions = kakaoOption 262 | ) 263 | val response = messageService.sendOne(SingleMessageSendingRequest(message)) 264 | println(response) 265 | return response 266 | } 267 | } -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/kotlin/net/nurigo/kotlinspringdemo/KotlinSpringDemoApplication.kt: -------------------------------------------------------------------------------- 1 | package net.nurigo.kotlinspringdemo 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication 4 | import org.springframework.boot.runApplication 5 | 6 | @SpringBootApplication 7 | class KotlinSpringDemoApplication 8 | 9 | fun main(args: Array) { 10 | runApplication(*args) 11 | } 12 | -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/resources/static/cti.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/kotlin-spring-demo/src/main/resources/static/cti.jpg -------------------------------------------------------------------------------- /kotlin-spring-demo/src/main/resources/static/sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/kotlin-spring-demo/src/main/resources/static/sample.jpg -------------------------------------------------------------------------------- /kotlin-spring-demo/src/test/kotlin/net/nurigo/kotlinspringdemo/KotlinSpringDemoApplicationTests.kt: -------------------------------------------------------------------------------- 1 | package net.nurigo.kotlinspringdemo 2 | 3 | import org.junit.jupiter.api.Test 4 | import org.springframework.boot.test.context.SpringBootTest 5 | 6 | @SpringBootTest 7 | class KotlinSpringDemoApplicationTests { 8 | 9 | @Test 10 | fun contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /maven-spring-demo/.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /maven-spring-demo/.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/maven-spring-demo/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /maven-spring-demo/.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.4/apache-maven-3.8.4-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar 3 | -------------------------------------------------------------------------------- /maven-spring-demo/mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /maven-spring-demo/mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /maven-spring-demo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.5 9 | 10 | 11 | net.nurigo 12 | maven-spring-demo 13 | 0.0.1-SNAPSHOT 14 | maven-spring-demo 15 | maven-spring-demo 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-test 28 | test 29 | 30 | 31 | 32 | net.nurigo 33 | sdk 34 | 4.3.2 35 | 36 | 37 | 38 | 39 | 40 | 41 | org.springframework.boot 42 | spring-boot-maven-plugin 43 | 2.7.5 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /maven-spring-demo/src/main/java/net/nurigo/mavenspringdemo/ExampleController.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.mavenspringdemo; 2 | 3 | import net.nurigo.sdk.NurigoApp; 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; 5 | import net.nurigo.sdk.message.model.Balance; 6 | import net.nurigo.sdk.message.model.Message; 7 | import net.nurigo.sdk.message.model.StorageType; 8 | import net.nurigo.sdk.message.request.MessageListRequest; 9 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest; 10 | import net.nurigo.sdk.message.response.MessageListResponse; 11 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse; 12 | import net.nurigo.sdk.message.response.SingleMessageSentResponse; 13 | import net.nurigo.sdk.message.service.DefaultMessageService; 14 | import org.springframework.core.io.ClassPathResource; 15 | import org.springframework.web.bind.annotation.GetMapping; 16 | import org.springframework.web.bind.annotation.PostMapping; 17 | import org.springframework.web.bind.annotation.RestController; 18 | 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.time.Instant; 22 | import java.time.LocalDateTime; 23 | import java.time.ZoneId; 24 | import java.time.ZoneOffset; 25 | import java.time.format.DateTimeFormatter; 26 | import java.util.ArrayList; 27 | 28 | @RestController 29 | public class ExampleController { 30 | 31 | final DefaultMessageService messageService; 32 | 33 | public ExampleController() { 34 | // 반드시 계정 내 등록된 유효한 API 키, API Secret Key를 입력해주셔야 합니다! 35 | this.messageService = NurigoApp.INSTANCE.initialize("INSERT_API_KEY", "INSERT_API_SECRET_KEY", "https://api.coolsms.co.kr"); 36 | } 37 | 38 | /** 39 | * 메시지 조회 예제 40 | */ 41 | @GetMapping("/get-message-list") 42 | public MessageListResponse getMessageList() { 43 | // 검색 조건이 있는 경우에 MessagListRequest를 초기화 하여 getMessageList 함수에 파라미터로 넣어서 검색할 수 있습니다!. 44 | // 수신번호와 발신번호는 반드시 -,* 등의 특수문자를 제거한 01012345678 형식으로 입력해주셔야 합니다! 45 | MessageListRequest request = new MessageListRequest(); 46 | 47 | // 검색할 건 수, 값 미지정 시 20건 조회, 최대 500건 까지 설정 가능 48 | // request.setLimit(1); 49 | 50 | // 조회 후 다음 페이지로 넘어가려면 조회 당시 마지막의 messageId를 입력해주셔야 합니다! 51 | // request.setStartKey("메시지 ID"); 52 | 53 | // request.setTo("검색할 수신번호"); 54 | // request.setFrom("검색할 발신번호"); 55 | 56 | // 메시지 상태 검색, PENDING은 대기 건, SENDING은 발송 중,COMPLETE는 발송완료, FAILED는 발송에 실패한 모든 건입니다. 57 | /* 58 | request.setStatus(MessageStatusType.PENDING); 59 | request.setStatus(MessageStatusType.SENDING); 60 | request.setStatus(MessageStatusType.COMPLETE); 61 | request.setStatus(MessageStatusType.FAILED); 62 | */ 63 | 64 | // request.setMessageId("검색할 메시지 ID"); 65 | 66 | // 검색할 메시지 목록 67 | /* 68 | ArrayList messageIds = new ArrayList<>(); 69 | messageIds.add("검색할 메시지 ID"); 70 | request.setMessageIds(messageIds); 71 | */ 72 | 73 | // 조회 할 메시지 유형 검색, 유형에 대한 값은 아래 내용을 참고해주세요! 74 | // SMS: 단문 75 | // LMS: 장문 76 | // MMS: 사진문자 77 | // ATA: 알림톡 78 | // CTA: 친구톡 79 | // CTI: 이미지 친구톡 80 | // NSA: 네이버 스마트알림 81 | // RCS_SMS: RCS 단문 82 | // RCS_LMS: RCS 장문 83 | // RCS_MMS: RCS 사진문자 84 | // RCS_TPL: RCS 템플릿문자 85 | // request.setType("조회 할 메시지 유형"); 86 | 87 | return this.messageService.getMessageList(request); 88 | } 89 | 90 | /** 91 | * 단일 메시지 발송 예제 92 | */ 93 | @PostMapping("/send-one") 94 | public SingleMessageSentResponse sendOne() { 95 | Message message = new Message(); 96 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 97 | message.setFrom("발신번호 입력"); 98 | message.setTo("수신번호 입력"); 99 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다."); 100 | 101 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 102 | System.out.println(response); 103 | 104 | return response; 105 | } 106 | 107 | /** 108 | * MMS 발송 예제 109 | * 단일 발송, 여러 건 발송 상관없이 이용 가능 110 | */ 111 | @PostMapping("/send-mms") 112 | public SingleMessageSentResponse sendMmsByResourcePath() throws IOException { 113 | ClassPathResource resource = new ClassPathResource("static/sample.jpg"); 114 | File file = resource.getFile(); 115 | String imageId = this.messageService.uploadFile(file, StorageType.MMS, null); 116 | 117 | Message message = new Message(); 118 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 119 | message.setFrom("발신번호 입력"); 120 | message.setTo("수신번호 입력"); 121 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다."); 122 | message.setImageId(imageId); 123 | 124 | // 여러 건 메시지 발송일 경우 send many 예제와 동일하게 구성하여 발송할 수 있습니다. 125 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 126 | System.out.println(response); 127 | 128 | return response; 129 | } 130 | 131 | /** 132 | * 여러 메시지 발송 예제 133 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 134 | */ 135 | @PostMapping("/send-many") 136 | public MultipleDetailMessageSentResponse sendMany() { 137 | ArrayList messageList = new ArrayList<>(); 138 | 139 | for (int i = 0; i < 3; i++) { 140 | Message message = new Message(); 141 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 142 | message.setFrom("발신번호 입력"); 143 | message.setTo("수신번호 입력"); 144 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 145 | 146 | // 메시지 건건 마다 사용자가 원하는 커스텀 값(특정 주문/결제 건의 ID를 넣는등)을 map 형태로 기입하여 전송 후 확인해볼 수 있습니다! 147 | /*HashMap map = new HashMap<>(); 148 | 149 | map.put("키 입력", "값 입력"); 150 | message.setCustomFields(map); 151 | 152 | messageList.add(message);*/ 153 | } 154 | 155 | try { 156 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 157 | // 세 번째 파라미터인 showMessageList 값을 true로 설정할 경우 MultipleDetailMessageSentResponse에서 MessageList를 리턴하게 됩니다! 158 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, false, true); 159 | 160 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 161 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, true); 162 | 163 | System.out.println(response); 164 | 165 | return response; 166 | } catch (NurigoMessageNotReceivedException exception) { 167 | System.out.println(exception.getFailedMessageList()); 168 | System.out.println(exception.getMessage()); 169 | } catch (Exception exception) { 170 | System.out.println(exception.getMessage()); 171 | } 172 | return null; 173 | } 174 | 175 | 176 | @PostMapping("/send-scheduled-messages") 177 | public MultipleDetailMessageSentResponse sendScheduledMessages() { 178 | ArrayList messageList = new ArrayList<>(); 179 | 180 | for (int i = 0; i < 3; i++) { 181 | Message message = new Message(); 182 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 183 | message.setFrom("발신번호 입력"); 184 | message.setTo("수신번호 입력"); 185 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 186 | 187 | messageList.add(message); 188 | } 189 | 190 | try { 191 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 192 | LocalDateTime localDateTime = LocalDateTime.parse("2022-11-26 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 193 | ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime); 194 | Instant instant = localDateTime.toInstant(zoneOffset); 195 | 196 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 197 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant); 198 | 199 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 200 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant, true); 201 | 202 | System.out.println(response); 203 | 204 | return response; 205 | } catch (NurigoMessageNotReceivedException exception) { 206 | System.out.println(exception.getFailedMessageList()); 207 | System.out.println(exception.getMessage()); 208 | } catch (Exception exception) { 209 | System.out.println(exception.getMessage()); 210 | } 211 | return null; 212 | } 213 | 214 | /** 215 | * 잔액 조회 예제 216 | */ 217 | @GetMapping("/get-balance") 218 | public Balance getBalance() { 219 | Balance balance = this.messageService.getBalance(); 220 | System.out.println(balance); 221 | 222 | return balance; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /maven-spring-demo/src/main/java/net/nurigo/mavenspringdemo/KakaoExampleController.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.mavenspringdemo; 2 | 3 | import net.nurigo.sdk.NurigoApp; 4 | import net.nurigo.sdk.message.exception.NurigoMessageNotReceivedException; 5 | import net.nurigo.sdk.message.model.*; 6 | import net.nurigo.sdk.message.request.SingleMessageSendingRequest; 7 | import net.nurigo.sdk.message.response.MultipleDetailMessageSentResponse; 8 | import net.nurigo.sdk.message.response.SingleMessageSentResponse; 9 | import net.nurigo.sdk.message.service.DefaultMessageService; 10 | import org.springframework.core.io.ClassPathResource; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | import java.io.File; 16 | import java.io.IOException; 17 | import java.time.Instant; 18 | import java.time.LocalDateTime; 19 | import java.time.ZoneId; 20 | import java.time.ZoneOffset; 21 | import java.time.format.DateTimeFormatter; 22 | import java.util.ArrayList; 23 | 24 | /** 25 | * 모든 발송 API에는 발신, 수신번호 입력 항목에 +82 또는 +8210, 010-0000-0000 같은 형태로 기입할 수 없습니다. 26 | * 수/발신 가능한 예시) 01000000000, 020000000 등 27 | */ 28 | @RestController 29 | @RequestMapping("/kakao") 30 | public class KakaoExampleController { 31 | 32 | private final DefaultMessageService messageService; 33 | 34 | /** 35 | * 발급받은 API KEY와 API Secret Key를 사용해주세요. 36 | */ 37 | public KakaoExampleController() { 38 | // 반드시 계정 내 등록된 유효한 API 키, API Secret Key를 입력해주셔야 합니다! 39 | this.messageService = NurigoApp.INSTANCE.initialize("INSERT_API_KEY", "INSERT_API_SECRET_KEY", "https://api.coolsms.co.kr"); 40 | } 41 | 42 | /** 43 | * 알림톡 한건 발송 예제 44 | */ 45 | @PostMapping("/send-one-ata") 46 | public SingleMessageSentResponse sendOneAta() { 47 | KakaoOption kakaoOption = new KakaoOption(); 48 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 49 | // kakaoOption.setDisableSms(true); 50 | 51 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 52 | kakaoOption.setPfId(""); 53 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 54 | kakaoOption.setTemplateId(""); 55 | 56 | // 알림톡 템플릿 내에 #{변수} 형태가 존재할 경우 variables를 설정해주세요. 57 | /* 58 | HashMap variables = new HashMap<>(); 59 | variables.put("#{변수명1}", "테스트"); 60 | variables.put("#{변수명2}", "치환문구 테스트2"); 61 | kakaoOption.setVariables(variables); 62 | */ 63 | 64 | Message message = new Message(); 65 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 66 | message.setFrom("발신번호 입력"); 67 | message.setTo("수신번호 입력"); 68 | message.setKakaoOptions(kakaoOption); 69 | 70 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 71 | System.out.println(response); 72 | 73 | return response; 74 | } 75 | 76 | /** 77 | * 여러 메시지 발송 예제 78 | * 한 번 실행으로 최대 10,000건 까지의 메시지가 발송 가능합니다. 79 | */ 80 | @PostMapping("/send-many-ata") 81 | public MultipleDetailMessageSentResponse sendMany() { 82 | ArrayList messageList = new ArrayList<>(); 83 | 84 | for (int i = 0; i < 3; i++) { 85 | KakaoOption kakaoOption = new KakaoOption(); 86 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 87 | kakaoOption.setPfId(""); 88 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 89 | kakaoOption.setTemplateId(""); 90 | 91 | Message message = new Message(); 92 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 93 | message.setFrom("발신번호 입력"); 94 | message.setTo("수신번호 입력"); 95 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 96 | message.setKakaoOptions(kakaoOption); 97 | 98 | // 기본적으로 실패 시 같은 내용으로 문자 전송을 요청하나, 99 | // 같은 내용이 아닌 다른 내용으로 대체발송을 원한다면 replacements값을 설정해줍니다. 100 | /* 101 | Message replacementMessage = new Message(); 102 | replacementMessage.setFrom("발신번호 입력"); 103 | replacementMessage.setTo("수신번호 입력"); 104 | replacementMessage.setText("실패 시 대체 발송 될 메시지입니다."); 105 | ArrayList replacmentMessages = new ArrayList<>(); 106 | replacmentMessages.add(replacementMessage); 107 | message.setReplacements(replacmentMessages); 108 | */ 109 | 110 | messageList.add(message); 111 | } 112 | 113 | try { 114 | // send 메소드로 단일 Message 객체를 넣어도 동작합니다! 115 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList); 116 | 117 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 118 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, true); 119 | 120 | System.out.println(response); 121 | 122 | return response; 123 | } catch (NurigoMessageNotReceivedException exception) { 124 | System.out.println(exception.getFailedMessageList()); 125 | System.out.println(exception.getMessage()); 126 | } catch (Exception exception) { 127 | System.out.println(exception.getMessage()); 128 | } 129 | return null; 130 | } 131 | 132 | @PostMapping("/send-ata-scheduled-messages") 133 | public MultipleDetailMessageSentResponse sendScheduledMessages() { 134 | ArrayList messageList = new ArrayList<>(); 135 | 136 | for (int i = 0; i < 3; i++) { 137 | KakaoOption kakaoOption = new KakaoOption(); 138 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 139 | kakaoOption.setPfId(""); 140 | // 등록하신 카카오 알림톡 템플릿의 templateId를 입력해주세요. 141 | kakaoOption.setTemplateId(""); 142 | 143 | Message message = new Message(); 144 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 145 | message.setFrom("발신번호 입력"); 146 | message.setTo("수신번호 입력"); 147 | message.setText("한글 45자, 영자 90자 이하 입력되면 자동으로 SMS타입의 메시지가 추가됩니다." + i); 148 | message.setKakaoOptions(kakaoOption); 149 | 150 | messageList.add(message); 151 | } 152 | 153 | try { 154 | // 과거 시간으로 예약 발송을 진행할 경우 즉시 발송처리 됩니다. 155 | LocalDateTime localDateTime = LocalDateTime.parse("2022-05-27 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 156 | ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(localDateTime); 157 | Instant instant = localDateTime.toInstant(zoneOffset); 158 | 159 | // 단일 발송도 지원하여 ArrayList 객체가 아닌 Message 단일 객체만 넣어도 동작합니다! 160 | MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant); 161 | 162 | // 중복 수신번호를 허용하고 싶으실 경우 위 코드 대신 아래코드로 대체해 사용해보세요! 163 | //MultipleDetailMessageSentResponse response = this.messageService.send(messageList, instant, true); 164 | 165 | System.out.println(response); 166 | 167 | return response; 168 | } catch (NurigoMessageNotReceivedException exception) { 169 | System.out.println(exception.getFailedMessageList()); 170 | System.out.println(exception.getMessage()); 171 | } catch (Exception exception) { 172 | System.out.println(exception.getMessage()); 173 | } 174 | return null; 175 | } 176 | 177 | /** 178 | * 친구톡 한건 발송 예제, send 호환, 다량 발송의 경우 위 send-many-ata 코드를 참조해보세요! 179 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 180 | */ 181 | @PostMapping("/send-cta") 182 | public SingleMessageSentResponse sendOneCta() { 183 | KakaoOption kakaoOption = new KakaoOption(); 184 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 185 | // kakaoOption.setDisableSms(true); 186 | 187 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 188 | kakaoOption.setPfId(""); 189 | kakaoOption.setVariables(null); 190 | 191 | // 친구톡에 버튼을 넣으실 경우에만 추가해주세요. 192 | ArrayList kakaoButtons = new ArrayList<>(); 193 | // 웹링크 버튼 194 | KakaoButton kakaoWebLinkButton = new KakaoButton( 195 | "테스트 버튼1", KakaoButtonType.WL, 196 | "https://example.com", "https://example.com", 197 | null, null 198 | ); 199 | 200 | // 앱링크 버튼 201 | KakaoButton kakaoAppLinkButton = new KakaoButton( 202 | "테스트 버튼2", KakaoButtonType.AL, 203 | null, null, 204 | "exampleapp://test", "exampleapp://test" 205 | ); 206 | 207 | // 봇 키워드 버튼, 버튼을 클릭하면 버튼 이름으로 수신자가 발신자에게 채팅을 보냅니다. 208 | KakaoButton kakaoBotKeywordButton = new KakaoButton( 209 | "테스트 버튼3", KakaoButtonType.BK, null, null, null, null 210 | ); 211 | 212 | // 메시지 전달 버튼, 버튼을 클릭하면 버튼 이름과 친구톡 메시지 내용을 포함하여 수신자가 발신자에게 채팅을 보냅니다. 213 | KakaoButton kakaoMessageDeliveringButton = new KakaoButton( 214 | "테스트 버튼4", KakaoButtonType.MD, null, null, null, null 215 | ); 216 | 217 | /* 218 | * 상담톡 전환 버튼, 상담톡 서비스를 이용하고 있을 경우 상담톡으로 전환. 상담톡 서비스 미이용시 해당 버튼 추가될 경우 발송 오류 처리됨. 219 | * @see 상담톡 딜러사 확인 220 | */ 221 | /*KakaoButton kakaoBotCustomerButton = new KakaoButton( 222 | "테스트 버튼6", KakaoButtonType.BC, null, null, null, null 223 | );*/ 224 | 225 | // 봇전환 버튼, 해당 비즈니스 채널에 카카오 챗봇이 없는 경우 동작안함. 226 | // KakaoButton kakaoBotTransferButton = new KakaoButton("테스트 버튼7", KakaoButtonType.BT, null, null, null, null); 227 | 228 | kakaoButtons.add(kakaoWebLinkButton); 229 | kakaoButtons.add(kakaoAppLinkButton); 230 | kakaoButtons.add(kakaoBotKeywordButton); 231 | kakaoButtons.add(kakaoMessageDeliveringButton); 232 | 233 | kakaoOption.setButtons(kakaoButtons); 234 | 235 | Message message = new Message(); 236 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 237 | message.setFrom("발신번호 입력"); 238 | message.setTo("수신번호 입력"); 239 | message.setText("친구톡 테스트 메시지"); 240 | message.setKakaoOptions(kakaoOption); 241 | 242 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 243 | System.out.println(response); 244 | 245 | return response; 246 | } 247 | 248 | /** 249 | * 친구톡 이미지 단건 발송, send 호환, 다량 발송의 경우 위 send-many-ata 코드를 참조해보세요! 250 | * 친구톡 내 버튼은 최대 5개까지만 생성 가능합니다. 251 | */ 252 | @PostMapping("/send-cti") 253 | public SingleMessageSentResponse sendOneCti() throws IOException { 254 | ClassPathResource resource = new ClassPathResource("static/cti.jpg"); 255 | File file = resource.getFile(); 256 | // 이미지 크기는 가로 500px 세로 250px 이상이어야 합니다, 링크도 필수로 기입해주세요. 257 | String imageId = this.messageService.uploadFile(file, StorageType.KAKAO, "https://example.com"); 258 | 259 | KakaoOption kakaoOption = new KakaoOption(); 260 | // disableSms를 true로 설정하실 경우 문자로 대체발송 되지 않습니다. 261 | // kakaoOption.setDisableSms(true); 262 | 263 | // 등록하신 카카오 비즈니스 채널의 pfId를 입력해주세요. 264 | kakaoOption.setPfId(""); 265 | kakaoOption.setImageId(imageId); 266 | kakaoOption.setVariables(null); 267 | 268 | Message message = new Message(); 269 | // 발신번호 및 수신번호는 반드시 01012345678 형태로 입력되어야 합니다. 270 | message.setFrom("발신번호 입력"); 271 | message.setTo("수신번호 입력"); 272 | message.setText("테스트"); 273 | message.setKakaoOptions(kakaoOption); 274 | 275 | SingleMessageSentResponse response = this.messageService.sendOne(new SingleMessageSendingRequest(message)); 276 | System.out.println(response); 277 | 278 | return response; 279 | } 280 | } 281 | -------------------------------------------------------------------------------- /maven-spring-demo/src/main/java/net/nurigo/mavenspringdemo/MavenSpringDemoApplication.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.mavenspringdemo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class MavenSpringDemoApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(MavenSpringDemoApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /maven-spring-demo/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /maven-spring-demo/src/main/resources/static/cti.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/maven-spring-demo/src/main/resources/static/cti.jpg -------------------------------------------------------------------------------- /maven-spring-demo/src/main/resources/static/sample.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/coolsms/coolsms-java-examples/96e1c9f44d1ebe2f055f339cd6ee5b162bf47219/maven-spring-demo/src/main/resources/static/sample.jpg -------------------------------------------------------------------------------- /maven-spring-demo/src/test/java/net/nurigo/mavenspringdemo/MavenSpringDemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package net.nurigo.mavenspringdemo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class MavenSpringDemoApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | --------------------------------------------------------------------------------