├── .gitignore
├── LICENSE
├── README.md
├── config
├── application.properties
└── robot.properties
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── lib
├── common-1.2.1.jar
└── sdk-1.2.1.jar
├── main
├── java
│ ├── cn
│ │ └── wildfirechat
│ │ │ └── app
│ │ │ ├── Application.java
│ │ │ ├── Controller.java
│ │ │ ├── DESUtil.java
│ │ │ ├── ExecutorConfig.java
│ │ │ ├── HttpUtils.java
│ │ │ ├── RobotConfig.java
│ │ │ ├── Service.java
│ │ │ ├── ServiceImpl.java
│ │ │ ├── TokenUtils.java
│ │ │ ├── tuling
│ │ │ ├── TulingResponse.java
│ │ │ └── TulingService.java
│ │ │ └── webhook
│ │ │ ├── IWebhook.java
│ │ │ ├── WebhookService.java
│ │ │ ├── general
│ │ │ └── GeneralWebhook.java
│ │ │ ├── gitee
│ │ │ ├── GiteeWebhook.java
│ │ │ └── pojo
│ │ │ │ ├── Branch.java
│ │ │ │ ├── Commit.java
│ │ │ │ ├── Enterprise.java
│ │ │ │ ├── Issue.java
│ │ │ │ ├── IssueHook.java
│ │ │ │ ├── Label.java
│ │ │ │ ├── Milestone.java
│ │ │ │ ├── Note.java
│ │ │ │ ├── NoteHook.java
│ │ │ │ ├── Project.java
│ │ │ │ ├── PullRequest.java
│ │ │ │ ├── PullRequestHook.java
│ │ │ │ ├── PushOrTagHook.java
│ │ │ │ └── User.java
│ │ │ ├── github
│ │ │ ├── GithubWebhook.java
│ │ │ └── pojo
│ │ │ │ ├── Comment.java
│ │ │ │ ├── Commit.java
│ │ │ │ ├── ForkEvent.java
│ │ │ │ ├── Forkee.java
│ │ │ │ ├── Issue.java
│ │ │ │ ├── IssueCommentEvent.java
│ │ │ │ ├── IssueEvent.java
│ │ │ │ ├── License.java
│ │ │ │ ├── PingEvent.java
│ │ │ │ ├── PullRequest.java
│ │ │ │ ├── PullRequestEvent.java
│ │ │ │ ├── PushEvent.java
│ │ │ │ ├── Pusher.java
│ │ │ │ ├── Repository.java
│ │ │ │ ├── Sender.java
│ │ │ │ ├── StarEvent.java
│ │ │ │ ├── User.java
│ │ │ │ └── WatchEvent.java
│ │ │ └── gitlab
│ │ │ ├── GitLabWebhook.java
│ │ │ └── pojo
│ │ │ ├── Author.java
│ │ │ ├── Commit.java
│ │ │ ├── IssueEvent.java
│ │ │ ├── IssueObjectAttributes.java
│ │ │ ├── Label.java
│ │ │ ├── MergeRequest.java
│ │ │ ├── MergeRequestEvent.java
│ │ │ ├── NoteEvent.java
│ │ │ ├── NoteObjectAttributes.java
│ │ │ ├── Project.java
│ │ │ ├── PushEvent.java
│ │ │ ├── Repository.java
│ │ │ ├── Snippet.java
│ │ │ ├── TagEvent.java
│ │ │ └── User.java
│ └── ikidou
│ │ └── reflect
│ │ ├── TypeBuilder.java
│ │ ├── TypeToken.java
│ │ ├── exception
│ │ └── TypeException.java
│ │ └── typeimpl
│ │ ├── ParameterizedTypeImpl.java
│ │ └── WildcardTypeImpl.java
└── resources
│ └── application.properties
└── test
└── java
└── cn
└── wildfirechat
└── app
└── ApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | .idea
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 wildfirechat
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 | 1. ikidou/TypeBuilder
24 | Copyright 2016 ikidou
25 |
26 | Licensed under the Apache License, Version 2.0 (the "License");
27 | you may not use this file except in compliance with the License.
28 | You may obtain a copy of the License at
29 |
30 | http://www.apache.org/licenses/LICENSE-2.0
31 |
32 | Unless required by applicable law or agreed to in writing, software
33 | distributed under the License is distributed on an "AS IS" BASIS,
34 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35 | See the License for the specific language governing permissions and
36 | limitations under the License.
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 野火IM机器人应用
2 | 作为野火IM机器人应用的演示,本工程仅演示机器人应用的接口。其中用到图灵的免费版。
3 |
4 | #### 编译
5 | ```
6 | mvn package
7 | ```
8 |
9 | #### 图灵
10 | 本应用使用了[图灵机器人](http://www.tuling123.com),需要申请到```atuling_key```,并配置到```robot.properties```中去。用户也可以自行更换为自己的机器人应用。如果不想使用图灵机器人,可以在配置里把参数```use_tuling```设置为false.
11 |
12 | #### 修改配置
13 | 本演示服务有2个配置文件在工程的```config```目录下,分别是```application.properties```和```robot.properties```。请正确配置放到jar包所在的目录下的```config```目录下。
14 |
15 | #### 运行
16 | 在```target```目录找到```robot-XXXX.jar```,把jar包和放置配置文件的```config```目录放到一起,然后执行下面命令:
17 | ```
18 | java -jar robot-XXXXX.jar
19 | ```
20 |
21 | #### 使用到的开源代码
22 | 1. [TypeBuilder](https://github.com/ikidou/TypeBuilder) 一个用于生成泛型的简易Builder
23 |
24 | #### LICENSE
25 | UNDER MIT LICENSE. 详情见LICENSE文件
26 |
--------------------------------------------------------------------------------
/config/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8883
--------------------------------------------------------------------------------
/config/robot.properties:
--------------------------------------------------------------------------------
1 | # 机器人ID
2 | robot.im_id=FireRobot
3 | # 机器人名称。在群里@机器人时,处理消息内容需要去掉机器人的名字。
4 | robot.im_name=小火
5 | # 注意端口是80端口,不是admin的18080端口
6 | robot.im_url=http://localhost
7 | # 注意secret是机器人的secret,不是admin的secret
8 | robot.im_secret=123456
9 |
10 | # 图灵机器人api
11 | robot.use_tuling=true
12 | robot.tuling_key=a09a38b7da2f4f058b3b07972b505ec4
13 |
14 | # 当前服务的公网地址,用来生成webhook地址。
15 | robot.public_addr=http://192.168.3.101:8883
16 |
--------------------------------------------------------------------------------
/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 | # http://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 | # Maven2 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 /etc/mavenrc ] ; then
40 | . /etc/mavenrc
41 | fi
42 |
43 | if [ -f "$HOME/.mavenrc" ] ; then
44 | . "$HOME/.mavenrc"
45 | fi
46 |
47 | fi
48 |
49 | # OS specific support. $var _must_ be set to either true or false.
50 | cygwin=false;
51 | darwin=false;
52 | mingw=false
53 | case "`uname`" in
54 | CYGWIN*) cygwin=true ;;
55 | MINGW*) mingw=true;;
56 | Darwin*) darwin=true
57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html
59 | if [ -z "$JAVA_HOME" ]; then
60 | if [ -x "/usr/libexec/java_home" ]; then
61 | export JAVA_HOME="`/usr/libexec/java_home`"
62 | else
63 | export JAVA_HOME="/Library/Java/Home"
64 | fi
65 | fi
66 | ;;
67 | esac
68 |
69 | if [ -z "$JAVA_HOME" ] ; then
70 | if [ -r /etc/gentoo-release ] ; then
71 | JAVA_HOME=`java-config --jre-home`
72 | fi
73 | fi
74 |
75 | if [ -z "$M2_HOME" ] ; then
76 | ## resolve links - $0 may be a link to maven's home
77 | PRG="$0"
78 |
79 | # need this for relative symlinks
80 | while [ -h "$PRG" ] ; do
81 | ls=`ls -ld "$PRG"`
82 | link=`expr "$ls" : '.*-> \(.*\)$'`
83 | if expr "$link" : '/.*' > /dev/null; then
84 | PRG="$link"
85 | else
86 | PRG="`dirname "$PRG"`/$link"
87 | fi
88 | done
89 |
90 | saveddir=`pwd`
91 |
92 | M2_HOME=`dirname "$PRG"`/..
93 |
94 | # make it fully qualified
95 | M2_HOME=`cd "$M2_HOME" && pwd`
96 |
97 | cd "$saveddir"
98 | # echo Using m2 at $M2_HOME
99 | fi
100 |
101 | # For Cygwin, ensure paths are in UNIX format before anything is touched
102 | if $cygwin ; then
103 | [ -n "$M2_HOME" ] &&
104 | M2_HOME=`cygpath --unix "$M2_HOME"`
105 | [ -n "$JAVA_HOME" ] &&
106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
107 | [ -n "$CLASSPATH" ] &&
108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
109 | fi
110 |
111 | # For Migwn, ensure paths are in UNIX format before anything is touched
112 | if $mingw ; then
113 | [ -n "$M2_HOME" ] &&
114 | M2_HOME="`(cd "$M2_HOME"; pwd)`"
115 | [ -n "$JAVA_HOME" ] &&
116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
117 | # TODO classpath?
118 | fi
119 |
120 | if [ -z "$JAVA_HOME" ]; then
121 | javaExecutable="`which javac`"
122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
123 | # readlink(1) is not available as standard on Solaris 10.
124 | readLink=`which readlink`
125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
126 | if $darwin ; then
127 | javaHome="`dirname \"$javaExecutable\"`"
128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
129 | else
130 | javaExecutable="`readlink -f \"$javaExecutable\"`"
131 | fi
132 | javaHome="`dirname \"$javaExecutable\"`"
133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'`
134 | JAVA_HOME="$javaHome"
135 | export JAVA_HOME
136 | fi
137 | fi
138 | fi
139 |
140 | if [ -z "$JAVACMD" ] ; then
141 | if [ -n "$JAVA_HOME" ] ; then
142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
143 | # IBM's JDK on AIX uses strange locations for the executables
144 | JAVACMD="$JAVA_HOME/jre/sh/java"
145 | else
146 | JAVACMD="$JAVA_HOME/bin/java"
147 | fi
148 | else
149 | JAVACMD="`which java`"
150 | fi
151 | fi
152 |
153 | if [ ! -x "$JAVACMD" ] ; then
154 | echo "Error: JAVA_HOME is not defined correctly." >&2
155 | echo " We cannot execute $JAVACMD" >&2
156 | exit 1
157 | fi
158 |
159 | if [ -z "$JAVA_HOME" ] ; then
160 | echo "Warning: JAVA_HOME environment variable is not set."
161 | fi
162 |
163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
164 |
165 | # traverses directory structure from process work directory to filesystem root
166 | # first directory with .mvn subdirectory is considered project base directory
167 | find_maven_basedir() {
168 |
169 | if [ -z "$1" ]
170 | then
171 | echo "Path not specified to find_maven_basedir"
172 | return 1
173 | fi
174 |
175 | basedir="$1"
176 | wdir="$1"
177 | while [ "$wdir" != '/' ] ; do
178 | if [ -d "$wdir"/.mvn ] ; then
179 | basedir=$wdir
180 | break
181 | fi
182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc)
183 | if [ -d "${wdir}" ]; then
184 | wdir=`cd "$wdir/.."; pwd`
185 | fi
186 | # end of workaround
187 | done
188 | echo "${basedir}"
189 | }
190 |
191 | # concatenates all lines of a file
192 | concat_lines() {
193 | if [ -f "$1" ]; then
194 | echo "$(tr -s '\n' ' ' < "$1")"
195 | fi
196 | }
197 |
198 | BASE_DIR=`find_maven_basedir "$(pwd)"`
199 | if [ -z "$BASE_DIR" ]; then
200 | exit 1;
201 | fi
202 |
203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
204 | echo $MAVEN_PROJECTBASEDIR
205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
206 |
207 | # For Cygwin, switch paths to Windows format before running java
208 | if $cygwin; then
209 | [ -n "$M2_HOME" ] &&
210 | M2_HOME=`cygpath --path --windows "$M2_HOME"`
211 | [ -n "$JAVA_HOME" ] &&
212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
213 | [ -n "$CLASSPATH" ] &&
214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
215 | [ -n "$MAVEN_PROJECTBASEDIR" ] &&
216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
217 | fi
218 |
219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
220 |
221 | exec "$JAVACMD" \
222 | $MAVEN_OPTS \
223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
226 |
--------------------------------------------------------------------------------
/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 http://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 Maven2 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 key stroke 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 enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
84 | @REM Fallback to current working directory if not found.
85 |
86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
88 |
89 | set EXEC_DIR=%CD%
90 | set WDIR=%EXEC_DIR%
91 | :findBaseDir
92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
93 | cd ..
94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
95 | set WDIR=%CD%
96 | goto findBaseDir
97 |
98 | :baseDirFound
99 | set MAVEN_PROJECTBASEDIR=%WDIR%
100 | cd "%EXEC_DIR%"
101 | goto endDetectBaseDir
102 |
103 | :baseDirNotFound
104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
105 | cd "%EXEC_DIR%"
106 |
107 | :endDetectBaseDir
108 |
109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
110 |
111 | @setlocal EnableExtensions EnableDelayedExpansion
112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
114 |
115 | :endReadAdditionalConfig
116 |
117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
118 |
119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
121 |
122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
123 | if ERRORLEVEL 1 goto error
124 | goto end
125 |
126 | :error
127 | set ERROR_CODE=1
128 |
129 | :end
130 | @endlocal & set ERROR_CODE=%ERROR_CODE%
131 |
132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
136 | :skipRcPost
137 |
138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
140 |
141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
142 |
143 | exit /B %ERROR_CODE%
144 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | cn.wildfirechat
7 | robot
8 | 0.25
9 | jar
10 |
11 | robot
12 | Demo project for Spring Boot
13 |
14 |
15 | org.springframework.boot
16 | spring-boot-starter-parent
17 | 2.2.10.RELEASE
18 |
19 |
20 |
21 |
22 | UTF-8
23 | UTF-8
24 | 1.8
25 | 1.2.1
26 | 4.1.12.Final
27 | 2.17.1
28 |
29 |
30 |
31 |
32 | org.springframework.boot
33 | spring-boot-starter
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-web
39 |
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-starter-test
44 | test
45 |
46 |
47 |
48 | org.slf4j
49 | slf4j-api
50 | 1.7.5
51 |
52 |
53 |
54 | org.slf4j
55 | slf4j-log4j12
56 | 1.7.5
57 |
58 |
59 |
60 | org.apache.logging.log4j
61 | log4j-slf4j-impl
62 | ${log4j2.version}
63 |
64 |
65 | org.apache.logging.log4j
66 | log4j-api
67 | ${log4j2.version}
68 |
69 |
70 | org.apache.logging.log4j
71 | log4j-core
72 | ${log4j2.version}
73 |
74 |
75 | org.apache.logging.log4j
76 | log4j-to-slf4j
77 | ${log4j2.version}
78 |
79 |
80 |
81 | com.google.code.gson
82 | gson
83 | 2.8.9
84 |
85 |
86 |
87 | commons-httpclient
88 | commons-httpclient
89 | 3.1
90 |
91 |
92 |
93 | org.apache.httpcomponents
94 | httpclient
95 | 4.5.13
96 |
97 |
98 |
99 | commons-codec
100 | commons-codec
101 | 1.11
102 | compile
103 |
104 |
105 |
106 | com.google.protobuf
107 | protobuf-java
108 | 2.5.0
109 |
110 |
111 |
112 | com.googlecode.json-simple
113 | json-simple
114 | 1.1.1
115 |
116 |
117 |
118 | cn.wildfirechat
119 | sdk
120 | ${wfc.sdk.version}
121 | system
122 | ${project.basedir}/src/lib/sdk-${wfc.sdk.version}.jar
123 |
124 |
125 |
126 | cn.wildfirechat
127 | common
128 | ${wfc.sdk.version}
129 | system
130 | ${project.basedir}/src/lib/common-${wfc.sdk.version}.jar
131 |
132 |
133 |
134 | io.netty
135 | netty-common
136 | ${netty.version}
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | org.springframework.boot
145 | spring-boot-maven-plugin
146 |
147 | true
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
--------------------------------------------------------------------------------
/src/lib/common-1.2.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/robot_server/c5c5d2b8137be2d47b6d5229a608a93d68f7a102/src/lib/common-1.2.1.jar
--------------------------------------------------------------------------------
/src/lib/sdk-1.2.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wildfirechat/robot_server/c5c5d2b8137be2d47b6d5229a608a93d68f7a102/src/lib/sdk-1.2.1.jar
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/Application.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Application {
8 | public static void main(String[] args) {
9 | SpringApplication.run(Application.class, args);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/Controller.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import cn.wildfirechat.app.webhook.WebhookService;
4 | import cn.wildfirechat.pojos.OutputMessageData;
5 | import cn.wildfirechat.pojos.SendMessageData;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.web.bind.annotation.*;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | @RestController
12 | public class Controller {
13 | @Autowired
14 | private Service mService;
15 |
16 | @Autowired
17 | private WebhookService webhookService;
18 |
19 | @PostMapping(value = "/robot/recvmsg", produces = "application/json;charset=UTF-8" )
20 | public Object recvMsg(@RequestBody OutputMessageData messageData) {
21 | mService.onReceiveMessage(messageData);
22 | return "ok";
23 | }
24 |
25 |
26 | @PostMapping(value = "/robot/webhook/{app}/{token}", produces = "application/json;charset=UTF-8" )
27 | public Object webhook(HttpServletRequest request, @PathVariable("app") String app, @PathVariable("token") String token, @RequestBody String payload) {
28 | return webhookService.handleWebhookPost(request, "/"+app, token, payload);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/DESUtil.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import javax.crypto.Cipher;
4 | import javax.crypto.CipherInputStream;
5 | import javax.crypto.CipherOutputStream;
6 | import javax.crypto.SecretKeyFactory;
7 | import javax.crypto.spec.DESKeySpec;
8 | import javax.crypto.spec.IvParameterSpec;
9 | import java.io.*;
10 | import java.security.Key;
11 | import java.util.Base64;
12 |
13 | public class DESUtil {
14 |
15 |
16 | /**
17 | * 偏移变量,固定占8位字节
18 | */
19 | private final static String IV_PARAMETER = "12345678";
20 | /**
21 | * 密钥算法
22 | */
23 | private static final String ALGORITHM = "DES";
24 | /**
25 | * 加密/解密算法-工作模式-填充模式
26 | */
27 | private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";
28 | /**
29 | * 默认编码
30 | */
31 | private static final String CHARSET = "utf-8";
32 |
33 | private static final String password = "ax8123csdd";
34 |
35 | /**
36 | * 生成key
37 | *
38 | * @param password
39 | * @return
40 | * @throws Exception
41 | */
42 | private static Key generateKey(String password) throws Exception {
43 | DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));
44 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
45 | return keyFactory.generateSecret(dks);
46 | }
47 |
48 |
49 | /**
50 | * DES加密字符串
51 | *
52 | * @param data 待加密字符串
53 | * @return 加密后内容
54 | */
55 | public static String encrypt(String data) {
56 | if (password== null || password.length() < 8) {
57 | throw new RuntimeException("加密失败,key不能小于8位");
58 | }
59 | if (data == null)
60 | return null;
61 | try {
62 | Key secretKey = generateKey(password);
63 | Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
64 | IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
65 | cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
66 | byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));
67 |
68 | //JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder
69 | //Android平台可以使用android.util.Base64
70 | String s = new String(Base64.getEncoder().encode(bytes));
71 | s = s.replace("/", "~").replace("+","-").replace("=","_");
72 | return s;
73 | } catch (Exception e) {
74 | e.printStackTrace();
75 | return data;
76 | }
77 | }
78 |
79 | /**
80 | * DES解密字符串
81 | *
82 | * @param data 待解密字符串
83 | * @return 解密后内容
84 | */
85 | public static String decrypt(String data) {
86 | if (data == null)
87 | return null;
88 | try {
89 | data = data.replace("~", "/").replace("-", "+").replace("_", "=");
90 | Key secretKey = generateKey(password);
91 | Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
92 | IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));
93 | cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
94 | return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET);
95 | } catch (Exception e) {
96 | e.printStackTrace();
97 | return data;
98 | }
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/ExecutorConfig.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.scheduling.annotation.EnableAsync;
6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
7 |
8 | import java.util.concurrent.Executor;
9 |
10 | @Configuration
11 | @EnableAsync
12 | public class ExecutorConfig {
13 |
14 | @Bean
15 | public Executor asyncExecutor() {
16 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
17 | executor.setCorePoolSize(10);
18 | executor.setMaxPoolSize(10);
19 | executor.initialize();
20 | return executor;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/HttpUtils.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import cn.wildfirechat.sdk.model.IMResult;
4 | import com.google.gson.Gson;
5 | import ikidou.reflect.TypeBuilder;
6 | import org.apache.commons.codec.digest.DigestUtils;
7 | import org.apache.http.HttpResponse;
8 | import org.apache.http.HttpStatus;
9 | import org.apache.http.client.HttpClient;
10 | import org.apache.http.client.methods.HttpPost;
11 | import org.apache.http.entity.StringEntity;
12 | import org.apache.http.impl.client.HttpClientBuilder;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 |
16 | import java.io.BufferedReader;
17 | import java.io.InputStreamReader;
18 | import java.lang.reflect.Type;
19 | import java.nio.charset.Charset;
20 |
21 |
22 | public class HttpUtils {
23 | private static final Logger LOG = LoggerFactory.getLogger(HttpUtils.class);
24 |
25 | static public T post(String url, Object object, Class clazz) throws Exception{
26 |
27 | HttpPost post = null;
28 | try {
29 | HttpClient httpClient = HttpClientBuilder.create().build();
30 |
31 | post = new HttpPost(url);
32 | post.setHeader("Content-type", "application/json; charset=utf-8");
33 | post.setHeader("Connection", "Keep-Alive");
34 |
35 | String jsonStr;
36 | if (object instanceof String) {
37 | jsonStr = (String) object;
38 | } else {
39 | jsonStr = new Gson().toJson(object);
40 | }
41 |
42 | LOG.info("http request content: {}", jsonStr);
43 |
44 | StringEntity entity = new StringEntity(jsonStr, Charset.forName("UTF-8"));
45 | entity.setContentEncoding("UTF-8");
46 | entity.setContentType("application/json");
47 | post.setEntity(entity);
48 | HttpResponse response = httpClient.execute(post);
49 |
50 | int statusCode = response.getStatusLine().getStatusCode();
51 | if(statusCode != HttpStatus.SC_OK){
52 | LOG.info("Request error: "+statusCode);
53 | throw new Exception("Http request error with code:" + statusCode);
54 | }else{
55 | BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity()
56 | .getContent(),"utf-8"));
57 | StringBuffer sb = new StringBuffer();
58 | String line;
59 | String NL = System.getProperty("line.separator");
60 | while ((line = in.readLine()) != null) {
61 | sb.append(line + NL);
62 | }
63 |
64 | in.close();
65 |
66 | String content = sb.toString();
67 | LOG.info("http request response content: {}", content);
68 |
69 | return new Gson().fromJson(content, clazz);
70 | }
71 | } catch (Exception e) {
72 | e.printStackTrace();
73 | throw e;
74 | }finally{
75 | if(post != null){
76 | post.releaseConnection();
77 | }
78 | }
79 | }
80 |
81 | private static IMResult fromJsonObject(String content, Class clazz) {
82 | Type type = TypeBuilder
83 | .newInstance(IMResult.class)
84 | .addTypeParam(clazz)
85 | .build();
86 | return new Gson().fromJson(content, type);
87 | }
88 |
89 | private static boolean isNullOrEmpty(String str) {
90 | return str == null || str.isEmpty();
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/RobotConfig.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.context.annotation.PropertySource;
6 |
7 | @Configuration
8 | @ConfigurationProperties(prefix="robot")
9 | @PropertySource(value = "file:config/robot.properties", encoding = "UTF-8")
10 | public class RobotConfig {
11 | public String im_url;
12 | public String im_secret;
13 | public String im_id;
14 | public String im_name;
15 |
16 | public boolean use_tuling;
17 |
18 | public String tuling_key;
19 |
20 | public String public_addr;
21 |
22 | public boolean isUse_tuling() {
23 | return use_tuling;
24 | }
25 |
26 | public void setUse_tuling(boolean use_tuling) {
27 | this.use_tuling = use_tuling;
28 | }
29 |
30 | public String getTuling_key() {
31 | return tuling_key;
32 | }
33 |
34 | public void setTuling_key(String tuling_key) {
35 | this.tuling_key = tuling_key;
36 | }
37 |
38 | public String getIm_name() {
39 | return im_name;
40 | }
41 |
42 | public void setIm_name(String im_name) {
43 | this.im_name = im_name;
44 | }
45 |
46 | public String getIm_id() {
47 | return im_id;
48 | }
49 |
50 | public void setIm_id(String im_id) {
51 | this.im_id = im_id;
52 | }
53 |
54 | public String getIm_url() {
55 | return im_url;
56 | }
57 |
58 | public void setIm_url(String im_url) {
59 | this.im_url = im_url;
60 | }
61 |
62 | public String getIm_secret() {
63 | return im_secret;
64 | }
65 |
66 | public void setIm_secret(String im_secret) {
67 | this.im_secret = im_secret;
68 | }
69 |
70 | public String getPublic_addr() {
71 | return public_addr;
72 | }
73 |
74 | public void setPublic_addr(String public_addr) {
75 | this.public_addr = public_addr;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/Service.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 |
4 | import cn.wildfirechat.pojos.OutputMessageData;
5 | import cn.wildfirechat.pojos.SendMessageData;
6 |
7 | public interface Service {
8 | void onReceiveMessage(OutputMessageData messageData);
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/ServiceImpl.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import cn.wildfirechat.app.tuling.TulingService;
4 | import cn.wildfirechat.app.webhook.WebhookService;
5 | import cn.wildfirechat.common.ErrorCode;
6 | import cn.wildfirechat.messagecontentbuilder.StreamingTextMessageContentBuilder;
7 | import cn.wildfirechat.pojos.*;
8 | import cn.wildfirechat.proto.ProtoConstants;
9 | import cn.wildfirechat.sdk.MessageAdmin;
10 | import cn.wildfirechat.sdk.RobotService;
11 | import cn.wildfirechat.sdk.model.*;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 | import org.springframework.beans.factory.annotation.Autowired;
15 | import org.springframework.scheduling.annotation.Async;
16 | import sun.misc.BASE64Encoder;
17 |
18 | import javax.annotation.PostConstruct;
19 | import java.util.Arrays;
20 | import java.util.UUID;
21 |
22 | @org.springframework.stereotype.Service
23 | public class ServiceImpl implements Service {
24 | private static final Logger LOG = LoggerFactory.getLogger(ServiceImpl.class);
25 |
26 | @Autowired
27 | private RobotConfig mRobotConfig;
28 |
29 | @Autowired
30 | private WebhookService webhookService;
31 |
32 | @Autowired
33 | private TulingService tulingService;
34 |
35 | private RobotService robotService;
36 |
37 | @PostConstruct
38 | private void init() {
39 | robotService = new RobotService(mRobotConfig.im_url, mRobotConfig.getIm_id(), mRobotConfig.im_secret);
40 | }
41 |
42 | // int ConversationType_Private = 0;
43 | // int ConversationType_Group = 1;
44 | // int ConversationType_ChatRoom = 2;
45 | // int ConversationType_Channel = 3;
46 | // int ConversationType_Thing = 4;
47 | @Override
48 | @Async("asyncExecutor")
49 | public void onReceiveMessage(OutputMessageData messageData) {
50 | LOG.info("on receive message {}", messageData.getMessageId());
51 | boolean needResponse = false;
52 | if (messageData.getConv().getType() == 0) {
53 | needResponse = true;
54 | }
55 | if (!needResponse && messageData.getConv().getType() == 1) {
56 | if (messageData.getPayload() != null) {
57 | if (messageData.getPayload().getMentionedType() == 2) {
58 | //needResponse = true;
59 | needResponse = false; //@全体时,机器人就别乱回复捣乱了
60 | } else if (messageData.getPayload().getMentionedType() == 1) {
61 | if (messageData.getPayload().getMentionedTarget() != null && messageData.getPayload().getMentionedTarget().contains(mRobotConfig.getIm_id())) {
62 | needResponse = true;
63 | }
64 | }
65 | }
66 | }
67 | // public interface ContentType {
68 | // int Unknown = 0;
69 | // int Text = 1;
70 | // int Image = 2;
71 | // int Voice = 3;
72 | // int Location = 4;
73 | // int Video = 5;
74 | // int RichMedia = 6;
75 | // }
76 | if (needResponse) {
77 | Conversation conversation = messageData.getConv();
78 | if (conversation.getType() == 0) {
79 | conversation.setTarget(messageData.getSender());
80 | }
81 |
82 | String response = messageData.getPayload().getSearchableContent();
83 | boolean localResponse = true;
84 |
85 | LOG.info("msg:{}, robotName:{}", response, mRobotConfig.im_name);
86 | response = response.replace("@" + mRobotConfig.im_name, "").trim();
87 | LOG.info("msg:{}, robotName:{}", response, mRobotConfig.im_name);
88 | if (messageData.getPayload().getType() == 1) {
89 | if(response.contains("地址") || response.contains("文档") || response.contains("论坛") || response.contains("官网")) {
90 | localResponse = false;
91 | response = "项目地址在: https://github.com/wildfirechat。 文档地址在: https://docs.wildfirechat.cn。论坛地址在: https://bbs.wildfirechat.cn。官网地址在:https://wildfirechat.cn";
92 | } else if(response.startsWith("公众号")) {
93 | localResponse = false;
94 | response = "请关注微信公众号:野火IM";
95 | } else if(response.startsWith("价格") || response.startsWith("收费") || response.startsWith("费用")) {
96 | localResponse = false;
97 | response = "野火IM相关价格,请参考我们的文档: http://docs.wildfirechat.cn";
98 | } else if(response.startsWith("商务") || response.startsWith("购买") || response.startsWith("联系")) {
99 | localResponse = false;
100 | response = "请微信联系 wildfirechat 或 wfchat 进行商务交流";
101 | } else if(response.startsWith("问题") || response.startsWith("崩溃")) {
102 | localResponse = false;
103 | response = "请确保是按照文档进行对接使用。请检索github issue或者论坛bbs.wildfirechat.cn。如果还无法解决请提issue或者论坛发帖";
104 | } else if(response.equalsIgnoreCase("/list") || response.equalsIgnoreCase("/")) {
105 | if (conversation.getType() == 1 || conversation.getType() == 0) {
106 | response = webhookService.InvokeCommands();
107 | } else {
108 | response = "仅支持群组和私聊";
109 | }
110 | } else if(response.equals("流式文本")) {
111 | testStreamingText(conversation);
112 | return;
113 | } else if(webhookService.handleInvokeCommand(response, messageData.getSender(), messageData.getConv())) {
114 | return;
115 | } else {
116 | response = tulingService.handleWord(messageData.getSender(), response);
117 | }
118 | } else if (messageData.getPayload().getType() == 3) {
119 | localResponse = false;
120 | response = "不好意思,我还不会看照片哟~";
121 | } else if (messageData.getPayload().getType() == 2) {
122 | localResponse = false;
123 | response = "不好意思,我还不会听声音哟~";
124 | } else if (messageData.getPayload().getType() == 4) {
125 | localResponse = false;
126 | response = "这是那里?我还没有学会看地图啊!";
127 | } else if (messageData.getPayload().getType() == 6) {
128 | localResponse = false;
129 | response = "我也想看视频,可惜我还没学会!";
130 | } else if (messageData.getPayload().getType() == 400) {
131 | localResponse = false;
132 | response = "别给我打电话了,我是个机器人,还不会接电话,还没有人教过我啊!";
133 |
134 | MessagePayload payload = new MessagePayload();
135 | payload.setType(402);
136 | payload.setContent(messageData.getPayload().getContent());
137 | String reason = "{\"r\":5}";
138 | payload.setBase64edData(new BASE64Encoder().encode(reason.getBytes()));
139 | try {
140 | robotService.sendMessage(mRobotConfig.getIm_id(), conversation, payload);
141 | } catch (Exception e) {
142 | e.printStackTrace();
143 | }
144 | } else if(messageData.getPayload().getType() > 400 && messageData.getPayload().getType() < 500) {
145 | //voip signal message, ignore it
146 | return;
147 | }
148 |
149 | if(localResponse) {
150 | if (messageData.getPayload().getType() != 1) {
151 | response = "我不明白你在说什么";
152 | } else {
153 | response = response.replace("@" + mRobotConfig.getIm_name() + " ", "");
154 | response = response.replace("@" + mRobotConfig.getIm_name(), "");
155 | response = response.replace("我", "");
156 | response = response.replace("吗", "");
157 | response = response.replace("你是谁", "我是" + mRobotConfig.getIm_name() + "呀");
158 | response = response.replace("你", "我");
159 | response = response.replace("?", "!");
160 | response = response.replace("? ", "!");
161 | response = response.replace("?", "!");
162 | response = response.replace("? ", "!");
163 | if (response.equals(messageData.getPayload().getSearchableContent())) {
164 | response = "我不明白你在说什么";
165 | }
166 | }
167 | }
168 |
169 | MessagePayload payload = new MessagePayload();
170 | payload.setType(1);
171 | payload.setSearchableContent(response);
172 | if (conversation.getType() == 1 && messageData.getPayload().getType() == 1) { //群里的文本,加上@信息
173 | InputOutputUserInfo sender = null;
174 | try {
175 | IMResult result = robotService.getUserInfo(messageData.getSender());
176 | if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
177 | sender = result.getResult();
178 | }
179 | } catch (Exception e) {
180 | e.printStackTrace();
181 | }
182 | if (sender != null && sender.getDisplayName() != null) {
183 | payload.setSearchableContent("@" + sender.getDisplayName() + " " + payload.getSearchableContent());
184 | payload.setMentionedType(1);
185 | payload.setMentionedTarget(Arrays.asList(messageData.getSender()));
186 | }
187 | }
188 | try {
189 | IMResult result = robotService.sendMessage(mRobotConfig.getIm_id(), conversation, payload);
190 | if (result != null) {
191 | if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
192 | LOG.info("Send response success");
193 | } else {
194 | LOG.error("Send response error {}", result.getCode());
195 | }
196 | } else {
197 | LOG.error("Send response is null");
198 | }
199 | } catch (Exception e) {
200 | e.printStackTrace();
201 | LOG.error("Send response execption");
202 | }
203 | }
204 | return;
205 | }
206 |
207 |
208 | void testStreamingText(Conversation conversation) {
209 | String fullText = "北京野火无限网络科技有限公司是成立于2019年底的一家科技创新企业,公司的主要目标是为广大企业和单位提供优质可控、私有部署的即时通讯和实时音视频能力,为社会信息化水平提高作出自己的贡献。\n" +
210 | "\n" +
211 | "野火IM是公司研发一套自主可控的即时通讯组件,具有全部私有化、功能齐全、协议稳定可靠、全平台支持、安全性高和支持国产化等技术特点。客户端分层设计,既可开箱即用,也可与现有系统深度融合。具有完善的服务端API和自定义消息功能,可以任意扩展功能。代码开源率高,方便二次开发和使用。支持多人实时音视频和会议功能,线上沟通更通畅。\n" +
212 | "\n" +
213 | "公司致力于开源项目,在Github上开源项目广受好评,其中Server项目有超过7.1K个Star,组织合计Star超过1万个。有大量的技术公司受益于我们的开源,为自己的产品添加了即时通讯能力,这也算是我们公司为社会信息化建设做出的一点点贡献吧。\n" +
214 | "\n" +
215 | "公司以即时通讯技术为核心,持续努力优化和完善即时通讯和实时音视频产品,努力为客户提供最优质的即时通讯和实时音视频能力。";
216 | int i = 0;
217 | String streamId = UUID.randomUUID().toString();
218 | while (i < fullText.length()) {
219 | i+= 15;
220 |
221 | boolean finish = i >= fullText.length();
222 | String partText = finish?fullText:fullText.substring(0, i);
223 |
224 | MessagePayload payload = StreamingTextMessageContentBuilder.newBuilder(streamId).text(partText).generating(!finish).build();
225 |
226 | try {
227 | IMResult resultSendMessage = robotService.sendMessage(mRobotConfig.getIm_id(), conversation, payload);
228 | if (resultSendMessage != null && resultSendMessage.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
229 | System.out.println("send message success");
230 | } else {
231 | System.out.println("send message failure");
232 | return;
233 | }
234 |
235 | Thread.sleep(500);
236 | } catch (Exception e) {
237 | e.printStackTrace();
238 | return;
239 | }
240 | }
241 | }
242 | }
243 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/TokenUtils.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import cn.wildfirechat.pojos.Conversation;
4 |
5 | public class TokenUtils {
6 | private static final String signWord = "hello world";
7 | public static String webhookToken(Conversation conversation, String user) {
8 | String key = conversation.getType() + "|" + conversation.getLine() + "|" + conversation.getTarget() + signWord + user;
9 | return DESUtil.encrypt(key);
10 | }
11 |
12 | public static String userFromToken(String token) {
13 | String s = DESUtil.decrypt(token);
14 | if(s == null) {
15 | return null;
16 | }
17 |
18 | return s.substring(s.indexOf(signWord) + signWord.length());
19 | }
20 | public static Conversation conversationFromToken(String token) {
21 | String s = DESUtil.decrypt(token);
22 | if(s == null) {
23 | return null;
24 | }
25 | Conversation conversation = new Conversation();
26 | String[] arr = s.split("\\|");
27 | conversation.setType(Integer.parseInt(arr[0]));
28 | conversation.setLine(Integer.parseInt(arr[1]));
29 | String target = s.substring((conversation.getType()+"|"+conversation.getLine()+"|").length(), s.indexOf(signWord));
30 | conversation.setTarget(target);
31 | return conversation;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/tuling/TulingResponse.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.tuling;
2 |
3 | import java.util.List;
4 |
5 | public class TulingResponse {
6 | public static class Intent {
7 | int code;
8 | String intentName;
9 | String actionName;
10 | }
11 | public static class Value {
12 | String url;
13 | String text;
14 | }
15 | public static class Result {
16 | int groupType;
17 | String resultType;
18 | Value values;
19 | }
20 | public Intent intent;
21 | public List results;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/tuling/TulingService.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.tuling;
2 |
3 | import cn.wildfirechat.app.HttpUtils;
4 | import cn.wildfirechat.app.RobotConfig;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.util.StringUtils;
8 |
9 | @Service
10 | public class TulingService {
11 | @Autowired
12 | private RobotConfig mRobotConfig;
13 |
14 | public String handleWord(String sender, String text) {
15 | String response = "";
16 | if (mRobotConfig.use_tuling) {
17 | String searchReq = "{\n" + "\t\"reqType\":0,\n" + " \"perception\": {\n" + " \"inputText\": {\n" + " \"text\": \"${TEXT}\"\n" + " }\n" + " },\n" + " \"userInfo\": {\n" + " \"apiKey\": \"${APIKEY}\",\n" + " \"userId\": \"${USERID}\"\n" + " }\n" + "}";
18 | searchReq = searchReq.replace("${APIKEY}", mRobotConfig.getTuling_key()).replace("${USERID}", Math.abs(sender.hashCode()) + "");
19 | searchReq = searchReq.replace("${TEXT}", text);
20 |
21 |
22 | try {
23 | TulingResponse s = HttpUtils.post("http://openapi.tuling123.com/openapi/api/v2", searchReq, TulingResponse.class);
24 | if (s != null) {
25 | if (s.results != null && s.results.size() > 0) {
26 | for (TulingResponse.Result result : s.results
27 | ) {
28 | if (result.values != null) {
29 | if (!StringUtils.isEmpty(result.values.text)) {
30 | if(StringUtils.isEmpty(response)) {
31 | response = result.values.text;
32 | } else {
33 | response = response + " \n" + result.values.text;
34 | }
35 | }
36 |
37 | if (!StringUtils.isEmpty(result.values.url)) {
38 | if(StringUtils.isEmpty(response)) {
39 | response = result.values.url;
40 | } else {
41 | response = response + " \n" + result.values.url;
42 | }
43 | }
44 | }
45 | }
46 | }
47 | }
48 | } catch (Exception e) {
49 | e.printStackTrace();
50 | }
51 | }
52 | return response;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/IWebhook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook;
2 |
3 | import cn.wildfirechat.pojos.MessagePayload;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 |
7 | public interface IWebhook {
8 | interface SendMessageCallback {
9 | void sendMessage(MessagePayload payload);
10 | }
11 |
12 | String invokeCommand();
13 | Object handleWebhookPost(HttpServletRequest request, String user, String body, SendMessageCallback callback);
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/WebhookService.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook;
2 |
3 | import cn.wildfirechat.app.RobotConfig;
4 | import cn.wildfirechat.app.TokenUtils;
5 | import cn.wildfirechat.app.webhook.general.GeneralWebhook;
6 | import cn.wildfirechat.app.webhook.gitee.GiteeWebhook;
7 | import cn.wildfirechat.app.webhook.github.GithubWebhook;
8 | import cn.wildfirechat.app.webhook.gitlab.GitLabWebhook;
9 | import cn.wildfirechat.common.ErrorCode;
10 | import cn.wildfirechat.pojos.Conversation;
11 | import cn.wildfirechat.pojos.InputOutputUserInfo;
12 | import cn.wildfirechat.pojos.MessagePayload;
13 | import cn.wildfirechat.pojos.SendMessageResult;
14 | import cn.wildfirechat.sdk.RobotService;
15 | import cn.wildfirechat.sdk.model.IMResult;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 | import org.springframework.beans.factory.annotation.Autowired;
19 | import org.springframework.stereotype.Service;
20 |
21 | import javax.annotation.PostConstruct;
22 | import javax.servlet.http.HttpServletRequest;
23 | import javax.validation.Payload;
24 | import java.util.HashMap;
25 | import java.util.Map;
26 | import java.util.concurrent.ConcurrentHashMap;
27 |
28 | @Service
29 | public class WebhookService {
30 | private static class Pair {
31 | public String key;
32 | public long value;
33 |
34 | public Pair(String key, long value) {
35 | this.key = key;
36 | this.value = value;
37 | }
38 |
39 | public String getKey() {
40 | return key;
41 | }
42 |
43 | public long getValue() {
44 | return value;
45 | }
46 | }
47 | private static final Logger LOG = LoggerFactory.getLogger(WebhookService.class);
48 | @Autowired
49 | private RobotConfig mRobotConfig;
50 |
51 | private Map webhookMap;
52 |
53 | private Map userNameCache = new ConcurrentHashMap<>();
54 |
55 |
56 | private RobotService robotService;
57 |
58 | @PostConstruct
59 | void init() {
60 | webhookMap = new HashMap<>();
61 |
62 | IWebhook github = new GithubWebhook();
63 | IWebhook gitlab = new GitLabWebhook();
64 | IWebhook general = new GeneralWebhook();
65 | IWebhook gitee = new GiteeWebhook();
66 |
67 | webhookMap.put(general.invokeCommand(), general);
68 | webhookMap.put(github.invokeCommand(), github);
69 | webhookMap.put(gitlab.invokeCommand(), gitlab);
70 | webhookMap.put(gitee.invokeCommand(), gitee);
71 |
72 | robotService = new RobotService(mRobotConfig.im_url, mRobotConfig.getIm_id(), mRobotConfig.im_secret);
73 | }
74 |
75 | public String InvokeCommands() {
76 | String commands = "";
77 | for (String command : webhookMap.keySet()) {
78 | commands += command;
79 | commands += "\n";
80 | }
81 |
82 | return commands;
83 | }
84 |
85 | public boolean handleInvokeCommand(String command, String fromUser, Conversation conversation) {
86 | if(webhookMap.containsKey(command)) {
87 | IWebhook webhook = webhookMap.get(command);
88 | String callback = mRobotConfig.getPublic_addr()
89 | + "/robot"
90 | + "/webhook"
91 | + webhook.invokeCommand()
92 | + "/" + TokenUtils.webhookToken(conversation, fromUser);
93 |
94 | String response = "您请求应用的webhook地址为:\n" + callback;
95 | if(conversation.getType() == 0) {
96 | sendMessage(conversation, response);
97 | } else if(conversation.getType() == 1) {
98 | Conversation privateConv = new Conversation();
99 | privateConv.setLine(conversation.getLine());
100 | privateConv.setType(0);
101 | privateConv.setTarget(fromUser);
102 | sendMessage(privateConv, response);
103 | sendMessage(conversation, "Webhook地址已经发送给您本人了,请到您与机器人的单聊会话查收");
104 | }
105 | return true;
106 | }
107 | return false;
108 | }
109 |
110 | public Object handleWebhookPost(HttpServletRequest request, String app, String token, String body) {
111 | LOG.info("receive callback {}", app);
112 | if(webhookMap.containsKey(app)) {
113 | IWebhook webhook = webhookMap.get(app);
114 | String user = TokenUtils.userFromToken(token);
115 | Conversation conversation = TokenUtils.conversationFromToken(token);
116 | LOG.info("user {}", user);
117 | if(user != null) {
118 | Pair namePair = userNameCache.computeIfAbsent(user, s -> {
119 | try {
120 | IMResult inputOutputUserInfo = robotService.getUserInfo(s);
121 | if(inputOutputUserInfo != null && inputOutputUserInfo.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS && inputOutputUserInfo.getResult() != null) {
122 | return new Pair(inputOutputUserInfo.getResult().getDisplayName(), System.currentTimeMillis());
123 | }
124 | } catch (Exception e) {
125 | e.printStackTrace();
126 | }
127 | return new Pair("user " + s, System.currentTimeMillis());
128 | });
129 | if(namePair.getValue() + 24 * 60 * 60 * 1000 < System.currentTimeMillis()) {
130 | userNameCache.remove(user);
131 | }
132 |
133 | return webhook.handleWebhookPost(request, namePair.getKey(), body, payload -> {
134 | sendMessage(conversation, payload);
135 | });
136 | }
137 | }
138 | return "ok";
139 | }
140 |
141 | private void sendMessage(Conversation conversation, MessagePayload payload) {
142 | IMResult result = null;
143 | try {
144 | result = robotService.sendMessage(mRobotConfig.getIm_id(), conversation, payload);
145 | } catch (Exception e) {
146 | e.printStackTrace();
147 | }
148 |
149 | if (result != null) {
150 | if (result.getErrorCode() == ErrorCode.ERROR_CODE_SUCCESS) {
151 | LOG.info("Send response success");
152 | } else {
153 | LOG.error("Send response error {}", result.getCode());
154 | }
155 | } else {
156 | LOG.error("Send response error");
157 | }
158 | }
159 |
160 | private void sendMessage(Conversation conversation, String text) {
161 | MessagePayload payload = new MessagePayload();
162 | payload.setType(1);
163 | payload.setSearchableContent(text);
164 | sendMessage(conversation, payload);
165 | }
166 | }
167 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/general/GeneralWebhook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.general;
2 |
3 | import cn.wildfirechat.app.webhook.IWebhook;
4 | import cn.wildfirechat.pojos.MessagePayload;
5 | import org.apache.commons.codec.binary.Base64;
6 | import org.json.simple.JSONObject;
7 | import org.json.simple.parser.JSONParser;
8 | import org.json.simple.parser.ParseException;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 | import java.nio.charset.StandardCharsets;
12 |
13 | public class GeneralWebhook implements IWebhook {
14 | @Override
15 | public String invokeCommand() {
16 | return "/general";
17 | }
18 |
19 | @Override
20 | public Object handleWebhookPost(HttpServletRequest request, String user, String body, SendMessageCallback callback) {
21 | MessagePayload messagePayload = new MessagePayload();
22 | try {
23 | JSONObject object = (JSONObject)(new JSONParser().parse(body));
24 | long type = (Long) object.get("type");
25 | if(type == 1) {
26 | String text = (String)object.get("text");
27 | messagePayload.setType(1);
28 | messagePayload.setSearchableContent(text + "\n\n来自 " + user + " 的机器人消息");
29 | } else if(type == 8) {
30 | String title = (String) object.get("title");
31 | String digest = (String) object.get("digest");
32 | String url = (String) object.get("url");
33 | messagePayload.setType(8);
34 | messagePayload.setSearchableContent(title);
35 | JSONObject jsonObject = new JSONObject();
36 | jsonObject.put("d", digest);
37 | jsonObject.put("u", url);
38 | messagePayload.setBase64edData(new Base64().encodeAsString(jsonObject.toString().getBytes(StandardCharsets.UTF_8)));
39 | } else {
40 | messagePayload.setType(1);
41 | messagePayload.setSearchableContent(body + "\n\n来自 " + user + " 的机器人消息");
42 | }
43 | } catch (Exception e) {
44 | e.printStackTrace();
45 | messagePayload.setType(1);
46 | messagePayload.setSearchableContent(body + "\n\n来自 " + user + " 的机器人消息");
47 | }
48 |
49 | callback.sendMessage(messagePayload);
50 | return "ok";
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/GiteeWebhook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee;
2 |
3 | import cn.wildfirechat.app.webhook.IWebhook;
4 | import cn.wildfirechat.app.webhook.gitee.pojo.*;
5 | import cn.wildfirechat.pojos.MessagePayload;
6 | import com.google.gson.Gson;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 |
12 | public class GiteeWebhook implements IWebhook {
13 | private static final Logger LOG = LoggerFactory.getLogger(GiteeWebhook.class);
14 | @Override
15 | public String invokeCommand() {
16 | return "/gitee";
17 | }
18 |
19 | @Override
20 | public Object handleWebhookPost(HttpServletRequest request, String user, String githubPayload, SendMessageCallback callback) {
21 | String event = request.getHeader("X-Gitee-Event");
22 | LOG.info("on receive message {}, event {}", githubPayload, event);
23 |
24 | String message = null;
25 |
26 | //https://gitee.com/help/articles/4271#article-header0
27 | MessagePayload messagePayload = new MessagePayload();
28 | messagePayload.setType(1);
29 | try {
30 | if (event.equals("Push Hook")) {
31 | PushOrTagHook pushOrTagHook = new Gson().fromJson(githubPayload, PushOrTagHook.class);
32 | message = pushOrTagHook.sender.name + " push " + pushOrTagHook.total_commits_count + " commits";
33 | if (pushOrTagHook.commits != null) {
34 | for (Commit commit : pushOrTagHook.commits) {
35 | message += "\nCommit url: " + commit.url;
36 | message += "\nCommit message: " + commit.message;
37 | message += "\n";
38 | }
39 | }
40 | } else if(event.equals("Tag Push Hook")) {
41 | PushOrTagHook pushOrTagHook = new Gson().fromJson(githubPayload, PushOrTagHook.class);
42 | message = pushOrTagHook.sender.name + (pushOrTagHook.created ? "创建了" : (pushOrTagHook.deleted ? "删除了":"更新了")) + " tag.";
43 | message += "\nTag: " + pushOrTagHook.compare;
44 | message += "\nRef: " + pushOrTagHook.ref;
45 | } else if(event.equals("Issue Hook")) {
46 | IssueHook issueHook = new Gson().fromJson(githubPayload, IssueHook.class);
47 | message = issueHook.sender.name + " " + issueHook.action + " issue.";
48 | message += "\nIssue:" + issueHook.issue.html_url;
49 | message += "\nMessage: " + issueHook.description;
50 | message += "\nStatus: " + issueHook.state;
51 | } else if(event.equals("Note Hook")) {
52 | NoteHook noteHook = new Gson().fromJson(githubPayload, NoteHook.class);
53 | message = noteHook.sender.name + " " + noteHook.action + " issue";
54 | message += "\nIssue:" + noteHook.issue.html_url;
55 | message += "\nMessage: " + noteHook.note;
56 | message += "\nStatus: " + noteHook.issue.state;
57 | } else if(event.equals("Pull Request Hook")) {
58 | PullRequestHook pullRequestHook = new Gson().fromJson(githubPayload, PullRequestHook.class);
59 | message = pullRequestHook.sender.name + " " + pullRequestHook.action + "PR";
60 | message += "\nPR: " + pullRequestHook.url;
61 | message += "\nTitle: " + pullRequestHook.title;
62 | message += "\nBody: " + pullRequestHook.body;
63 | }
64 | } catch (Exception e) {
65 | e.printStackTrace();
66 | messagePayload.setSearchableContent("糟糕,处理gitee事件出错了:" + e.getMessage());
67 | callback.sendMessage(messagePayload);
68 | }
69 |
70 | if (message == null) {
71 | messagePayload.setSearchableContent("你收到了一个gitee事件:" + event);
72 | callback.sendMessage(messagePayload);
73 |
74 | messagePayload.setSearchableContent(githubPayload);
75 | callback.sendMessage(messagePayload);
76 | } else {
77 | messagePayload.setSearchableContent(message);
78 | callback.sendMessage(messagePayload);
79 | }
80 | return "ok";
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Branch.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Branch {
4 | public String label;
5 | public String ref;
6 | public String sha;
7 | public User user;
8 | public Project repo;
9 | /*
10 | label: String, # 分支标记。eg:oschina:master
11 | ref: String, # 分支名。eg:master
12 | sha: String, # git 提交记录中 sha 值。eg:51b1acb1b4044fcdb2ff8a75ad15a4b655101754
13 | user: *user, # 分支所在仓库的所有者信息
14 | repo: *project # 分支所在仓库的信息
15 | */
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Commit.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Commit {
4 | public String id;
5 | public String tree_id;
6 | public String[] parent_ids;
7 | public String message;
8 | public String timestamp;
9 | public String url;
10 | public User author;
11 | public User committer;
12 | public boolean distinct;
13 | public String[] added;
14 | public String[] removed;
15 | public String[] modified;
16 | // id: String,
17 | // tree_id: String, # commit tree oid。eg:db78f3594ec0683f5d857ef731df0d860f14f2b2
18 | // parent_ids: [String], # commit parent_ids。eg:['a3bddf21a35af54348aae5b0f5627e6ba35be51c']
19 | // message: String, # commit 的信息。eg:fix(cache): 修复了缓存问题
20 | // timestamp: String, # commit 的时间。eg:2020-01-01T00:00:00+08:00
21 | // url: String, # commit 对应的 Gitee url。eg:https://gitee.com/mayun-team/oauth2_dingtalk/commit/664b34859fc4a924cd60be2592c0fc788fbeaf8f
22 | // author: *user, # 作者信息。
23 | // committer: *user, # 提交者信息。
24 | // distinct: Boolean, # 特殊的 commit,没任何改动,如 tag
25 | // added: [String] || null, # 新加入的文件名。eg:['README.md']
26 | // removed: [String] || null, # 被移除的文件名。eg:['README.md']
27 | // modified: [String] || null # 修改过的文件名。eg:['README.md']
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Enterprise.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Enterprise {
4 | public String name;
5 | public String url;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Issue.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Issue {
4 | public String html_url;
5 | public long id;
6 | public String number;
7 | public String title;
8 | public User user;
9 | public Label[] labels;
10 | public String state;
11 | public String state_name;
12 | public String type_name;
13 | public User assignee;
14 | public User[] collaborators;
15 | public Milestone milestone;
16 | public int comments;
17 | public String created_at;
18 | public String updated_at;
19 | public String body;
20 | /*
21 | html_url: String, # Gitee 上对应的 url。eg:https://gitee.com/oschina/git-osc/issues/1
22 | id: Number,
23 | number: String, # issue 对应的标识。eg:IG6E9
24 | title: String, # issue 标题。eg:这是一个 issue 标题
25 | user: *user, # issue 创建者。
26 | labels: [*label] || null, # issue 对应的标签。
27 | state: String, # issue 状态。eg:open
28 | state_name: String, # issue 状态名。eg:代办的
29 | type_name: String, # issue 类型。eg:任务
30 | assignee: *user || null, # issue 负责人。
31 | collaborators: [*user] || null, # issue 协助者。
32 | milestone: *milestone || null, # issue 所属的里程碑。
33 | comments: Number, # issue 的评论总数
34 | created_at: String, # issue 的创建时间。eg:2020-01-01T00:00:00+08:00
35 | updated_at: String, # issue 的更新时间。eg:2020-01-01T00:00:00+08:00
36 | body: String # issue 的内容体。eg:数据库优化...
37 | */
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/IssueHook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | public class IssueHook {
6 | public String hook_url;
7 | public String hook_name;
8 | public String password;
9 | public long timestamp;
10 | public String sign;
11 | public String action;
12 | public Issue issue;
13 | public Project repository;
14 | public Project project;
15 | public User sender;
16 | public User target_user;
17 | public User assignee;
18 | public User updated_by;
19 | public String iid;
20 | public String title;
21 | public String description;
22 | public String state;
23 | public String milestone;
24 | public String url;
25 | public Enterprise enterprise;
26 | /*
27 | hook_id: self.id, # 钩子 id。
28 | hook_url: hook_url, # 钩子路由。
29 | hook_name: String, # 钩子名,固定为 issue_hooks。
30 | password: String, # 钩子密码。eg:123456
31 | timestamp: Number, # 触发钩子的时间戳。eg: 1576754827988
32 | sign: String, # 钩子根据密钥计算的签名。eg: "rLEHLuZRIQHuTPeXMib9Czoq9dVXO4TsQcmQQHtjXHA="
33 | action: String, # issue 状态。eg:open
34 | issue: *issue, # issue 信息。
35 | repository: *project || null, # 仓库信息。
36 | project: *project || null, # 仓库信息。
37 | sender: *user, # 触发 hook 的用户信息。
38 | target_user: *user || null, # 被委托处理 issue 的用户信息。
39 | user: *user, # issue 创建者。
40 | assignee: *user || null, # issue 负责人。
41 | updated_by: *user, # 触发 hook 的用户信息。
42 | iid: String, # issue 对应的标识。eg:IG6E9
43 | title: String, # issue 标题。eg:这是一个 issue 标题
44 | description: String, # issue 的内容体。eg:数据库优化...
45 | state: String, # issue 状态。eg:open
46 | milestone: String || null, # 里程碑的标题。eg:开源计划
47 | url: String, # issue 在 Gitee 上对应的 url。eg:https://gitee.com/oschina/git-osc/issues/1
48 | enterprise: *enterprise || null # issue 所属的企业信息。
49 | */
50 | public static void main(String[] var0) {
51 | String str = "{\"action\":\"open\",\"issue\":{\"html_url\":\"https://gitee.com/heavyrain2012/test/issues/I35DB8\",\"id\":5289380,\"number\":\"I35DB8\",\"title\":\"test\",\"user\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"labels\":[],\"state\":\"open\",\"state_name\":\"待办的\",\"type_name\":\"任务\",\"assignee\":null,\"collaborators\":[],\"milestone\":null,\"comments\":0,\"created_at\":\"2021-02-03T16:07:03+08:00\",\"updated_at\":\"2021-02-03T16:07:03+08:00\",\"body\":\"### 该问题是怎么引起的?\\r\\n\\r\\n\\r\\n\\r\\n### 重现步骤\\r\\n\\r\\n\\r\\n\\r\\n### 报错信息\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\"},\"repository\":{\"id\":14074728,\"name\":\"test\",\"path\":\"test\",\"full_name\":\"heavyrain2012/test\",\"owner\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"private\":false,\"html_url\":\"https://gitee.com/heavyrain2012/test\",\"url\":\"https://gitee.com/heavyrain2012/test\",\"description\":\"test\",\"fork\":false,\"created_at\":\"2021-02-03T14:44:33+08:00\",\"updated_at\":\"2021-02-03T14:44:34+08:00\",\"pushed_at\":\"2021-02-03T14:44:34+08:00\",\"git_url\":\"git://gitee.com/heavyrain2012/test.git\",\"ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"clone_url\":\"https://gitee.com/heavyrain2012/test.git\",\"svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"git_http_url\":\"https://gitee.com/heavyrain2012/test.git\",\"git_ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"git_svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"homepage\":null,\"stargazers_count\":0,\"watchers_count\":1,\"forks_count\":0,\"language\":\"Java\",\"has_issues\":true,\"has_wiki\":true,\"has_pages\":false,\"license\":\"MIT\",\"open_issues_count\":1,\"default_branch\":\"master\",\"namespace\":\"heavyrain2012\",\"name_with_namespace\":\"heavyrain2012/test\",\"path_with_namespace\":\"heavyrain2012/test\"},\"project\":{\"id\":14074728,\"name\":\"test\",\"path\":\"test\",\"full_name\":\"heavyrain2012/test\",\"owner\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"private\":false,\"html_url\":\"https://gitee.com/heavyrain2012/test\",\"url\":\"https://gitee.com/heavyrain2012/test\",\"description\":\"test\",\"fork\":false,\"created_at\":\"2021-02-03T14:44:33+08:00\",\"updated_at\":\"2021-02-03T14:44:34+08:00\",\"pushed_at\":\"2021-02-03T14:44:34+08:00\",\"git_url\":\"git://gitee.com/heavyrain2012/test.git\",\"ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"clone_url\":\"https://gitee.com/heavyrain2012/test.git\",\"svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"git_http_url\":\"https://gitee.com/heavyrain2012/test.git\",\"git_ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"git_svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"homepage\":null,\"stargazers_count\":0,\"watchers_count\":1,\"forks_count\":0,\"language\":\"Java\",\"has_issues\":true,\"has_wiki\":true,\"has_pages\":false,\"license\":\"MIT\",\"open_issues_count\":1,\"default_branch\":\"master\",\"namespace\":\"heavyrain2012\",\"name_with_namespace\":\"heavyrain2012/test\",\"path_with_namespace\":\"heavyrain2012/test\"},\"sender\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"target_user\":null,\"user\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"assignee\":null,\"updated_by\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"iid\":\"I35DB8\",\"title\":\"test\",\"description\":\"### 该问题是怎么引起的?\\r\\n\\r\\n\\r\\n\\r\\n### 重现步骤\\r\\n\\r\\n\\r\\n\\r\\n### 报错信息\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\",\"state\":\"open\",\"milestone\":null,\"url\":\"https://gitee.com/heavyrain2012/test/issues/I35DB8\",\"enterprise\":null,\"hook_name\":\"issue_hooks\",\"hook_id\":548608,\"hook_url\":\"https://gitee.com/heavyrain2012/test/hooks/548608/edit\",\"password\":\"\",\"timestamp\":\"1612339623863\",\"sign\":\"\"}";
52 | IssueHook noteHook = new Gson().fromJson(str, IssueHook.class);
53 | System.out.println(noteHook.action);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Label.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Label {
4 | public long id;
5 | public String name;
6 | public String color;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Milestone.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Milestone {
4 | public String html_url;
5 | public long id;
6 | public long number;
7 | public String title;
8 | public String description;
9 | public int open_issues;
10 | public int closed_issues;
11 | public String state;
12 | public String created_at;
13 | public String updated_at;
14 | public String due_on;
15 | /*
16 | html_url: String, # Gitee 上对应的 url。eg:https://gitee.com/oschina/git-osc/milestones/1
17 | id: Number,
18 | number: Number, # 与上面的 id 一致
19 | title: String, # 里程碑的标题。eg:开源计划
20 | description: String || null, # 里程碑的详细描述。eg:走向世界
21 | open_issues: Number, # 开启状态的 issue 数量
22 | closed_issues: Number, # 关闭状态的 issue 数量
23 | state: String, # 里程碑的状态。eg:open
24 | created_at: String, # 里程碑创建的时间。eg:2020-01-01T00:00:00+08:00
25 | updated_at: String, # 里程碑更新的时间。eg:2020-01-01T00:00:00+08:00
26 | due_on: String || null # 里程碑结束的时间。eg:2020-01-01T00:00:00+08:00
27 | */
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Note.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Note {
4 | public long id;
5 | public String body;
6 | public User user;
7 | public String created_at;
8 | public String updated_at;
9 | public String html_url;
10 | public String position;
11 | public String commit_id;
12 | // id: Number,
13 | // body: String, # 评论内容。eg:好的东西应该开源...
14 | // user: *user, # 评论的作者信息。
15 | // created_at: String, # 评论的创建时间。eg:2020-01-01T00:00:00+08:00
16 | // updated_at: String, # 评论的更新时间。eg:2020-11-11T11:11:11+08:00
17 | // html_url: String, # 这条评论在 Gitee 上的 url。eg:https://gitee.com/oschina/git-osc#note_1
18 | // [position: String], # 在代码 commit 评论中对应的代码位置。eg:76ec1c6df700af34ae5f8dd00bd7bcb56c1bd706_9_9
19 | // [commit_id: String] # 在代码 commit 评论中对应的 commit id。eg:611de62f634d353bb75a290f59fa238ff2d8d3c7
20 | //}
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/NoteHook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | public class NoteHook {
6 | public String hook_url;
7 | public String hook_name;
8 | public String password;
9 | public long timestamp;
10 | public String sign;
11 | public String action;
12 | public Commit commit;
13 | public Project repository;
14 | public Project project;
15 | public User author;
16 | public User sender;
17 | public String url;
18 | public String note;
19 | public String noteable_type;
20 | public long noteable_id;
21 | public Issue issue;
22 | public PullRequest pullRequest;
23 | public String title;
24 | public String per_iid;
25 | public String short_commit_id;
26 | public Enterprise enterprise;
27 | /*
28 | hook_id: self.id, # 钩子 id。
29 | hook_url: hook_url, # 钩子路由。
30 | hook_name: String, # 钩子名,固定为 note_hooks。
31 | password: String, # 钩子密码。eg:123456
32 | timestamp: Number, # 触发钩子的时间戳。eg: 1576754827988
33 | sign: String, # 钩子根据密钥计算的签名。eg: "rLEHLuZRIQHuTPeXMib9Czoq9dVXO4TsQcmQQHtjXHA="
34 | action: String, # 评论的动作。eg:comment
35 | comment: *note, # 评论的数据信息。
36 | repository: *project || null, # 评论所在仓库的信息。
37 | project: *project || null, # 评论所在仓库的信息。
38 | author: *user, # 评论的作者信息。
39 | sender: *user, # 评论的作者信息。
40 | url: String, # 这条评论在 Gitee 上的 url。eg:https://gitee.com/oschina/git-osc#note_1
41 | note: String, # 评论内容。eg:好的东西应该开源...
42 | noteable_type: String, # 被评论的目标类型。eg:Issue
43 | noteable_id: Number, # 被评论的目标 id。
44 | [issue: *issue], # 被评论的 Issue 信息。
45 | [pull_request: *pull_request], # 被评论的 PR 信息。
46 | title: String || null, # 被评论的目标标题。eg:这是一个 PR 标题
47 | per_iid: String, # 被评论的目标标识。eg:IG6E9
48 | short_commit_id: String || null, # 被平路的 commit 提交中的简短 sha。eg:51b1acb
49 | enterprise: *enterprise || null # 被评论的目标所在的企业信息。
50 | */
51 | public static void main(String[] var0) {
52 | String str = "{\"action\":\"comment\",\"comment\":{\"id\":4227147,\"body\":\"aksdjfklads\",\"user\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"created_at\":\"2021-02-03T16:10:05+08:00\",\"updated_at\":\"2021-02-03T16:10:05+08:00\",\"html_url\":\"https://gitee.com/heavyrain2012/test/issues/I35DB8#note_4227147\"},\"repository\":{\"id\":14074728,\"name\":\"test\",\"path\":\"test\",\"full_name\":\"heavyrain2012/test\",\"owner\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"private\":false,\"html_url\":\"https://gitee.com/heavyrain2012/test\",\"url\":\"https://gitee.com/heavyrain2012/test\",\"description\":\"test\",\"fork\":false,\"created_at\":\"2021-02-03T14:44:33+08:00\",\"updated_at\":\"2021-02-03T16:07:03+08:00\",\"pushed_at\":\"2021-02-03T14:44:34+08:00\",\"git_url\":\"git://gitee.com/heavyrain2012/test.git\",\"ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"clone_url\":\"https://gitee.com/heavyrain2012/test.git\",\"svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"git_http_url\":\"https://gitee.com/heavyrain2012/test.git\",\"git_ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"git_svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"homepage\":null,\"stargazers_count\":0,\"watchers_count\":1,\"forks_count\":0,\"language\":\"Java\",\"has_issues\":true,\"has_wiki\":true,\"has_pages\":false,\"license\":\"MIT\",\"open_issues_count\":1,\"default_branch\":\"master\",\"namespace\":\"heavyrain2012\",\"name_with_namespace\":\"heavyrain2012/test\",\"path_with_namespace\":\"heavyrain2012/test\"},\"project\":{\"id\":14074728,\"name\":\"test\",\"path\":\"test\",\"full_name\":\"heavyrain2012/test\",\"owner\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"private\":false,\"html_url\":\"https://gitee.com/heavyrain2012/test\",\"url\":\"https://gitee.com/heavyrain2012/test\",\"description\":\"test\",\"fork\":false,\"created_at\":\"2021-02-03T14:44:33+08:00\",\"updated_at\":\"2021-02-03T16:07:03+08:00\",\"pushed_at\":\"2021-02-03T14:44:34+08:00\",\"git_url\":\"git://gitee.com/heavyrain2012/test.git\",\"ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"clone_url\":\"https://gitee.com/heavyrain2012/test.git\",\"svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"git_http_url\":\"https://gitee.com/heavyrain2012/test.git\",\"git_ssh_url\":\"git@gitee.com:heavyrain2012/test.git\",\"git_svn_url\":\"svn://gitee.com/heavyrain2012/test\",\"homepage\":null,\"stargazers_count\":0,\"watchers_count\":1,\"forks_count\":0,\"language\":\"Java\",\"has_issues\":true,\"has_wiki\":true,\"has_pages\":false,\"license\":\"MIT\",\"open_issues_count\":1,\"default_branch\":\"master\",\"namespace\":\"heavyrain2012\",\"name_with_namespace\":\"heavyrain2012/test\",\"path_with_namespace\":\"heavyrain2012/test\"},\"author\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"sender\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"url\":\"https://gitee.com/heavyrain2012/test/issues/I35DB8#note_4227147\",\"note\":\"aksdjfklads\",\"noteable_type\":\"Issue\",\"noteable_id\":5289380,\"title\":\"test\",\"per_iid\":\"#I35DB8\",\"short_commit_id\":\"\",\"enterprise\":null,\"issue\":{\"html_url\":\"https://gitee.com/heavyrain2012/test/issues/I35DB8\",\"id\":5289380,\"number\":\"I35DB8\",\"title\":\"test\",\"user\":{\"id\":8657970,\"name\":\"heavyrain2012\",\"email\":\"8657970+heavyrain2012@user.noreply.gitee.com\",\"username\":\"heavyrain2012\",\"user_name\":\"heavyrain2012\",\"url\":\"https://gitee.com/heavyrain2012\",\"login\":\"heavyrain2012\",\"avatar_url\":\"https://gitee.com/assets/no_portrait.png\",\"html_url\":\"https://gitee.com/heavyrain2012\",\"type\":\"User\",\"site_admin\":false},\"labels\":[],\"state\":\"open\",\"state_name\":\"待办的\",\"type_name\":\"任务\",\"assignee\":null,\"collaborators\":[],\"milestone\":null,\"comments\":1,\"created_at\":\"2021-02-03T16:07:03+08:00\",\"updated_at\":\"2021-02-03T16:10:05+08:00\",\"body\":\"### 该问题是怎么引起的?\\r\\n\\r\\n\\r\\n\\r\\n### 重现步骤\\r\\n\\r\\n\\r\\n\\r\\n### 报错信息\\r\\n\\r\\n\\r\\n\\r\\n\\r\\n\"},\"hook_name\":\"note_hooks\",\"hook_id\":548608,\"hook_url\":\"https://gitee.com/heavyrain2012/test/hooks/548608/edit\",\"password\":\"\",\"timestamp\":\"1612339806012\",\"sign\":\"\"}";
53 | NoteHook noteHook = new Gson().fromJson(str, NoteHook.class);
54 | System.out.println(noteHook.action);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/Project.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class Project {
4 | public long id;
5 | public String name;
6 | public String path;
7 | public String full_name;
8 | public User owner;
9 | // public boolean private;
10 | public String html_url;
11 | public String url;
12 | public String description;
13 | public boolean fork;
14 | public String created_at;
15 | public String updated_at;
16 | public String pushed_at;
17 | public String git_url;
18 | public String ssh_url;
19 | public String clone_url;
20 | public String svn_url;
21 | public String git_http_url;
22 | public String git_ssh_url;
23 | public String git_svn_ur;
24 | public String homepage;
25 | public int stargazers_count;
26 | public int watchers_count;
27 | public int forks_count;
28 | public String language;
29 | public boolean has_issues;
30 | public boolean has_wiki;
31 | public boolean has_pages;
32 | public String license;
33 | public int open_issues_count;
34 | public String default_branch;
35 | public String namespace;
36 | public String name_with_namespace;
37 | public String path_with_namespace;
38 | /*
39 | id: Number,
40 | name: String, # 仓库名。eg:gitee
41 | path: String, # 仓库所属的空间地址。eg:oschian
42 | full_name: String, # 完整的名字,name + path。eg:gitee/oschian
43 | owner: *user, # 仓库的所有者。
44 | private: Boolean, # 是否公开。
45 | html_url: String, # 对应 Gitee 的 url。eg:https://gitee.com/oschina/git-osc
46 | url: String, # 与上面 html_url 一致
47 | description: String, # 仓库描述。eg:这是一个开源仓库...
48 | fork: Boolean, # 是不是 fork 仓库。
49 | created_at: String, # 仓库的创建时间。eg:2020-01-01T00:00:00+08:00
50 | updated_at: String, # 仓库的更新时间。eg:2020-01-01T00:00:00+08:00
51 | pushed_at: String, # 仓库的最近一次推送时间。eg:2020-01-01T00:00:00+08:00
52 | git_url: String, # 仓库的 git 地址。eg:git://gitee.com:oschina/git-osc.git
53 | ssh_url: String, # 仓库的 ssh 地址。eg:git@gitee.com:oschina/git-osc.git
54 | clone_url: String, # 仓库的 clone 地址。eg:https://gitee.com/oschina/git-osc.git
55 | svn_url: String, # 仓库的 svn 地址。eg:svn://gitee.com/oschina/git-osc
56 | git_http_url: String, # 与上面的 clone_url 一致。
57 | git_ssh_url: String, # 与上面的 ssh_url 一致。
58 | git_svn_url: String, # 与上面的 svn_url 一致。
59 | homepage: String || null, # 仓库的网页主页。eg:https://gitee.com
60 | stargazers_count: Number, # 仓库的 star 数量。
61 | watchers_count: Number, # 仓库的 watch 数量。
62 | forks_count: Number, # 仓库的 fork 数量。
63 | language: String, # 仓库的编程语言。eg: Ruby
64 | has_issues: Boolean, # 仓库的是否开启了 issue 功能。
65 | has_wiki: Boolean, # 仓库的是否开启了 wiki 功能。
66 | has_pages: Boolean, # 仓库的是否开启了 page 服务。
67 | license: String || null, # 仓库的开源协议。eg:MIT
68 | open_issues_count: Number, # 仓库开启状态的 issue 总数。
69 | default_branch: String, # 仓库的默认复制。eg:master
70 | namespace: String, # 仓库所属的 Gitee 地址。eg:oschina
71 | name_with_namespace: String, # 与上面的 full_name 一致。
72 | path_with_namespace: String # 仓库的在 Gitee 的资源唯一标识。eg:oschia/git-osc
73 | */
74 | }
75 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/PullRequest.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class PullRequest {
4 | public long id;
5 | public long number;
6 | public String state;
7 | public String html_url;
8 | public String diff_url;
9 | public String patch_url;
10 | public String title;
11 | public String body;
12 | public String created_at;
13 | public String updated_at;
14 | public String closed_at;
15 | public String merged_at;
16 | public String merge_commit_sha;
17 | public String merge_refreence_name;
18 | public User user;
19 | public User assignee;
20 | public User[] assignees;
21 | public User tester;
22 | public User[] testers;
23 | public boolean need_test;
24 | public boolean need_review;
25 | public Milestone milestone;
26 | public Branch head;
27 | public Branch base;
28 | public boolean merged;
29 | public boolean mergeable;
30 | public String merge_status;
31 | public User updated_by;
32 | public int comments;
33 | public int commits;
34 | public int additions;
35 | public int deletions;
36 | public int changed_files;
37 | /*id: Number,
38 | number: Number, # 与上面 id 一致
39 | state: String, # PR 状态。eg:open
40 | html_url: String, # PR 在 Gitee 上 url。eg:https://gitee.com/oschina/pulls/1
41 | diff_url: String, # PR diff 信息 url。eg:https://gitee.com/oschina/pulls/1.diff
42 | patch_url: String, # PR patch 信息 url。eg:https://gitee.com/oschina/pulls/1.patch
43 | title: String, # PR 的标题。eg:这是一个 PR 标题
44 | body: String || null, # PR 的内容。eg:升级服务...
45 | created_at: String, # PR 的创建时间。eg:2020-01-01T00:00:00+08:00
46 | updated_at: String, # PR 的更新时间。eg:2020-01-01T00:00:00+08:00
47 | closed_at: String || null, # PR 的关闭时间。eg:2020-01-01T00:00:00+08:00
48 | merged_at: String || null, # PR 的合并时间。eg:2020-01-01T00:00:00+08:00
49 | merge_commit_sha: String || null, # PR 合并产生的 commit id。eg:51b1acb1b4044fcdb2ff8a75ad15a4b655101754
50 | merge_reference_name: String, # PR 的源分支目标。eg:refs/pull/1/MERGE
51 | user: *user, # PR 的创建者。
52 | assignee: *user || null, # PR 的负责人。
53 | assignees: [*user] || null, # PR 的审核人。
54 | tester: *user || null, # PR 的测试者。
55 | testers: [*user] || null, # PR 的所有测试者。
56 | need_test: Boolean, # PR 是否需要测试。
57 | need_review: Boolean, # PR 是否需要审核。
58 | milestone: *milestone || null, # PR 所属的里程碑。
59 | head: *branch || null, # PR 的源分支。
60 | base: *branch, # PR 要合并的目标分支
61 | merged: Boolean, # PR 是否已合并。
62 | mergeable: Boolean, # PR 是否可以合并。
63 | merge_status: String, # PR 的合并状态。eg:unchecked
64 | updated_by: *user || null, # PR 的修改者。
65 | comments: Number, # PR 的总评论数量。
66 | commits: Number, # PR 的总 commit 数量。
67 | additions: Number, # PR 新增了多少行。
68 | deletions: Number, # PR 删除了多少行。
69 | changed_files: Number # PR 修改了多少行。
70 | */
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/PullRequestHook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class PullRequestHook {
4 | public String hook_url;
5 | public String hook_name;
6 | public String password;
7 | public long timestamp;
8 | public String sign;
9 | public String action;
10 | public PullRequest pull_request;
11 | public long number;
12 | public long iid;
13 | public String title;
14 | public String body;
15 | public String state;
16 | public String merge_status;
17 | public String merge_commit_sha;
18 | public String url;
19 | public String source_branch;
20 | public String target_branch;
21 | public Project project;
22 | public Project repository;
23 | public User author;
24 | public User updated_by;
25 | public User sender;
26 | public User target_user;
27 | public Enterprise enterprise;
28 | /*
29 | hook_id: self.id, # 钩子 id。
30 | hook_url: hook_url, # 钩子路由。
31 | hook_name: String, # 钩子名,固定为 merge_request_hooks。
32 | password: String, # 钩子密码。eg:123456
33 | timestamp: Number, # 触发钩子的时间戳。eg: 1576754827988
34 | sign: String, # 钩子根据密钥计算的签名。eg: "rLEHLuZRIQHuTPeXMib9Czoq9dVXO4TsQcmQQHtjXHA="
35 | action: String, # PR 状态。eg:open
36 | pull_request: *pull_request, # PR 的信息。
37 | number: Number, # PR 的 id。
38 | iid: Number, # 与上面 number 一致。
39 | title: String, # PR 的标题。eg:这是一个 PR 标题
40 | body: String || nil, # PR 的内容。eg:升级服务...
41 | state: String, # PR 状态。eg:open
42 | merge_status: String, # PR 的合并状态。eg:unchecked
43 | merge_commit_sha: String, # PR 合并产生的 commit id。eg:51b1acb1b4044fcdb2ff8a75ad15a4b655101754
44 | url: String, # PR 在 Gitee 上 url。eg:https://gitee.com/oschina/pulls/1
45 | source_branch: String || null, # PR 的源分支名。eg:fixbug
46 | source_repo: {
47 | project: *project, # PR 的源仓库信息。
48 | repository: *project # PR 的源仓库信息。
49 | } || null,
50 | target_branch: String, # PR 的目标分支名。master
51 | target_repo: {
52 | project: *project, # PR 的目标仓库信息。
53 | repository: *project # PR 的目标仓库信息。
54 | },
55 | project: *project, # PR 的目标仓库信息。
56 | repository: *project, # PR 的目标仓库信息。
57 | author: *user, # PR 的创建者信息。
58 | updated_by: *user, # PR 的更新者信息。
59 | sender: *user, # PR 的更新者信息。
60 | target_user: *user || null, # 被委托处理 PR 的用户信息。
61 | enterprise: *enterprise || null # PR 仓库所在的企业信息。
62 | */
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/PushOrTagHook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class PushOrTagHook {
4 | public String hook_url;
5 | public String hook_name;
6 | public String password;
7 | public long timestamp;
8 | public String sign;
9 | public String ref;
10 | public String before;
11 | public String after;
12 | public int total_commits_count;
13 | public boolean commits_more_than_ten;
14 | public boolean created;
15 | public boolean deleted;
16 | public String compare;
17 | public Commit[] commits;
18 | public Commit head_commit;
19 | public Project repository;
20 | public Project project;
21 | public long user_id;
22 | public String user_name;
23 | public User user;
24 | public User pusher;
25 | public User sender;
26 | public Enterprise enterprise;
27 | /*
28 | hook_id: self.id, # 钩子 id。
29 | hook_url: hook_url, # 钩子路由。
30 | hook_name: String, # 钩子名,固定为 push_hooks/tag_push_hooks。
31 | password: String, # 钩子密码。eg:123456
32 | timestamp: Number, # 触发钩子的时间戳。eg: 1576754827988
33 | sign: String, # 钩子根据密钥计算的签名。eg: "rLEHLuZRIQHuTPeXMib9Czoq9dVXO4TsQcmQQHtjXHA="
34 | ref: String, # 推送的分支。eg:refs/heads/master
35 | before: String, # 推送前分支的 commit id。eg:5221c062df39e9e477ab015df22890b7bf13fbbd
36 | after: String, # 推送后分支的 commit id。eg:1cdcd819599cbb4099289dbbec762452f006cb40
37 | [total_commits_count: Number], # 推送包含的 commit 总数。
38 | [commits_more_than_ten: Boolean], # 推送包含的 commit 总数是否大于十二。
39 | created: Boolean, # 推送的是否是新分支。
40 | deleted: Boolean, # 推送的是否是删除分支。
41 | compare: String, # 推送的 commit 差异 url。eg:https://gitee.com/oschina/git-osc/compare/5221c062df39e9e477ab015df22890b7bf13fbbd...1cdcd819599cbb4099289dbbec762452f006cb40
42 | commits: [*commit] || null, # 推送的全部 commit 信息。
43 | head_commit: commit, # 推送最前面的 commit 信息。
44 | repository: *project, # 推送的目标仓库信息。
45 | project: *project, # 推送的目标仓库信息。
46 | user_id: Number,
47 | user_name: String, # 推送者的昵称。
48 | user: *user, # 推送者的用户信息。
49 | pusher: *user, # 推送者的用户信息。
50 | sender: *user, # 推送者的用户信息。
51 | enterprise: *enterprise || ull # 推送的目标仓库所在的企业信息。
52 | */
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitee/pojo/User.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitee.pojo;
2 |
3 | public class User {
4 | public long id;
5 | public String name;
6 | public String email;
7 | public String username;
8 | public String user_name;
9 | public String url;
10 | public String login;
11 | public String avatar_url;
12 | public String html_url;
13 | public String type;
14 | public String site_admin;
15 | public String time;
16 | public String remark;
17 | // [id: Number],
18 | // name: String, # 用户的昵称。eg:红薯
19 | // email: String, # 用户的邮箱。eg:git@oschina.cn
20 | // [username: String], # 用户的 Gitee 个人空间地址。eg:gitee
21 | // [user_name: String], # 与上面的 username 一致。
22 | // [url: String], # 用户的 Gitee 个人主页 url。eg:https://gitee.com/gitee
23 | // [login: String], # 与上面的 username 一致。
24 | // [avatar_url: String || null], # 用户头像 url。eg:https://gitee.com/assets/favicon.ico
25 | // [html_url: String], # 与上面的 url 一致。
26 | // [type: String], # 用户类型,目前固定为 User。
27 | // [site_admin: Boolean], # 是不是管理员。
28 | // [time: String], # git commit 中的时间。eg:2020-01-01T00:00:00+08:00
29 | // [remark: String] # 用户备注名。eg:Ruby 大神
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/GithubWebhook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github;
2 |
3 | import cn.wildfirechat.app.webhook.IWebhook;
4 | import cn.wildfirechat.app.webhook.github.pojo.*;
5 | import cn.wildfirechat.pojos.MessagePayload;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 |
11 | public class GithubWebhook implements IWebhook {
12 | private static final Logger LOG = LoggerFactory.getLogger(GithubWebhook.class);
13 | @Override
14 | public String invokeCommand() {
15 | return "/github";
16 | }
17 |
18 | @Override
19 | public Object handleWebhookPost(HttpServletRequest request, String user, String githubPayload, SendMessageCallback callback) {
20 | String event = request.getHeader("X-GitHub-Event");
21 | LOG.info("on receive message {}", githubPayload);
22 |
23 | String message = null;
24 |
25 | MessagePayload messagePayload = new MessagePayload();
26 | messagePayload.setType(1);
27 | try {
28 | if (event.equals("push")) {
29 | PushEvent pushEvent = PushEvent.fromJson(githubPayload);
30 | message = "用户 " + pushEvent.pusher.name + " 在仓库 " + pushEvent.repository.full_name + " 提交了代码\n";
31 | for (Commit commit : pushEvent.commits) {
32 | message += "提交描述: " + commit.message + " 修改代码: " + commit.url + " \n";
33 | }
34 | } else if(event.equals("issues")) {
35 | IssueEvent issueEvent = IssueEvent.fromJson(githubPayload);
36 | message = "用户 " + issueEvent.sender.login + " 在仓库 " + issueEvent.repository.full_name + " " + issueEvent.action + " issue\n";
37 | message += issueEvent.issue.html_url + " \n";
38 | message += issueEvent.issue.title + " : " + issueEvent.issue.body;
39 | } else if(event.equals("star")) {
40 | StarEvent starEvent = StarEvent.fromJson(githubPayload);
41 | if (starEvent.action.equals("created")) {
42 | message = "用户 " + starEvent.sender.login + " star 了工程 " + starEvent.repository.full_name + " \n";
43 | } else {
44 | message = "用户 " + starEvent.sender.login + " unstar 了工程 " + starEvent.repository.full_name + " \n";
45 | }
46 | message += "现有star数: " + starEvent.repository.stargazers_count;
47 | } else if(event.equals("issue_comment")) {
48 | IssueCommentEvent issueCommentEvent = IssueCommentEvent.fromJson(githubPayload);
49 | if (issueCommentEvent.action.equals("created")) {
50 | message = "用户 " + issueCommentEvent.sender.login + " 评论了issue " + issueCommentEvent.repository.full_name + " : " + issueCommentEvent.issue.title + " \n";
51 | message += "内容: " + issueCommentEvent.comment.body + " \n";
52 | } else if (issueCommentEvent.action.equals("edited")) {
53 | message = "用户 " + issueCommentEvent.sender.login + " 修改了issue " + issueCommentEvent.repository.full_name + " : " + issueCommentEvent.issue.title + " 的评论\n";
54 | message += "修改内容: " + issueCommentEvent.comment.body + " \n";
55 | } else {
56 | message = "用户 " + issueCommentEvent.sender.login + " 删除了issue " + issueCommentEvent.repository.full_name + " 的评论\n";
57 | }
58 | message += "issue链接: " + issueCommentEvent.issue.html_url;
59 | } else if(event.equals("fork")) {
60 | ForkEvent forkEvent = ForkEvent.fromJson(githubPayload);
61 | if (forkEvent.forkee.fork) {
62 | message = "用户 " + forkEvent.sender.login + " fork 了工程 " + forkEvent.repository.full_name + " \n";
63 | } else {
64 | message = "用户 " + forkEvent.sender.login + " unfork 了工程 " + forkEvent.repository.full_name + " \n";
65 | }
66 | message += "现有star数: " + forkEvent.repository.stargazers_count + "。 现在的fork数: " + forkEvent.repository.forks_count;
67 | } else if(event.equals("watch")) {
68 | WatchEvent watchEvent = WatchEvent.fromJson(githubPayload);
69 | message = "用户 " + watchEvent.sender.login + " watch 了工程 " + watchEvent.repository.full_name + " \n";
70 | } else if(event.equals("ping")) {
71 | PingEvent pingEvent = PingEvent.fromJson(githubPayload);
72 | message = "Ping to " + pingEvent.repository.full_name;
73 | } else if(event.equals("pull_request")) {
74 | PullRequestEvent pullRequestEvent = PullRequestEvent.fromJson(githubPayload);
75 | message = "User " + pullRequestEvent.sender.login + " pull request:" + pullRequestEvent.repository.full_name + "。\nTitle:" + pullRequestEvent.pull_request.title + "\nbody:" + pullRequestEvent.pull_request.body + "\nurl:" + pullRequestEvent.pull_request.html_url;
76 | }
77 | } catch (Exception e) {
78 | e.printStackTrace();
79 | messagePayload.setSearchableContent("糟糕,处理github事件出错了:" + e.getMessage());
80 | callback.sendMessage(messagePayload);
81 | }
82 |
83 | if (message == null) {
84 | messagePayload.setSearchableContent("你收到了一个github事件:" + event);
85 | callback.sendMessage(messagePayload);
86 | messagePayload.setSearchableContent(githubPayload);
87 | callback.sendMessage(messagePayload);
88 | } else {
89 | messagePayload.setSearchableContent(message);
90 | callback.sendMessage(messagePayload);
91 | }
92 | return "ok";
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Comment.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class Comment {
4 | public String url;
5 | public String html_url;
6 | public String issue_url;
7 | public long id;
8 | public String node_id;
9 | public User user;
10 | public String body;
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Commit.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import java.util.Date;
4 |
5 | public class Commit {
6 | public String id;
7 | public String tree_id;
8 | public Date timestamp;
9 | public String sha;
10 | public String message;
11 | public Pusher author;
12 | public String url;
13 | public boolean distinct;
14 | public String[] added;
15 | public String[] removed;
16 | public String[] modified;
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/ForkEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | public class ForkEvent {
6 | public Forkee forkee;
7 | public Repository repository;
8 | public User sender;
9 |
10 | public static ForkEvent fromJson(String jsonStr) {
11 | return new Gson().fromJson(jsonStr, ForkEvent.class);
12 | }
13 | public static void main(String[] args) {
14 | String event1 = "{\"forkee\":{\"id\":242609213,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyNDI2MDkyMTM=\",\"name\":\"server\",\"full_name\":\"yangwugui/server\",\"private\":false,\"owner\":{\"login\":\"yangwugui\",\"id\":9507380,\"node_id\":\"MDQ6VXNlcjk1MDczODA=\",\"avatar_url\":\"https://avatars3.githubusercontent.com/u/9507380?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/yangwugui\",\"html_url\":\"https://github.com/yangwugui\",\"followers_url\":\"https://api.github.com/users/yangwugui/followers\",\"following_url\":\"https://api.github.com/users/yangwugui/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/yangwugui/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/yangwugui/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/yangwugui/subscriptions\",\"organizations_url\":\"https://api.github.com/users/yangwugui/orgs\",\"repos_url\":\"https://api.github.com/users/yangwugui/repos\",\"events_url\":\"https://api.github.com/users/yangwugui/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/yangwugui/received_events\",\"type\":\"User\",\"site_admin\":false},\"html_url\":\"https://github.com/yangwugui/server\",\"description\":\"即时通讯(IM)系统\",\"fork\":true,\"url\":\"https://api.github.com/repos/yangwugui/server\",\"forks_url\":\"https://api.github.com/repos/yangwugui/server/forks\",\"keys_url\":\"https://api.github.com/repos/yangwugui/server/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/yangwugui/server/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/yangwugui/server/teams\",\"hooks_url\":\"https://api.github.com/repos/yangwugui/server/hooks\",\"issue_events_url\":\"https://api.github.com/repos/yangwugui/server/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/yangwugui/server/events\",\"assignees_url\":\"https://api.github.com/repos/yangwugui/server/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/yangwugui/server/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/yangwugui/server/tags\",\"blobs_url\":\"https://api.github.com/repos/yangwugui/server/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/yangwugui/server/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/yangwugui/server/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/yangwugui/server/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/yangwugui/server/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/yangwugui/server/languages\",\"stargazers_url\":\"https://api.github.com/repos/yangwugui/server/stargazers\",\"contributors_url\":\"https://api.github.com/repos/yangwugui/server/contributors\",\"subscribers_url\":\"https://api.github.com/repos/yangwugui/server/subscribers\",\"subscription_url\":\"https://api.github.com/repos/yangwugui/server/subscription\",\"commits_url\":\"https://api.github.com/repos/yangwugui/server/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/yangwugui/server/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/yangwugui/server/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/yangwugui/server/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/yangwugui/server/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/yangwugui/server/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/yangwugui/server/merges\",\"archive_url\":\"https://api.github.com/repos/yangwugui/server/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/yangwugui/server/downloads\",\"issues_url\":\"https://api.github.com/repos/yangwugui/server/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/yangwugui/server/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/yangwugui/server/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/yangwugui/server/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/yangwugui/server/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/yangwugui/server/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/yangwugui/server/deployments\",\"created_at\":\"2020-02-23T23:40:41Z\",\"updated_at\":\"2020-02-23T03:38:30Z\",\"pushed_at\":\"2020-02-21T03:20:03Z\",\"git_url\":\"git://github.com/yangwugui/server.git\",\"ssh_url\":\"git@github.com:yangwugui/server.git\",\"clone_url\":\"https://github.com/yangwugui/server.git\",\"svn_url\":\"https://github.com/yangwugui/server\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":8928,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":false,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":0,\"license\":{\"key\":\"other\",\"name\":\"Other\",\"spdx_id\":\"NOASSERTION\",\"url\":null,\"node_id\":\"MDc6TGljZW5zZTA=\"},\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\",\"public\":true},\"repository\":{\"id\":167204613,\"node_id\":\"MDEwOlJlcG9zaXRvcnkxNjcyMDQ2MTM=\",\"name\":\"server\",\"full_name\":\"wildfirechat/server\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/server\",\"description\":\"即时通讯(IM)系统\",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/server\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/server/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/server/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/server/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/server/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/server/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/server/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/server/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/server/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/server/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/server/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/server/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/server/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/server/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/server/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/server/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/server/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/server/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/server/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/server/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/server/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/server/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/server/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/server/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/server/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/server/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/server/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/server/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/server/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/server/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/server/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/server/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/server/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/server/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/server/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/server/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/server/deployments\",\"created_at\":\"2019-01-23T15:21:28Z\",\"updated_at\":\"2020-02-23T03:38:30Z\",\"pushed_at\":\"2020-02-21T03:20:03Z\",\"git_url\":\"git://github.com/wildfirechat/server.git\",\"ssh_url\":\"git@github.com:wildfirechat/server.git\",\"clone_url\":\"https://github.com/wildfirechat/server.git\",\"svn_url\":\"https://github.com/wildfirechat/server\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":8928,\"stargazers_count\":4694,\"watchers_count\":4694,\"language\":\"Java\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":1040,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":14,\"license\":{\"key\":\"other\",\"name\":\"Other\",\"spdx_id\":\"NOASSERTION\",\"url\":null,\"node_id\":\"MDc6TGljZW5zZTA=\"},\"forks\":1040,\"open_issues\":14,\"watchers\":4694,\"default_branch\":\"wildfirechat\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"yangwugui\",\"id\":9507380,\"node_id\":\"MDQ6VXNlcjk1MDczODA=\",\"avatar_url\":\"https://avatars3.githubusercontent.com/u/9507380?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/yangwugui\",\"html_url\":\"https://github.com/yangwugui\",\"followers_url\":\"https://api.github.com/users/yangwugui/followers\",\"following_url\":\"https://api.github.com/users/yangwugui/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/yangwugui/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/yangwugui/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/yangwugui/subscriptions\",\"organizations_url\":\"https://api.github.com/users/yangwugui/orgs\",\"repos_url\":\"https://api.github.com/users/yangwugui/repos\",\"events_url\":\"https://api.github.com/users/yangwugui/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/yangwugui/received_events\",\"type\":\"User\",\"site_admin\":false}}";
15 | ForkEvent forkEvent = fromJson(event1);
16 | System.out.println(forkEvent.forkee.fork);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Forkee.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class Forkee {
4 | public long id;
5 | public String node_id;
6 | public String name;
7 | public String full_name;
8 | public User owner;
9 | public String html_url;
10 | public String description;
11 | public boolean fork;
12 | public String url;
13 | public String forks_url;
14 | public String keys_url;
15 | public String collaborators_url;
16 | public String teams_url;
17 | public String hooks_url;
18 | public String issue_events_url;
19 | public String events_url;
20 | public String assignees_url;
21 | public String branches_url;
22 | public String tags_url;
23 | public String blobs_url;
24 | public String git_tags_url;
25 | public String git_refs_url;
26 | public String trees_url;
27 | public String statuses_url;
28 | public String languages_url;
29 | public String stargazers_url;
30 | public String contributors_url;
31 | public String subscribers_url;
32 | public String subscription_url;
33 | public String commits_url;
34 | public String git_commits_url;
35 | public String comments_url;
36 | public String issue_comment_url;
37 | public String contents_url;
38 | public String compare_url;
39 | public String merges_url;
40 | public String archive_url;
41 | public String downloads_url;
42 | public String issues_url;
43 | public String pulls_url;
44 | public String milestones_url;
45 | public String notifications_url;
46 | public String labels_url;
47 | public String releases_url;
48 | public String deployments_url;
49 | public String git_url;
50 | public String ssh_url;
51 | public String clone_url;
52 | public String svn_url;
53 | public String homepage;
54 | public int size;
55 | public int stargazers_count;
56 | public int watchers_count;
57 | public String language;
58 | public boolean has_issues;
59 | public boolean has_projects;
60 | public boolean has_downloads;
61 | public boolean has_wiki;
62 | public boolean has_pages;
63 | public int forks_count;
64 | public String mirror_url;
65 | public boolean archived;
66 | public boolean disabled;
67 | public int open_issues_count;
68 | public License license;
69 | public int forks;
70 | public int open_issues;
71 | public int watchers;
72 | public String default_branch;
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Issue.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import java.util.Date;
4 |
5 | public class Issue {
6 | public String url;
7 | public String repository_url;
8 | public String labels_url;
9 | public String comments_url;
10 | public String events_url;
11 | public String html_url;
12 | public String id;
13 | public String node_id;
14 | public String number;
15 | public String title;
16 | public User user;
17 | public String state;
18 | public boolean locked;
19 | public String assignee;
20 | public String[] assignees;
21 | public String milestone;
22 | public int comments;
23 | public Date created_at;
24 | public Date updated_at;
25 | public Date closed_at;
26 | public String author_association;
27 | public String body;
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/IssueCommentEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | //https://developer.github.com/v3/activity/events/types/#issuecommentevent
6 | public class IssueCommentEvent {
7 | //The action that was performed on the comment. Can be one of created, edited, or deleted.
8 | public String action;
9 | public Issue issue;
10 | public Comment comment;
11 | public Repository repository;
12 | public User sender;
13 |
14 | public static IssueCommentEvent fromJson(String jsonStr) {
15 | IssueCommentEvent issueCommentEvent = new Gson().fromJson(jsonStr, IssueCommentEvent.class);
16 | return issueCommentEvent;
17 | }
18 |
19 | public static void main(String[] args) {
20 | String event1 = "{\"action\":\"created\",\"issue\":{\"url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/1\",\"repository_url\":\"https://api.github.com/repos/wildfirechat/github_webhook\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/1/labels{/name}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/1/comments\",\"events_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/1/events\",\"html_url\":\"https://github.com/wildfirechat/github_webhook/issues/1\",\"id\":569491189,\"node_id\":\"MDU6SXNzdWU1Njk0OTExODk=\",\"number\":1,\"title\":\"test issue\",\"user\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false},\"labels\":[],\"state\":\"open\",\"locked\":false,\"assignee\":null,\"assignees\":[],\"milestone\":null,\"comments\":0,\"created_at\":\"2020-02-23T12:57:10Z\",\"updated_at\":\"2020-02-23T14:04:17Z\",\"closed_at\":null,\"author_association\":\"CONTRIBUTOR\",\"body\":\"this is a test issue\"},\"comment\":{\"url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/comments/590072058\",\"html_url\":\"https://github.com/wildfirechat/github_webhook/issues/1#issuecomment-590072058\",\"issue_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/1\",\"id\":590072058,\"node_id\":\"MDEyOklzc3VlQ29tbWVudDU5MDA3MjA1OA==\",\"user\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false},\"created_at\":\"2020-02-23T14:04:17Z\",\"updated_at\":\"2020-02-23T14:04:17Z\",\"author_association\":\"CONTRIBUTOR\",\"body\":\"tttt\"},\"repository\":{\"id\":242506330,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyNDI1MDYzMzA=\",\"name\":\"github_webhook\",\"full_name\":\"wildfirechat/github_webhook\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/github_webhook\",\"description\":\"Github webhook robot applaciton\",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/github_webhook\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/github_webhook/deployments\",\"created_at\":\"2020-02-23T11:41:25Z\",\"updated_at\":\"2020-02-23T13:58:24Z\",\"pushed_at\":\"2020-02-23T13:58:22Z\",\"git_url\":\"git://github.com/wildfirechat/github_webhook.git\",\"ssh_url\":\"git@github.com:wildfirechat/github_webhook.git\",\"clone_url\":\"https://github.com/wildfirechat/github_webhook.git\",\"svn_url\":\"https://github.com/wildfirechat/github_webhook\",\"homepage\":null,\"size\":797,\"stargazers_count\":0,\"watchers_count\":0,\"language\":\"Java\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":1,\"license\":{\"key\":\"other\",\"name\":\"Other\",\"spdx_id\":\"NOASSERTION\",\"url\":null,\"node_id\":\"MDc6TGljZW5zZTA=\"},\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false}}";
21 | IssueCommentEvent issueCommentEvent = fromJson(event1);
22 | System.out.println(issueCommentEvent.action);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/IssueEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | //https://developer.github.com/v3/activity/events/types/#issuesevent
6 | public class IssueEvent {
7 | //The action that was performed. Can be one of opened, edited, deleted, pinned, unpinned, closed, reopened, assigned, unassigned, labeled, unlabeled, locked, unlocked, transferred, milestoned, or demilestoned.
8 | public String action;
9 | public Issue issue;
10 | public Repository repository;
11 | public Sender sender;
12 |
13 | public static IssueEvent fromJson(String jsonStr) {
14 | return new Gson().fromJson(jsonStr, IssueEvent.class);
15 | }
16 |
17 | public static void main(String[] args) {
18 | String event1 = "{\"action\":\"closed\",\"issue\":{\"url\":\"https://api.github.com/repos/wildfirechat/server/issues/257\",\"repository_url\":\"https://api.github.com/repos/wildfirechat/server\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/server/issues/257/labels{/name}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/server/issues/257/comments\",\"events_url\":\"https://api.github.com/repos/wildfirechat/server/issues/257/events\",\"html_url\":\"https://github.com/wildfirechat/server/issues/257\",\"id\":681562734,\"node_id\":\"MDU6SXNzdWU2ODE1NjI3MzQ=\",\"number\":257,\"title\":\"建议:用户在线状态回调希望回调所在包名称或当前登录的包唯一标识\",\"user\":{\"login\":\"zuoliang0\",\"id\":8434253,\"node_id\":\"MDQ6VXNlcjg0MzQyNTM=\",\"avatar_url\":\"https://avatars1.githubusercontent.com/u/8434253?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/zuoliang0\",\"html_url\":\"https://github.com/zuoliang0\",\"followers_url\":\"https://api.github.com/users/zuoliang0/followers\",\"following_url\":\"https://api.github.com/users/zuoliang0/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/zuoliang0/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/zuoliang0/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/zuoliang0/subscriptions\",\"organizations_url\":\"https://api.github.com/users/zuoliang0/orgs\",\"repos_url\":\"https://api.github.com/users/zuoliang0/repos\",\"events_url\":\"https://api.github.com/users/zuoliang0/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/zuoliang0/received_events\",\"type\":\"User\",\"site_admin\":false},\"labels\":[{\"id\":1205138170,\"node_id\":\"MDU6TGFiZWwxMjA1MTM4MTcw\",\"url\":\"https://api.github.com/repos/wildfirechat/server/labels/enhancement\",\"name\":\"enhancement\",\"color\":\"a2eeef\",\"default\":true,\"description\":\"New feature or request\"}],\"state\":\"closed\",\"locked\":false,\"assignee\":null,\"assignees\":[],\"milestone\":null,\"comments\":14,\"created_at\":\"2020-08-19T05:41:55Z\",\"updated_at\":\"2020-08-27T05:26:57Z\",\"closed_at\":\"2020-08-27T05:26:57Z\",\"author_association\":\"NONE\",\"active_lock_reason\":null,\"body\":\"回调在线状态这个需求也是我提出的,我们现在使用的是融云服务,计划在年底迁移到野火,目前正在做前期对接,后台对接时发现回调状态不包含当前所登录的包信息,希望能拿到这些信息。我们有多个app,用户可以在多个app之间登录。\",\"performed_via_github_app\":null},\"repository\":{\"id\":167204613,\"node_id\":\"MDEwOlJlcG9zaXRvcnkxNjcyMDQ2MTM=\",\"name\":\"server\",\"full_name\":\"wildfirechat/server\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/server\",\"description\":\"即时通讯(IM)系统\",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/server\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/server/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/server/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/server/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/server/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/server/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/server/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/server/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/server/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/server/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/server/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/server/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/server/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/server/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/server/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/server/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/server/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/server/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/server/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/server/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/server/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/server/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/server/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/server/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/server/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/server/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/server/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/server/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/server/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/server/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/server/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/server/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/server/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/server/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/server/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/server/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/server/deployments\",\"created_at\":\"2019-01-23T15:21:28Z\",\"updated_at\":\"2020-08-26T12:17:45Z\",\"pushed_at\":\"2020-08-25T13:04:59Z\",\"git_url\":\"git://github.com/wildfirechat/server.git\",\"ssh_url\":\"git@github.com:wildfirechat/server.git\",\"clone_url\":\"https://github.com/wildfirechat/server.git\",\"svn_url\":\"https://github.com/wildfirechat/server\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":9350,\"stargazers_count\":5330,\"watchers_count\":5330,\"language\":\"Java\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":1204,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":9,\"license\":{\"key\":\"other\",\"name\":\"Other\",\"spdx_id\":\"NOASSERTION\",\"url\":null,\"node_id\":\"MDc6TGljZW5zZTA=\"},\"forks\":1204,\"open_issues\":9,\"watchers\":5330,\"default_branch\":\"wildfirechat\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false}}";
19 | IssueEvent openedIssue = new Gson().fromJson(event1, IssueEvent.class);
20 | System.out.println(openedIssue.action);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/License.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class License {
4 | public String key;
5 | public String name;
6 | public String spdx_id;
7 | public String url;
8 | public String node_id;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/PingEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | //https://developer.github.com/v3/activity/events/types/#watchevent
6 | public class PingEvent {
7 | //The action that was performed. Currently, can only be started.
8 | public Repository repository;
9 | public User sender;
10 |
11 | public static PingEvent fromJson(String jsonStr) {
12 | return new Gson().fromJson(jsonStr, PingEvent.class);
13 | }
14 |
15 | public static void main(String[] args) {
16 | String event = "{\"zen\":\"Mind your words, they are important.\",\"hook_id\":245889670,\"hook\":{\"type\":\"Repository\",\"id\":245889670,\"name\":\"web\",\"active\":true,\"events\":[\"push\"],\"config\":{\"content_type\":\"json\",\"insecure_ssl\":\"0\",\"url\":\"http://wildfirechat.cn:8890/github/payload\"},\"updated_at\":\"2020-09-02T08:01:11Z\",\"created_at\":\"2020-09-02T08:01:11Z\",\"url\":\"https://api.github.com/repos/heavyrain2012/account_book/hooks/245889670\",\"test_url\":\"https://api.github.com/repos/heavyrain2012/account_book/hooks/245889670/test\",\"ping_url\":\"https://api.github.com/repos/heavyrain2012/account_book/hooks/245889670/pings\",\"last_response\":{\"code\":null,\"status\":\"unused\",\"message\":null}},\"repository\":{\"id\":196691777,\"node_id\":\"MDEwOlJlcG9zaXRvcnkxOTY2OTE3Nzc=\",\"name\":\"account_book\",\"full_name\":\"heavyrain2012/account_book\",\"private\":true,\"owner\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false},\"html_url\":\"https://github.com/heavyrain2012/account_book\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/heavyrain2012/account_book\",\"forks_url\":\"https://api.github.com/repos/heavyrain2012/account_book/forks\",\"keys_url\":\"https://api.github.com/repos/heavyrain2012/account_book/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/heavyrain2012/account_book/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/heavyrain2012/account_book/teams\",\"hooks_url\":\"https://api.github.com/repos/heavyrain2012/account_book/hooks\",\"issue_events_url\":\"https://api.github.com/repos/heavyrain2012/account_book/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/heavyrain2012/account_book/events\",\"assignees_url\":\"https://api.github.com/repos/heavyrain2012/account_book/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/heavyrain2012/account_book/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/heavyrain2012/account_book/tags\",\"blobs_url\":\"https://api.github.com/repos/heavyrain2012/account_book/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/heavyrain2012/account_book/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/heavyrain2012/account_book/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/heavyrain2012/account_book/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/heavyrain2012/account_book/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/heavyrain2012/account_book/languages\",\"stargazers_url\":\"https://api.github.com/repos/heavyrain2012/account_book/stargazers\",\"contributors_url\":\"https://api.github.com/repos/heavyrain2012/account_book/contributors\",\"subscribers_url\":\"https://api.github.com/repos/heavyrain2012/account_book/subscribers\",\"subscription_url\":\"https://api.github.com/repos/heavyrain2012/account_book/subscription\",\"commits_url\":\"https://api.github.com/repos/heavyrain2012/account_book/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/heavyrain2012/account_book/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/heavyrain2012/account_book/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/heavyrain2012/account_book/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/heavyrain2012/account_book/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/heavyrain2012/account_book/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/heavyrain2012/account_book/merges\",\"archive_url\":\"https://api.github.com/repos/heavyrain2012/account_book/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/heavyrain2012/account_book/downloads\",\"issues_url\":\"https://api.github.com/repos/heavyrain2012/account_book/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/heavyrain2012/account_book/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/heavyrain2012/account_book/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/heavyrain2012/account_book/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/heavyrain2012/account_book/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/heavyrain2012/account_book/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/heavyrain2012/account_book/deployments\",\"created_at\":\"2019-07-13T07:23:26Z\",\"updated_at\":\"2020-09-02T07:56:00Z\",\"pushed_at\":\"2020-09-02T07:55:58Z\",\"git_url\":\"git://github.com/heavyrain2012/account_book.git\",\"ssh_url\":\"git@github.com:heavyrain2012/account_book.git\",\"clone_url\":\"https://github.com/heavyrain2012/account_book.git\",\"svn_url\":\"https://github.com/heavyrain2012/account_book\",\"homepage\":null,\"size\":84,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":0,\"license\":null,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false}}";
17 | PingEvent watchEvent = fromJson(event);
18 | System.out.println("");
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/PullRequest.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import java.util.Date;
4 |
5 | public class PullRequest {
6 | public String html_url;
7 | public String id;
8 | public String node_id;
9 | public String number;
10 | public String title;
11 | public String body;
12 | public User user;
13 | public String state;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/PushEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | public class PushEvent {
6 | public String ref;
7 | public String before;
8 | public String after;
9 | public boolean created;
10 | public boolean deleted;
11 | public boolean forced;
12 | public String base_ref;
13 | public String compare;
14 | public Commit[] commits;
15 | public Commit head_commit;
16 | public Repository repository;
17 | public Pusher pusher;
18 | public Sender sender;
19 |
20 | public static PushEvent fromJson(String jsonStr) {
21 | return new Gson().fromJson(jsonStr, PushEvent.class);
22 | }
23 |
24 | public static void main(String[] args) {
25 | String event1 = "{\"ref\":\"refs/heads/master\",\"before\":\"0000000000000000000000000000000000000000\",\"after\":\"d7c02e15ef0f3eca28400bc92f2decbd6b9df2e0\",\"repository\":{\"id\":242506330,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyNDI1MDYzMzA=\",\"name\":\"github_webhoot\",\"full_name\":\"wildfirechat/github_webhoot\",\"private\":false,\"owner\":{\"name\":\"wildfirechat\",\"email\":\"heavyrain.lee@wildfirechat.cn\",\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/github_webhoot\",\"description\":\"Github webhook robot applaciton\",\"fork\":false,\"url\":\"https://github.com/wildfirechat/github_webhoot\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/github_webhoot/deployments\",\"created_at\":1582458085,\"updated_at\":\"2020-02-23T11:41:25Z\",\"pushed_at\":1582458469,\"git_url\":\"git://github.com/wildfirechat/github_webhoot.git\",\"ssh_url\":\"git@github.com:wildfirechat/github_webhoot.git\",\"clone_url\":\"https://github.com/wildfirechat/github_webhoot.git\",\"svn_url\":\"https://github.com/wildfirechat/github_webhoot\",\"homepage\":null,\"size\":0,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":0,\"license\":null,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\",\"stargazers\":0,\"master_branch\":\"master\",\"organization\":\"wildfirechat\"},\"pusher\":{\"name\":\"heavyrain2012\",\"email\":\"heavyrain.lee@gmail.com\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false},\"created\":true,\"deleted\":false,\"forced\":false,\"base_ref\":null,\"compare\":\"https://github.com/wildfirechat/github_webhoot/commit/d7c02e15ef0f\",\"commits\":[{\"id\":\"d7c02e15ef0f3eca28400bc92f2decbd6b9df2e0\",\"tree_id\":\"7311f1117ef41ec7585ae1e8ade79c1dae72ae7f\",\"distinct\":true,\"message\":\"first commit\",\"timestamp\":\"2020-02-23T19:47:09+08:00\",\"url\":\"https://github.com/wildfirechat/github_webhoot/commit/d7c02e15ef0f3eca28400bc92f2decbd6b9df2e0\",\"author\":{\"name\":\"heavyrain2012\",\"email\":\"heavyrain.lee@gmail.com\",\"username\":\"heavyrain2012\"},\"committer\":{\"name\":\"heavyrain2012\",\"email\":\"heavyrain.lee@gmail.com\",\"username\":\"heavyrain2012\"},\"added\":[\".gitignore\",\"LICENSE\",\"README.md\",\"github_webhook.iml\",\"mvnw\",\"mvnw.cmd\",\"pom.xml\",\"src/lib/common-0.21.jar\",\"src/lib/sdk-0.21.jar\",\"src/main/java/cn/wildfirechat/app/Application.java\",\"src/main/java/cn/wildfirechat/app/Controller.java\",\"src/main/java/cn/wildfirechat/app/HttpUtils.java\",\"src/main/java/cn/wildfirechat/app/Record.java\",\"src/main/java/cn/wildfirechat/app/RestResult.java\",\"src/main/java/cn/wildfirechat/app/Service.java\",\"src/main/java/cn/wildfirechat/app/ServiceImpl.java\",\"src/main/java/cn/wildfirechat/app/TulingResponse.java\",\"src/main/java/cn/wildfirechat/app/Utils.java\",\"src/main/java/cn/wildfirechat/app/pojo/License.java\",\"src/main/java/cn/wildfirechat/app/pojo/Owner.java\",\"src/main/java/cn/wildfirechat/app/pojo/Repository.java\",\"src/main/java/cn/wildfirechat/app/pojo/Sender.java\",\"src/main/java/cn/wildfirechat/app/pojo/StarEvent.java\",\"src/main/java/ikidou/reflect/TypeBuilder.java\",\"src/main/java/ikidou/reflect/TypeToken.java\",\"src/main/java/ikidou/reflect/exception/TypeException.java\",\"src/main/java/ikidou/reflect/typeimpl/ParameterizedTypeImpl.java\",\"src/main/java/ikidou/reflect/typeimpl/WildcardTypeImpl.java\",\"src/main/resources/application.properties\",\"src/test/java/cn/wildfirechat/app/ApplicationTests.java\"],\"removed\":[],\"modified\":[]}],\"head_commit\":{\"id\":\"d7c02e15ef0f3eca28400bc92f2decbd6b9df2e0\",\"tree_id\":\"7311f1117ef41ec7585ae1e8ade79c1dae72ae7f\",\"distinct\":true,\"message\":\"first commit\",\"timestamp\":\"2020-02-23T19:47:09+08:00\",\"url\":\"https://github.com/wildfirechat/github_webhoot/commit/d7c02e15ef0f3eca28400bc92f2decbd6b9df2e0\",\"author\":{\"name\":\"heavyrain2012\",\"email\":\"heavyrain.lee@gmail.com\",\"username\":\"heavyrain2012\"},\"committer\":{\"name\":\"heavyrain2012\",\"email\":\"heavyrain.lee@gmail.com\",\"username\":\"heavyrain2012\"},\"added\":[\".gitignore\",\"LICENSE\",\"README.md\",\"github_webhook.iml\",\"mvnw\",\"mvnw.cmd\",\"pom.xml\",\"src/lib/common-0.21.jar\",\"src/lib/sdk-0.21.jar\",\"src/main/java/cn/wildfirechat/app/Application.java\",\"src/main/java/cn/wildfirechat/app/Controller.java\",\"src/main/java/cn/wildfirechat/app/HttpUtils.java\",\"src/main/java/cn/wildfirechat/app/Record.java\",\"src/main/java/cn/wildfirechat/app/RestResult.java\",\"src/main/java/cn/wildfirechat/app/Service.java\",\"src/main/java/cn/wildfirechat/app/ServiceImpl.java\",\"src/main/java/cn/wildfirechat/app/TulingResponse.java\",\"src/main/java/cn/wildfirechat/app/Utils.java\",\"src/main/java/cn/wildfirechat/app/pojo/License.java\",\"src/main/java/cn/wildfirechat/app/pojo/Owner.java\",\"src/main/java/cn/wildfirechat/app/pojo/Repository.java\",\"src/main/java/cn/wildfirechat/app/pojo/Sender.java\",\"src/main/java/cn/wildfirechat/app/pojo/StarEvent.java\",\"src/main/java/ikidou/reflect/TypeBuilder.java\",\"src/main/java/ikidou/reflect/TypeToken.java\",\"src/main/java/ikidou/reflect/exception/TypeException.java\",\"src/main/java/ikidou/reflect/typeimpl/ParameterizedTypeImpl.java\",\"src/main/java/ikidou/reflect/typeimpl/WildcardTypeImpl.java\",\"src/main/resources/application.properties\",\"src/test/java/cn/wildfirechat/app/ApplicationTests.java\"],\"removed\":[],\"modified\":[]}}";
26 | PushEvent pushEvent = new Gson().fromJson(event1, PushEvent.class);
27 | System.out.println(pushEvent.compare);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Pusher.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class Pusher {
4 | public String name;
5 | public String email;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Repository.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import java.util.Date;
4 |
5 | public class Repository {
6 | public long id;
7 | public String node_id;
8 | public String name;
9 | public String full_name;
10 | public User owner;
11 | public String html_url;
12 | public String description;
13 | public boolean fork;
14 | public String url;
15 | public String forks_url;
16 | public String keys_url;
17 | public String collaborators_url;
18 | public String teams_url;
19 | public String hooks_url;
20 | public String issue_events_url;
21 | public String events_url;
22 | public String assignees_url;
23 | public String branches_url;
24 | public String tags_url;
25 | public String blobs_url;
26 | public String git_tags_url;
27 | public String git_refs_url;
28 | public String trees_url;
29 | public String statuses_url;
30 | public String languages_url;
31 | public String stargazers_url;
32 | public String contributors_url;
33 | public String subscribers_url;
34 | public String subscription_url;
35 | public String commits_url;
36 | public String git_commits_url;
37 | public String comments_url;
38 | public String issue_comment_url;
39 | public String contents_url;
40 | public String compare_url;
41 | public String merges_url;
42 | public String archive_url;
43 | public String downloads_url;
44 | public String issues_url;
45 | public String pulls_url;
46 | public String milestones_url;
47 | public String notifications_url;
48 | public String labels_url;
49 | public String releases_url;
50 | public String deployments_url;
51 | public String git_url;
52 | public String ssh_url;
53 | public String clone_url;
54 | public String svn_url;
55 | public String homepage;
56 | public int size;
57 | public int stargazers_count;
58 | public int watchers_count;
59 | public String language;
60 | public boolean has_issues;
61 | public boolean has_projects;
62 | public boolean has_downloads;
63 | public boolean has_wiki;
64 | public boolean has_pages;
65 | public int forks_count;
66 | public String mirror_url;
67 | public boolean archived;
68 | public boolean disabled;
69 | public int open_issues_count;
70 | public License license;
71 | public int forks;
72 | public int open_issues;
73 | public int watchers;
74 | public String default_branch;
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/Sender.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class Sender {
4 | public String login;
5 | public long id;
6 | public String node_id;
7 | public String avatar_url;
8 | public String gravatar_id;
9 | public String url;
10 | public String html_url;
11 | public String followers_url;
12 | public String following_url;
13 | public String gists_url;
14 | public String starred_url;
15 | public String subscriptions_url;
16 | public String organizations_url;
17 | public String repos_url;
18 | public String events_url;
19 | public String received_events_url;
20 | public String type;
21 | public boolean site_admin;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/StarEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | import java.util.Date;
6 |
7 | //https://developer.github.com/v3/activity/events/types/#starevent
8 | public class StarEvent {
9 | //The action performed. Can be created or deleted.
10 | public String action;
11 | public Date starred_at;
12 | public Repository repository;
13 | public Sender sender;
14 |
15 | public static StarEvent fromJson(String jsonStr) {
16 | return new Gson().fromJson(jsonStr, StarEvent.class);
17 | }
18 |
19 | public static void main(String[] args) {
20 | String starEvent1 = "{\"action\":\"deleted\",\"starred_at\":null,\"repository\":{\"id\":218795851,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyMTg3OTU4NTE=\",\"name\":\"web-chat\",\"full_name\":\"wildfirechat/web-chat\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/web-chat\",\"description\":\"Open source IM solution. \",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/web-chat\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/web-chat/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/web-chat/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/web-chat/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/web-chat/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/web-chat/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/web-chat/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/web-chat/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/web-chat/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/web-chat/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/web-chat/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/web-chat/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/web-chat/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/web-chat/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/web-chat/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/web-chat/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/web-chat/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/web-chat/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/web-chat/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/web-chat/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/web-chat/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/web-chat/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/web-chat/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/web-chat/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/web-chat/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/web-chat/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/web-chat/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/web-chat/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/web-chat/deployments\",\"created_at\":\"2019-10-31T15:17:35Z\",\"updated_at\":\"2020-02-23T10:34:40Z\",\"pushed_at\":\"2020-02-17T01:53:42Z\",\"git_url\":\"git://github.com/wildfirechat/web-chat.git\",\"ssh_url\":\"git@github.com:wildfirechat/web-chat.git\",\"clone_url\":\"https://github.com/wildfirechat/web-chat.git\",\"svn_url\":\"https://github.com/wildfirechat/web-chat\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":97998,\"stargazers_count\":18,\"watchers_count\":18,\"language\":\"JavaScript\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":31,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":3,\"license\":{\"key\":\"mit\",\"name\":\"MIT License\",\"spdx_id\":\"MIT\",\"url\":\"https://api.github.com/licenses/mit\",\"node_id\":\"MDc6TGljZW5zZTEz\"},\"forks\":31,\"open_issues\":3,\"watchers\":18,\"default_branch\":\"master\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false}}";
21 | StarEvent deletedEvent = new Gson().fromJson(starEvent1, StarEvent.class);
22 | System.out.println(deletedEvent.action);
23 |
24 | String starEvent2 = "{\"action\":\"created\",\"starred_at\":\"2020-02-23T10:35:05Z\",\"repository\":{\"id\":218795851,\"node_id\":\"MDEwOlJlcG9zaXRvcnkyMTg3OTU4NTE=\",\"name\":\"web-chat\",\"full_name\":\"wildfirechat/web-chat\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/web-chat\",\"description\":\"Open source IM solution. \",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/web-chat\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/web-chat/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/web-chat/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/web-chat/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/web-chat/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/web-chat/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/web-chat/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/web-chat/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/web-chat/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/web-chat/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/web-chat/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/web-chat/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/web-chat/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/web-chat/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/web-chat/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/web-chat/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/web-chat/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/web-chat/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/web-chat/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/web-chat/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/web-chat/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/web-chat/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/web-chat/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/web-chat/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/web-chat/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/web-chat/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/web-chat/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/web-chat/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/web-chat/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/web-chat/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/web-chat/deployments\",\"created_at\":\"2019-10-31T15:17:35Z\",\"updated_at\":\"2020-02-23T10:35:05Z\",\"pushed_at\":\"2020-02-17T01:53:42Z\",\"git_url\":\"git://github.com/wildfirechat/web-chat.git\",\"ssh_url\":\"git@github.com:wildfirechat/web-chat.git\",\"clone_url\":\"https://github.com/wildfirechat/web-chat.git\",\"svn_url\":\"https://github.com/wildfirechat/web-chat\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":97998,\"stargazers_count\":19,\"watchers_count\":19,\"language\":\"JavaScript\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":31,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":3,\"license\":{\"key\":\"mit\",\"name\":\"MIT License\",\"spdx_id\":\"MIT\",\"url\":\"https://api.github.com/licenses/mit\",\"node_id\":\"MDc6TGljZW5zZTEz\"},\"forks\":31,\"open_issues\":3,\"watchers\":19,\"default_branch\":\"master\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"heavyrain2012\",\"id\":34463389,\"node_id\":\"MDQ6VXNlcjM0NDYzMzg5\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/34463389?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/heavyrain2012\",\"html_url\":\"https://github.com/heavyrain2012\",\"followers_url\":\"https://api.github.com/users/heavyrain2012/followers\",\"following_url\":\"https://api.github.com/users/heavyrain2012/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/heavyrain2012/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/heavyrain2012/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/heavyrain2012/subscriptions\",\"organizations_url\":\"https://api.github.com/users/heavyrain2012/orgs\",\"repos_url\":\"https://api.github.com/users/heavyrain2012/repos\",\"events_url\":\"https://api.github.com/users/heavyrain2012/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/heavyrain2012/received_events\",\"type\":\"User\",\"site_admin\":false}}";
25 | StarEvent starredEvent = new Gson().fromJson(starEvent2, StarEvent.class);
26 | System.out.println(starredEvent.action);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/User.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | public class User {
4 | public String login;
5 | public long id;
6 | public String node_id;
7 | public String avatar_url;
8 | public String gravatar_id;
9 | public String url;
10 | public String html_url;
11 | public String followers_url;
12 | public String following_url;
13 | public String gists_url;
14 | public String starred_url;
15 | public String subscriptions_url;
16 | public String organizations_url;
17 | public String repos_url;
18 | public String events_url;
19 | public String received_events_url;
20 | public String type;
21 | public String site_admin;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/github/pojo/WatchEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.github.pojo;
2 |
3 | import com.google.gson.Gson;
4 |
5 | //https://developer.github.com/v3/activity/events/types/#watchevent
6 | public class WatchEvent {
7 | //The action that was performed. Currently, can only be started.
8 | public String action;
9 | public Repository repository;
10 | public User sender;
11 |
12 | public static WatchEvent fromJson(String jsonStr) {
13 | return new Gson().fromJson(jsonStr, WatchEvent.class);
14 | }
15 |
16 | public static void main(String[] args) {
17 | String event = "{\"action\":\"started\",\"repository\":{\"id\":172194045,\"node_id\":\"MDEwOlJlcG9zaXRvcnkxNzIxOTQwNDU=\",\"name\":\"pc-chat\",\"full_name\":\"wildfirechat/pc-chat\",\"private\":false,\"owner\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/wildfirechat\",\"html_url\":\"https://github.com/wildfirechat\",\"followers_url\":\"https://api.github.com/users/wildfirechat/followers\",\"following_url\":\"https://api.github.com/users/wildfirechat/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/wildfirechat/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/wildfirechat/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/wildfirechat/subscriptions\",\"organizations_url\":\"https://api.github.com/users/wildfirechat/orgs\",\"repos_url\":\"https://api.github.com/users/wildfirechat/repos\",\"events_url\":\"https://api.github.com/users/wildfirechat/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/wildfirechat/received_events\",\"type\":\"Organization\",\"site_admin\":false},\"html_url\":\"https://github.com/wildfirechat/pc-chat\",\"description\":\"Open source IM solution. \",\"fork\":false,\"url\":\"https://api.github.com/repos/wildfirechat/pc-chat\",\"forks_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/forks\",\"keys_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/teams\",\"hooks_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/hooks\",\"issue_events_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/events\",\"assignees_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/tags\",\"blobs_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/languages\",\"stargazers_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/stargazers\",\"contributors_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/contributors\",\"subscribers_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/subscribers\",\"subscription_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/subscription\",\"commits_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/merges\",\"archive_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/downloads\",\"issues_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/wildfirechat/pc-chat/deployments\",\"created_at\":\"2019-02-23T09:08:03Z\",\"updated_at\":\"2020-02-24T01:15:25Z\",\"pushed_at\":\"2020-02-23T08:31:54Z\",\"git_url\":\"git://github.com/wildfirechat/pc-chat.git\",\"ssh_url\":\"git@github.com:wildfirechat/pc-chat.git\",\"clone_url\":\"https://github.com/wildfirechat/pc-chat.git\",\"svn_url\":\"https://github.com/wildfirechat/pc-chat\",\"homepage\":\"http://docs.wildfirechat.cn\",\"size\":172881,\"stargazers_count\":268,\"watchers_count\":268,\"language\":\"JavaScript\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":199,\"mirror_url\":null,\"archived\":false,\"disabled\":false,\"open_issues_count\":7,\"license\":{\"key\":\"mit\",\"name\":\"MIT License\",\"spdx_id\":\"MIT\",\"url\":\"https://api.github.com/licenses/mit\",\"node_id\":\"MDc6TGljZW5zZTEz\"},\"forks\":199,\"open_issues\":7,\"watchers\":268,\"default_branch\":\"master\"},\"organization\":{\"login\":\"wildfirechat\",\"id\":33191460,\"node_id\":\"MDEyOk9yZ2FuaXphdGlvbjMzMTkxNDYw\",\"url\":\"https://api.github.com/orgs/wildfirechat\",\"repos_url\":\"https://api.github.com/orgs/wildfirechat/repos\",\"events_url\":\"https://api.github.com/orgs/wildfirechat/events\",\"hooks_url\":\"https://api.github.com/orgs/wildfirechat/hooks\",\"issues_url\":\"https://api.github.com/orgs/wildfirechat/issues\",\"members_url\":\"https://api.github.com/orgs/wildfirechat/members{/member}\",\"public_members_url\":\"https://api.github.com/orgs/wildfirechat/public_members{/member}\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/33191460?v=4\",\"description\":\"北京野火无限网络科技有限公司--专注于即时通讯技术,提供优质可控的即时通讯能力\"},\"sender\":{\"login\":\"longshadian\",\"id\":1725317,\"node_id\":\"MDQ6VXNlcjE3MjUzMTc=\",\"avatar_url\":\"https://avatars0.githubusercontent.com/u/1725317?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/longshadian\",\"html_url\":\"https://github.com/longshadian\",\"followers_url\":\"https://api.github.com/users/longshadian/followers\",\"following_url\":\"https://api.github.com/users/longshadian/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/longshadian/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/longshadian/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/longshadian/subscriptions\",\"organizations_url\":\"https://api.github.com/users/longshadian/orgs\",\"repos_url\":\"https://api.github.com/users/longshadian/repos\",\"events_url\":\"https://api.github.com/users/longshadian/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/longshadian/received_events\",\"type\":\"User\",\"site_admin\":false}}";
18 | WatchEvent watchEvent = fromJson(event);
19 | System.out.println(watchEvent.action);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/GitLabWebhook.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab;
2 |
3 | import cn.wildfirechat.app.webhook.IWebhook;
4 | import cn.wildfirechat.app.webhook.gitlab.pojo.*;
5 | import cn.wildfirechat.pojos.MessagePayload;
6 | import com.google.gson.Gson;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 |
12 | public class GitLabWebhook implements IWebhook {
13 | private static final Logger LOG = LoggerFactory.getLogger(GitLabWebhook.class);
14 | @Override
15 | public String invokeCommand() {
16 | return "/gitlab";
17 | }
18 |
19 | @Override
20 | public Object handleWebhookPost(HttpServletRequest request, String user, String payload, SendMessageCallback callback) {
21 | String event = request.getHeader("X-Gitlab-Event");
22 | LOG.info("on receive message {}, event {}", payload, event);
23 |
24 | String message = null;
25 |
26 | MessagePayload messagePayload = new MessagePayload();
27 | messagePayload.setType(1);
28 |
29 | //https://gitee.com/help/articles/4271#article-header0
30 | try {
31 | if (event.equals("Push Hook")) {
32 | PushEvent pushEvent = new Gson().fromJson(payload, PushEvent.class);
33 | message = pushEvent.user_name + " push " + pushEvent.total_commits_count + " commit(s) 到项目 " + pushEvent.repository.name;
34 | for (Commit commit: pushEvent.commits) {
35 | message += "\n";
36 | message += "\nTitle: " + commit.title;
37 | message += "\nMessage: " + commit.message;
38 | message += "\nUrl: " + commit.url;
39 | }
40 | } else if(event.equals("Tag Push Hook")) {
41 | TagEvent tagEvent = new Gson().fromJson(payload, TagEvent.class);
42 | message = tagEvent.user_name + " 在项目 " + tagEvent.repository.name + " " + tagEvent.object_kind + " " + tagEvent.ref;
43 | } else if(event.equals("Issue Hook")) {
44 | IssueEvent issueEvent = new Gson().fromJson(payload, IssueEvent.class);
45 | message = issueEvent.user.name + " 在项目 " + issueEvent.repository.name + " 提交了issue";
46 | message += "\nTitle: " + issueEvent.object_attributes.title;
47 | message += "\nMessage: " + issueEvent.object_attributes.description;
48 | message += "\nUrl: " + issueEvent.object_attributes.url;
49 | } else if(event.equals("Note Hook")) {
50 | NoteEvent noteEvent = new Gson().fromJson(payload, NoteEvent.class);
51 | message = noteEvent.user.name + " 在项目 " + noteEvent.repository.name + " 评论了 " + noteEvent.object_attributes.noteable_type;
52 | message += "\nMessage: " + noteEvent.object_attributes.note;
53 | if(noteEvent.object_attributes.noteable_type.equalsIgnoreCase("Commit")) {
54 | message += "\nCommit title: " + noteEvent.commit.title;
55 | message += "\nCommit message: " + noteEvent.commit.message;
56 | message += "\nCommit url: " + noteEvent.commit.url;
57 | } else if(noteEvent.object_attributes.noteable_type.equalsIgnoreCase("MergeRequest")) {
58 | message += "\nMergeRequest title: " + noteEvent.merge_request.description;
59 | message += "\nMergeRequest state: " + noteEvent.merge_request.state;
60 | message += "\nMergeRequest merge_status: " + noteEvent.merge_request.merge_status;
61 | } else if(noteEvent.object_attributes.noteable_type.equalsIgnoreCase("Issue")) {
62 | message += "\nIssue title: " + noteEvent.issue.title;
63 | message += "\nIssue message: " + noteEvent.issue.body;
64 | message += "\nIssue url: " + noteEvent.issue.html_url;
65 | } else if(noteEvent.object_attributes.noteable_type.equalsIgnoreCase("Snippet")) {
66 | message += "\nSnippet title: " + noteEvent.snippet.title;
67 | message += "\nSnippet message: " + noteEvent.snippet.content;
68 | message += "\nSnippet file: " + noteEvent.snippet.file_name;
69 | }
70 | } else if(event.equals("Merge Request Hook")) {
71 | MergeRequestEvent mergeRequestEvent = new Gson().fromJson(payload, MergeRequestEvent.class);
72 | message = mergeRequestEvent.user.name + " merge request 在项目 " + mergeRequestEvent.repository.name;
73 | message += "\nTitle: " + mergeRequestEvent.object_attributes.title;
74 | message += "\ndescription: " + mergeRequestEvent.object_attributes.description;
75 | message += "\nsource_branch: " + mergeRequestEvent.object_attributes.source_branch;
76 | message += "\ntarget_branch: " + mergeRequestEvent.object_attributes.target_branch;
77 | }
78 | } catch (Exception e) {
79 | e.printStackTrace();
80 | messagePayload.setSearchableContent("糟糕,处理gitlab事件出错了:" + e.getMessage());
81 | callback.sendMessage(messagePayload);
82 | }
83 |
84 | if (message == null) {
85 | messagePayload.setSearchableContent("你收到了一个gitlab事件:" + event);
86 | callback.sendMessage(messagePayload);
87 | messagePayload.setSearchableContent(payload);
88 | callback.sendMessage(messagePayload);
89 | } else {
90 | messagePayload.setSearchableContent(message);
91 | callback.sendMessage(messagePayload);
92 | }
93 | return "ok";
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Author.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Author {
4 | public String name;
5 | public String email;
6 | }
7 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Commit.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Commit {
4 | /*
5 | "id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
6 | "message": "Update Catalan translation to e38cb41.\n\nSee https://gitlab.com/gitlab-org/gitlab for more information",
7 | "title": "Update Catalan translation to e38cb41.",
8 | "timestamp": "2011-12-12T14:27:31+02:00",
9 | "url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
10 | "author": {
11 | "name": "Jordi Mallach",
12 | "email": "jordi@softcatala.org"
13 | },
14 | "added": ["CHANGELOG"],
15 | "modified": ["app/controller/application.rb"],
16 | "removed": []
17 | */
18 | public String id;
19 | public String message;
20 | public String title;
21 | public String timestamp;
22 | public String url;
23 | public Author author;
24 | public String[] added;
25 | public String[] modified;
26 | public String[] removed;
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/IssueEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class IssueEvent {
4 | public User user;
5 | public Project project;
6 | public Repository repository;
7 | public IssueObjectAttributes object_attributes;
8 | public User[] assignees;
9 | }
10 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/IssueObjectAttributes.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class IssueObjectAttributes {
4 | public String title;
5 | public String description;
6 | public String url;
7 | public String state;
8 | public String action;
9 | /*
10 | "id": 301,
11 | "title": "New API: create/update/delete file",
12 | "assignee_ids": [51],
13 | "assignee_id": 51,
14 | "author_id": 51,
15 | "project_id": 14,
16 | "created_at": "2013-12-03T17:15:43Z",
17 | "updated_at": "2013-12-03T17:15:43Z",
18 | "updated_by_id": 1,
19 | "last_edited_at": null,
20 | "last_edited_by_id": null,
21 | "relative_position": 0,
22 | "description": "Create new API for manipulations with repository",
23 | "milestone_id": null,
24 | "state_id": 1,
25 | "confidential": false,
26 | "discussion_locked": true,
27 | "due_date": null,
28 | "moved_to_id": null,
29 | "duplicated_to_id": null,
30 | "time_estimate": 0,
31 | "total_time_spent": 0,
32 | "human_total_time_spent": null,
33 | "human_time_estimate": null,
34 | "weight": null,
35 | "iid": 23,
36 | "url": "http://example.com/diaspora/issues/23",
37 | "state": "opened",
38 | "action": "open",
39 | */
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Label.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Label {
4 | /*
5 | "id": 206,
6 | "title": "API",
7 | "color": "#ffffff",
8 | "project_id": 14,
9 | "created_at": "2013-12-03T17:15:43Z",
10 | "updated_at": "2013-12-03T17:15:43Z",
11 | "template": false,
12 | "description": "API related issues",
13 | "type": "ProjectLabel",
14 | "group_id": 41
15 | */
16 | public long id;
17 | public String title;
18 | public String color;
19 | public long project_id;
20 | public String created_at;
21 | public String updated_at;
22 | public boolean template;
23 | public String description;
24 | public String type;
25 | public long group_id;
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/MergeRequest.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class MergeRequest {
4 | public String target_branch;
5 | public String source_branch;
6 | public String state;
7 | public String title;
8 | public String merge_status;
9 | public String description;
10 | public Repository source;
11 | public Repository target;
12 | public Commit last_commit;
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/MergeRequestEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class MergeRequestEvent {
4 | public User user;
5 | public Repository repository;
6 | public MergeRequest object_attributes;
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/NoteEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | import cn.wildfirechat.app.webhook.gitee.pojo.Issue;
4 |
5 | public class NoteEvent {
6 | public User user;
7 | public Project project;
8 | public Repository repository;
9 | public NoteObjectAttributes object_attributes;
10 | public Commit commit;
11 | public MergeRequest merge_request;
12 | public Issue issue;
13 | public Snippet snippet;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/NoteObjectAttributes.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class NoteObjectAttributes {
4 | /*
5 | "id": 1244,
6 | "note": "This MR needs work.",
7 | "noteable_type": "MergeRequest",
8 | "author_id": 1,
9 | "created_at": "2015-05-17 18:21:36 UTC",
10 | "updated_at": "2015-05-17 18:21:36 UTC",
11 | "project_id": 5,
12 | "attachment": null,
13 | "line_code": null,
14 | "commit_id": "",
15 | "noteable_id": 7,
16 | "system": false,
17 | "st_diff": null,
18 | "url": "http://example.com/gitlab-org/gitlab-test/merge_requests/1#note_1244"
19 | */
20 | public long id;
21 | public String note;
22 | public String noteable_type;
23 | public String url;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Project.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Project {
4 | /*
5 | "id": 15,
6 | "name":"Diaspora",
7 | "description":"",
8 | "web_url":"http://example.com/mike/diaspora",
9 | "avatar_url":null,
10 | "git_ssh_url":"git@example.com:mike/diaspora.git",
11 | "git_http_url":"http://example.com/mike/diaspora.git",
12 | "namespace":"Mike",
13 | "visibility_level":0,
14 | "path_with_namespace":"mike/diaspora",
15 | "default_branch":"master",
16 | "homepage":"http://example.com/mike/diaspora",
17 | "url":"git@example.com:mike/diaspora.git",
18 | "ssh_url":"git@example.com:mike/diaspora.git",
19 | "http_url":"http://example.com/mike/diaspora.git"
20 | */
21 | public long id;
22 | public String name;
23 | public String description;
24 | public String web_url;
25 | public String avatar_url;
26 | public String git_ssh_url;
27 | public String git_http_url;
28 | public String namespace;
29 | public int visibility_level;
30 | public String path_with_namespace;
31 | public String default_branch;
32 | public String homepage;
33 | public String url;
34 | public String ssh_url;
35 | public String http_url;
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/PushEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class PushEvent {
4 | public String user_name;
5 | public Repository repository;
6 | public Commit[] commits;
7 | public int total_commits_count;
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Repository.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Repository {
4 | /*
5 | "name": "Gitlab Test",
6 | "url": "http://example.com/gitlabhq/gitlab-test.git",
7 | "description": "Aut reprehenderit ut est.",
8 | "homepage": "http://example.com/gitlabhq/gitlab-test"
9 | */
10 | public String name;
11 | public String url;
12 | public String description;
13 | public String homepage;
14 | }
15 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/Snippet.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class Snippet {
4 | /*
5 | "id": 53,
6 | "title": "test",
7 | "content": "puts 'Hello world'",
8 | "author_id": 1,
9 | "project_id": 5,
10 | "created_at": "2015-04-09 02:40:38 UTC",
11 | "updated_at": "2015-04-09 02:40:38 UTC",
12 | "file_name": "test.rb",
13 | "expires_at": null,
14 | "type": "ProjectSnippet",
15 | "visibility_level": 0
16 | */
17 | public String title;
18 | public String content;
19 | public String file_name;
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/TagEvent.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class TagEvent {
4 | public String user_name;
5 | public String ref;
6 | public Repository repository;
7 | public String object_kind;
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/java/cn/wildfirechat/app/webhook/gitlab/pojo/User.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app.webhook.gitlab.pojo;
2 |
3 | public class User {
4 | /*
5 | "id": 1,
6 | "name": "Administrator",
7 | "username": "root",
8 | "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon",
9 | "email": "admin@example.com"
10 | */
11 | public long id;
12 | public String name;
13 | public String username;
14 | public String avatar_url;
15 | public String email;
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/java/ikidou/reflect/TypeBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 ikidou
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package ikidou.reflect;
18 |
19 | import java.lang.reflect.Type;
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import ikidou.reflect.exception.TypeException;
24 | import ikidou.reflect.typeimpl.ParameterizedTypeImpl;
25 | import ikidou.reflect.typeimpl.WildcardTypeImpl;
26 |
27 | public class TypeBuilder {
28 | private final TypeBuilder parent;
29 | private final Class raw;
30 | private final List args = new ArrayList<>();
31 |
32 |
33 | private TypeBuilder(Class raw, TypeBuilder parent) {
34 | assert raw != null;
35 | this.raw = raw;
36 | this.parent = parent;
37 | }
38 |
39 | public static TypeBuilder newInstance(Class raw) {
40 | return new TypeBuilder(raw, null);
41 | }
42 |
43 | private static TypeBuilder newInstance(Class raw, TypeBuilder parent) {
44 | return new TypeBuilder(raw, parent);
45 | }
46 |
47 |
48 | public TypeBuilder beginSubType(Class raw) {
49 | return newInstance(raw, this);
50 | }
51 |
52 | public TypeBuilder endSubType() {
53 | if (parent == null) {
54 | throw new TypeException("expect beginSubType() before endSubType()");
55 | }
56 |
57 | parent.addTypeParam(getType());
58 |
59 | return parent;
60 | }
61 |
62 | public TypeBuilder addTypeParam(Class clazz) {
63 | return addTypeParam((Type) clazz);
64 | }
65 |
66 | public TypeBuilder addTypeParamExtends(Class... classes) {
67 | if (classes == null) {
68 | throw new NullPointerException("addTypeParamExtends() expect not null Class");
69 | }
70 |
71 | WildcardTypeImpl wildcardType = new WildcardTypeImpl(null, classes);
72 |
73 | return addTypeParam(wildcardType);
74 | }
75 |
76 | public TypeBuilder addTypeParamSuper(Class... classes) {
77 | if (classes == null) {
78 | throw new NullPointerException("addTypeParamSuper() expect not null Class");
79 | }
80 |
81 | WildcardTypeImpl wildcardType = new WildcardTypeImpl(classes, null);
82 |
83 | return addTypeParam(wildcardType);
84 | }
85 |
86 | public TypeBuilder addTypeParam(Type type) {
87 | if (type == null) {
88 | throw new NullPointerException("addTypeParam expect not null Type");
89 | }
90 |
91 | args.add(type);
92 |
93 | return this;
94 | }
95 |
96 | public Type build() {
97 | if (parent != null) {
98 | throw new TypeException("expect endSubType() before build()");
99 | }
100 |
101 | return getType();
102 | }
103 |
104 | private Type getType() {
105 | if (args.isEmpty()) {
106 | return raw;
107 | }
108 | return new ParameterizedTypeImpl(raw, args.toArray(new Type[args.size()]), null);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/ikidou/reflect/TypeToken.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 ikidou
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package ikidou.reflect;
18 |
19 | import java.lang.reflect.ParameterizedType;
20 | import java.lang.reflect.Type;
21 |
22 | import ikidou.reflect.exception.TypeException;
23 |
24 | public abstract class TypeToken {
25 | private final Type type;
26 |
27 | public TypeToken() {
28 | Type superclass = getClass().getGenericSuperclass();
29 | if (superclass instanceof Class) {
30 | throw new TypeException("No generics found!");
31 | }
32 | ParameterizedType type = (ParameterizedType) superclass;
33 | this.type = type.getActualTypeArguments()[0];
34 | }
35 |
36 | public Type getType() {
37 | return type;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/ikidou/reflect/exception/TypeException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 ikidou
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package ikidou.reflect.exception;
18 |
19 | public class TypeException extends RuntimeException {
20 | public TypeException() {
21 | }
22 |
23 | public TypeException(String message) {
24 | super(message);
25 | }
26 |
27 | public TypeException(String message, Throwable cause) {
28 | super(message, cause);
29 | }
30 |
31 | public TypeException(Throwable cause) {
32 | super(cause);
33 | }
34 |
35 | public TypeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
36 | super(message, cause, enableSuppression, writableStackTrace);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/java/ikidou/reflect/typeimpl/ParameterizedTypeImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 ikidou
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package ikidou.reflect.typeimpl;
18 |
19 | import java.lang.reflect.ParameterizedType;
20 | import java.lang.reflect.Type;
21 | import java.lang.reflect.TypeVariable;
22 | import java.util.Arrays;
23 |
24 | import ikidou.reflect.exception.TypeException;
25 |
26 | @SuppressWarnings("SpellCheckingInspection")
27 | public class ParameterizedTypeImpl implements ParameterizedType {
28 | private final Class raw;
29 | private final Type[] args;
30 | private final Type owner;
31 |
32 | public ParameterizedTypeImpl(Class raw, Type[] args, Type owner) {
33 | this.raw = raw;
34 | this.args = args != null ? args : new Type[0];
35 | this.owner = owner;
36 | checkArgs();
37 | }
38 |
39 | private void checkArgs() {
40 | if (raw == null) {
41 | throw new TypeException("raw class can't be null");
42 | }
43 | TypeVariable[] typeParameters = raw.getTypeParameters();
44 | if (args.length != 0 && typeParameters.length != args.length) {
45 | throw new TypeException(raw.getName() + " expect " + typeParameters.length + " arg(s), got " + args.length);
46 | }
47 | }
48 |
49 | @Override
50 | public Type[] getActualTypeArguments() {
51 | return args;
52 | }
53 |
54 | @Override
55 | public Type getRawType() {
56 | return raw;
57 | }
58 |
59 | @Override
60 | public Type getOwnerType() {
61 | return owner;
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | StringBuilder sb = new StringBuilder();
67 | sb.append(raw.getName());
68 | if (args.length != 0) {
69 | sb.append('<');
70 | for (int i = 0; i < args.length; i++) {
71 | if (i != 0) {
72 | sb.append(", ");
73 | }
74 | Type type = args[i];
75 | if (type instanceof Class) {
76 | Class clazz = (Class) type;
77 |
78 | if (clazz.isArray()) {
79 | int count = 0;
80 | do {
81 | count++;
82 | clazz = clazz.getComponentType();
83 | } while (clazz.isArray());
84 |
85 | sb.append(clazz.getName());
86 |
87 | for (int j = count; j > 0; j--) {
88 | sb.append("[]");
89 | }
90 | } else {
91 | sb.append(clazz.getName());
92 | }
93 | } else {
94 | sb.append(args[i].toString());
95 | }
96 | }
97 | sb.append('>');
98 | }
99 | return sb.toString();
100 | }
101 |
102 | @Override
103 | public boolean equals(Object o) {
104 | if (this == o) return true;
105 | if (o == null || getClass() != o.getClass()) return false;
106 |
107 | ParameterizedTypeImpl that = (ParameterizedTypeImpl) o;
108 |
109 | if (!raw.equals(that.raw)) return false;
110 | // Probably incorrect - comparing Object[] arrays with Arrays.equals
111 | if (!Arrays.equals(args, that.args)) return false;
112 | return owner != null ? owner.equals(that.owner) : that.owner == null;
113 |
114 | }
115 |
116 | @Override
117 | public int hashCode() {
118 | int result = raw.hashCode();
119 | result = 31 * result + Arrays.hashCode(args);
120 | result = 31 * result + (owner != null ? owner.hashCode() : 0);
121 | return result;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/ikidou/reflect/typeimpl/WildcardTypeImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016 ikidou
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package ikidou.reflect.typeimpl;
18 |
19 | import java.lang.reflect.Type;
20 | import java.lang.reflect.WildcardType;
21 | import java.util.Arrays;
22 |
23 | public class WildcardTypeImpl implements WildcardType {
24 | private final Class[] upper;
25 | private final Class[] lower;
26 |
27 | public WildcardTypeImpl(Class[] lower, Class[] upper) {
28 | this.lower = lower != null ? lower : new Class[0];
29 | this.upper = upper != null ? upper : new Class[0];
30 |
31 | checkArgs();
32 | }
33 |
34 | private void checkArgs() {
35 | if (lower.length == 0 && upper.length == 0) {
36 | throw new IllegalArgumentException("lower or upper can't be null");
37 | }
38 |
39 | checkArgs(lower);
40 | checkArgs(upper);
41 | }
42 |
43 | private void checkArgs(Class[] args) {
44 | for (int i = 1; i < args.length; i++) {
45 | Class clazz = args[i];
46 | if (!clazz.isInterface()) {
47 | throw new IllegalArgumentException(clazz.getName() + " not a interface!");
48 | }
49 | }
50 | }
51 |
52 | @Override
53 | public Type[] getUpperBounds() {
54 | return upper;
55 | }
56 |
57 | @Override
58 | public Type[] getLowerBounds() {
59 | return lower;
60 | }
61 |
62 | @Override
63 | public String toString() {
64 | if (upper.length > 0) {
65 | if (upper[0] == Object.class) {
66 | return "?";
67 | }
68 | return getTypeString("? extends ", upper);
69 | } else {
70 | return getTypeString("? super ", lower);
71 | }
72 | }
73 |
74 | private String getTypeString(String prefix, Class[] type) {
75 | StringBuilder sb = new StringBuilder();
76 | sb.append(prefix);
77 |
78 | for (int i = 0; i < type.length; i++) {
79 | if (i != 0) {
80 | sb.append(" & ");
81 | }
82 | sb.append(type[i].getName());
83 | }
84 |
85 | return sb.toString();
86 |
87 | }
88 |
89 | @Override
90 | public boolean equals(Object o) {
91 | if (this == o) return true;
92 | if (o == null || getClass() != o.getClass()) return false;
93 |
94 | WildcardTypeImpl that = (WildcardTypeImpl) o;
95 |
96 | return Arrays.equals(upper, that.upper) && Arrays.equals(lower, that.lower);
97 |
98 | }
99 |
100 | @Override
101 | public int hashCode() {
102 | int result = Arrays.hashCode(upper);
103 | result = 31 * result + Arrays.hashCode(lower);
104 | return result;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8883
--------------------------------------------------------------------------------
/src/test/java/cn/wildfirechat/app/ApplicationTests.java:
--------------------------------------------------------------------------------
1 | package cn.wildfirechat.app;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 | import org.springframework.boot.test.context.SpringBootTest;
6 | import org.springframework.test.context.junit4.SpringRunner;
7 |
8 | @RunWith(SpringRunner.class)
9 | @SpringBootTest
10 | public class ApplicationTests {
11 |
12 | @Test
13 | public void contextLoads() {
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------