提交 7319042d 编写于 作者: JenkinsInChina's avatar JenkinsInChina

put server port into config

上级 49365041
...@@ -8,6 +8,7 @@ import ( ...@@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/linuxsuren/wechat-backend/config"
"gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
...@@ -16,14 +17,14 @@ const ( ...@@ -16,14 +17,14 @@ const (
CONFIG = "wechat" CONFIG = "wechat"
) )
func initCheck() { func initCheck(weConfig *config.WeChatConfig) {
var err error var err error
_, err = os.Stat(CONFIG) _, err = os.Stat(CONFIG)
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
_, err = git.PlainClone(CONFIG, false, &git.CloneOptions{ _, err = git.PlainClone(CONFIG, false, &git.CloneOptions{
URL: "https://github.com/LinuxSuRen/jenkins.wechat", URL: weConfig.GitURL,
Progress: os.Stdout, Progress: os.Stdout,
}) })
if err != nil { if err != nil {
...@@ -45,19 +46,19 @@ func initCheck() { ...@@ -45,19 +46,19 @@ func initCheck() {
} else { } else {
log.Println("open work tree with git error", err) log.Println("open work tree with git error", err)
os.Remove(CONFIG) os.Remove(CONFIG)
initCheck() initCheck(weConfig)
} }
} else { } else {
log.Println("open dir with git error", err) log.Println("open dir with git error", err)
os.Remove(CONFIG) os.Remove(CONFIG)
initCheck() initCheck(weConfig)
} }
} }
} else { } else {
log.Println("can't get config dir status", err) log.Println("can't get config dir status", err)
if os.RemoveAll(CONFIG) == nil { if os.RemoveAll(CONFIG) == nil {
initCheck() initCheck(weConfig)
} }
} }
...@@ -115,10 +116,6 @@ func update() { ...@@ -115,10 +116,6 @@ func update() {
} }
} }
func getWelcome() string {
return ""
}
func getKeywords() map[string]string { func getKeywords() map[string]string {
return nil return nil
} }
...@@ -9,10 +9,12 @@ import ( ...@@ -9,10 +9,12 @@ import (
// WeChatConfig represents WeChat config // WeChatConfig represents WeChat config
type WeChatConfig struct { type WeChatConfig struct {
GitURL string GitURL string `yaml:"git_url"`
GitBranch string GitBranch string `yaml:"git_branch"`
Token string Token string `yaml:"token"`
GitHubWebHookSecret string GitHubWebHookSecret string `yaml:"github_webhook_secret"`
ServerPort int `yaml:"server_port"`
} }
// LoadConfig load config // LoadConfig load config
...@@ -29,4 +31,5 @@ func LoadConfig(configFile string) (config *WeChatConfig, err error) { ...@@ -29,4 +31,5 @@ func LoadConfig(configFile string) (config *WeChatConfig, err error) {
if err != nil { if err != nil {
log.Printf("parse config file error: %v\n", err) log.Printf("parse config file error: %v\n", err)
} }
return
} }
token: Token
git_url: GitURL
git_branch: GitBranch
github_webhook_secret: GitHubWebHookSecret
server_port: 80
\ No newline at end of file
package config
import "testing"
func TestLoadConfig(t *testing.T) {
config, err := LoadConfig("config.yaml")
if err != nil {
t.Errorf("load config error %v", err)
}
if config.Token != "Token" || config.GitURL != "GitURL" ||
config.GitBranch != "GitBranch" ||
config.GitHubWebHookSecret != "GitHubWebHookSecret" ||
config.ServerPort != 80 {
t.Errorf("parse error, config %#v", config)
}
}
package main package github
import ( import (
"log" "log"
"net/http" "net/http"
"github.com/linuxsuren/wechat-backend/config"
"gopkg.in/go-playground/webhooks.v5/github" "gopkg.in/go-playground/webhooks.v5/github"
) )
func webhookHandler(w http.ResponseWriter, r *http.Request) { func WebhookHandler(w http.ResponseWriter, r *http.Request, weConfig *config.WeChatConfig, initCheck func(*config.WeChatConfig)) {
hook, _ := github.New(github.Options.Secret("secret")) hook, _ := github.New(github.Options.Secret("secret"))
payload, err := hook.Parse(r, github.PushEvent) payload, err := hook.Parse(r, github.PushEvent)
...@@ -30,5 +31,5 @@ func webhookHandler(w http.ResponseWriter, r *http.Request) { ...@@ -30,5 +31,5 @@ func webhookHandler(w http.ResponseWriter, r *http.Request) {
} }
log.Println("Going to update wechat config.") log.Println("Going to update wechat config.")
initCheck() initCheck(weConfig)
} }
...@@ -13,24 +13,26 @@ import ( ...@@ -13,24 +13,26 @@ import (
"time" "time"
"github.com/linuxsuren/wechat-backend/config" "github.com/linuxsuren/wechat-backend/config"
"github.com/linuxsuren/wechat-backend/github"
) )
const ( // WeChat represents WeChat
token = "wechat4go" type WeChat struct {
) Config *config.WeChatConfig
}
func makeSignature(timestamp, nonce string) string { func (w *WeChat) makeSignature(timestamp, nonce string) string {
sl := []string{token, timestamp, nonce} sl := []string{w.Config.Token, timestamp, nonce}
sort.Strings(sl) sort.Strings(sl)
s := sha1.New() s := sha1.New()
io.WriteString(s, strings.Join(sl, "")) io.WriteString(s, strings.Join(sl, ""))
return fmt.Sprintf("%x", s.Sum(nil)) return fmt.Sprintf("%x", s.Sum(nil))
} }
func validateUrl(w http.ResponseWriter, r *http.Request) bool { func (we *WeChat) validateUrl(w http.ResponseWriter, r *http.Request) bool {
timestamp := strings.Join(r.Form["timestamp"], "") timestamp := strings.Join(r.Form["timestamp"], "")
nonce := strings.Join(r.Form["nonce"], "") nonce := strings.Join(r.Form["nonce"], "")
signatureGen := makeSignature(timestamp, nonce) signatureGen := we.makeSignature(timestamp, nonce)
signatureIn := strings.Join(r.Form["signature"], "") signatureIn := strings.Join(r.Form["signature"], "")
if signatureGen != signatureIn { if signatureGen != signatureIn {
...@@ -41,9 +43,9 @@ func validateUrl(w http.ResponseWriter, r *http.Request) bool { ...@@ -41,9 +43,9 @@ func validateUrl(w http.ResponseWriter, r *http.Request) bool {
return true return true
} }
func procRequest(w http.ResponseWriter, r *http.Request) { func (we *WeChat) procRequest(w http.ResponseWriter, r *http.Request) {
r.ParseForm() r.ParseForm()
if !validateUrl(w, r) { if !we.validateUrl(w, r) {
log.Println("Wechat Service: this http request is not from Wechat platform!") log.Println("Wechat Service: this http request is not from Wechat platform!")
return return
} }
...@@ -51,73 +53,70 @@ func procRequest(w http.ResponseWriter, r *http.Request) { ...@@ -51,73 +53,70 @@ func procRequest(w http.ResponseWriter, r *http.Request) {
switch r.Method { switch r.Method {
case "POST": case "POST":
wechatRequest(w, r) we.wechatRequest(w, r)
case "GET": case "GET":
normalRequest(w, r) we.normalRequest(w, r)
} }
} }
func normalRequest(w http.ResponseWriter, r *http.Request) { func (we *WeChat) normalRequest(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "welcome aboard.") w.Write([]byte("welcome aboard WeChat."))
} }
func wechatRequest(w http.ResponseWriter, r *http.Request) { func (we *WeChat) wechatRequest(w http.ResponseWriter, r *http.Request) {
textRequestBody := parseTextRequestBody(r) textRequestBody := we.parseTextRequestBody(r)
if textRequestBody != nil { if textRequestBody != nil {
fmt.Printf("Wechat Service: Recv text msg [%s] from user [%s]!", fmt.Printf("Wechat Service: Recv text msg [%s] from user [%s]!",
textRequestBody.Content, textRequestBody.Content,
textRequestBody.FromUserName) textRequestBody.FromUserName)
if "event" == textRequestBody.MsgType && "subscribe" == textRequestBody.Event { if "event" == textRequestBody.MsgType && "subscribe" == textRequestBody.Event {
resp, err := makeWelcomeResponseBody(textRequestBody.ToUserName, textRequestBody.FromUserName) resp, err := we.replyResponse("welcome", textRequestBody.ToUserName, textRequestBody.FromUserName)
if err != nil { if err != nil {
log.Println("Wechat Service: makeTextResponseBody error: ", err) log.Println("handle welcome replay error:", err)
return } else {
}
fmt.Fprintf(w, string(resp)) fmt.Fprintf(w, string(resp))
}
} else { } else {
keyword := textRequestBody.Content keyword := textRequestBody.Content
fmt.Println(textRequestBody.MsgType, keyword, respMap) fmt.Println(textRequestBody.MsgType, keyword, respMap)
if "text" == textRequestBody.MsgType { if "text" == textRequestBody.MsgType {
resp, err := we.replyResponse(keyword, textRequestBody.ToUserName, textRequestBody.FromUserName)
if err != nil {
log.Println("handle auto replay error:", err)
} else {
fmt.Fprintf(w, string(resp))
}
}
}
}
}
func (we *WeChat) replyResponse(keyword string, from string, to string) (data []byte, err error) {
if resp, ok := respMap[keyword]; ok { if resp, ok := respMap[keyword]; ok {
if text, ok := resp.(TextResponseBody); ok { if text, ok := resp.(TextResponseBody); ok {
textResp, err := makeTextResponseBody(textRequestBody.ToUserName, textRequestBody.FromUserName, text.Content) data, err = we.makeTextResponseBody(from, to, text.Content)
if err != nil { if err != nil {
log.Println("Wechat Service: makeTextResponseBody error: ", err) err = fmt.Errorf("Wechat Service: makeTextResponseBody error: %v", err)
return
} }
fmt.Fprintf(w, string(textResp))
return
} else if image, ok := resp.(ImageResponseBody); ok { } else if image, ok := resp.(ImageResponseBody); ok {
imageResp, err := makeImageResponseBody(textRequestBody.ToUserName, textRequestBody.FromUserName, image.Image.MediaID) data, err = we.makeImageResponseBody(from, to, image.Image.MediaID)
if err != nil { if err != nil {
log.Println("Wechat Service: makeTextResponseBody error: ", err) err = fmt.Errorf("Wechat Service: makeImageResponseBody error: %v", err)
return
} }
log.Println("response", string(imageResp))
fmt.Fprintf(w, string(imageResp))
return
} else if news, ok := resp.(NewsResponseBody); ok { } else if news, ok := resp.(NewsResponseBody); ok {
newsResp, err := makeNewsResponseBody(textRequestBody.ToUserName, textRequestBody.FromUserName, news) data, err = we.makeNewsResponseBody(from, to, news)
if err != nil { if err != nil {
log.Println("Wechat Service: makeNewsResponseBody error: ", err) err = fmt.Errorf("Wechat Service: makeNewsResponseBody error: %v", err)
return
}
log.Println("response", string(newsResp))
fmt.Fprintf(w, string(newsResp))
return
} else {
log.Println("type error", ok)
} }
} else { } else {
log.Printf("can't find keyword %s\n", keyword) err = fmt.Errorf("type error")
}
}
} }
} }
return
} }
func makeTextResponseBody(fromUserName, toUserName, content string) ([]byte, error) { func (w *WeChat) makeTextResponseBody(fromUserName, toUserName, content string) ([]byte, error) {
textResponseBody := &TextResponseBody{} textResponseBody := &TextResponseBody{}
textResponseBody.FromUserName = fromUserName textResponseBody.FromUserName = fromUserName
textResponseBody.ToUserName = toUserName textResponseBody.ToUserName = toUserName
...@@ -127,7 +126,7 @@ func makeTextResponseBody(fromUserName, toUserName, content string) ([]byte, err ...@@ -127,7 +126,7 @@ func makeTextResponseBody(fromUserName, toUserName, content string) ([]byte, err
return xml.MarshalIndent(textResponseBody, " ", " ") return xml.MarshalIndent(textResponseBody, " ", " ")
} }
func makeImageResponseBody(fromUserName, toUserName, mediaID string) ([]byte, error) { func (w *WeChat) makeImageResponseBody(fromUserName, toUserName, mediaID string) ([]byte, error) {
imageResponseBody := &ImageResponseBody{} imageResponseBody := &ImageResponseBody{}
imageResponseBody.FromUserName = fromUserName imageResponseBody.FromUserName = fromUserName
imageResponseBody.ToUserName = toUserName imageResponseBody.ToUserName = toUserName
...@@ -139,11 +138,7 @@ func makeImageResponseBody(fromUserName, toUserName, mediaID string) ([]byte, er ...@@ -139,11 +138,7 @@ func makeImageResponseBody(fromUserName, toUserName, mediaID string) ([]byte, er
return xml.MarshalIndent(imageResponseBody, " ", " ") return xml.MarshalIndent(imageResponseBody, " ", " ")
} }
func makeWelcomeResponseBody(fromUserName string, toUserName string) ([]byte, error) { func (w *WeChat) makeNewsResponseBody(fromUserName, toUserName string, news NewsResponseBody) ([]byte, error) {
return makeTextResponseBody(fromUserName, toUserName, "welcome")
}
func makeNewsResponseBody(fromUserName, toUserName string, news NewsResponseBody) ([]byte, error) {
newsResponseBody := &NewsResponseBody{} newsResponseBody := &NewsResponseBody{}
newsResponseBody.FromUserName = fromUserName newsResponseBody.FromUserName = fromUserName
newsResponseBody.ToUserName = toUserName newsResponseBody.ToUserName = toUserName
...@@ -156,7 +151,7 @@ func makeNewsResponseBody(fromUserName, toUserName string, news NewsResponseBody ...@@ -156,7 +151,7 @@ func makeNewsResponseBody(fromUserName, toUserName string, news NewsResponseBody
return xml.MarshalIndent(newsResponseBody, " ", " ") return xml.MarshalIndent(newsResponseBody, " ", " ")
} }
func parseTextRequestBody(r *http.Request) *TextRequestBody { func (w *WeChat) parseTextRequestBody(r *http.Request) *TextRequestBody {
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
...@@ -168,19 +163,29 @@ func parseTextRequestBody(r *http.Request) *TextRequestBody { ...@@ -168,19 +163,29 @@ func parseTextRequestBody(r *http.Request) *TextRequestBody {
return requestBody return requestBody
} }
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}
func main() { func main() {
config.LoadConfig("") weConfig, err := config.LoadConfig("config/wechat.yaml")
if err != nil {
log.Printf("load config error %v\n", err)
}
if weConfig.ServerPort <= 0 {
weConfig.ServerPort = 8080
}
initCheck() wechat := WeChat{
Config: weConfig,
}
go func() {
initCheck(weConfig)
}()
createWxMenu() createWxMenu()
http.HandleFunc("/", procRequest) http.HandleFunc("/", wechat.procRequest)
http.HandleFunc("/status", healthHandler) http.HandleFunc("/status", healthHandler)
http.HandleFunc("/webhook", webhookHandler) http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
github.WebhookHandler(w, r, weConfig, initCheck)
})
log.Fatal(http.ListenAndServe(":18080", nil)) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", weConfig.ServerPort), nil))
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册