update
							parent
							
								
									6d9d87c00b
								
							
						
					
					
						commit
						df967ca290
					
				
							
								
								
									
										23
									
								
								api_join.go
								
								
								
								
							
							
						
						
									
										23
									
								
								api_join.go
								
								
								
								
							|  | @ -13,8 +13,6 @@ func Follow(event *linebot.Event) { | ||||||
| 	} | 	} | ||||||
| 	Hit("加入", uid) | 	Hit("加入", uid) | ||||||
| 
 | 
 | ||||||
| 	reply := event.ReplyToken |  | ||||||
| 
 |  | ||||||
| 	row := DB.Exec("select id from users where id = ?", uid).RowsAffected | 	row := DB.Exec("select id from users where id = ?", uid).RowsAffected | ||||||
| 	if row == 0 { | 	if row == 0 { | ||||||
| 		// 新用戶
 | 		// 新用戶
 | ||||||
|  | @ -23,31 +21,18 @@ func Follow(event *linebot.Event) { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 舊用戶
 |  | ||||||
| 		log.Debug().Str("user", uid).Msg("New user.") | 		log.Debug().Str("user", uid).Msg("New user.") | ||||||
| 		msg := linebot.NewTextMessage("你好!") | 		msg := linebot.NewTextMessage("你好!") | ||||||
| 		if reply != "" { | 		if _, err := SendMessage(event.ReplyToken, uid, msg); err != nil { | ||||||
| 			if _, err := bot.ReplyMessage(reply, msg).Do(); err != nil { | 			panic(err) | ||||||
| 				log.Error().Err(err).Caller().Msg("reply error") |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if _, err := bot.PushMessage(uid, msg).Do(); err != nil { |  | ||||||
| 				log.Error().Err(err).Caller().Msg("push error") |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 	} else { | 	} else { | ||||||
| 		// 舊用戶
 | 		// 舊用戶
 | ||||||
| 		log.Debug().Str("user", uid).Msg("user unblocked.") | 		log.Debug().Str("user", uid).Msg("user unblocked.") | ||||||
| 		msg := linebot.NewTextMessage("歡迎回來!") | 		msg := linebot.NewTextMessage("歡迎回來!") | ||||||
| 		if reply != "" { | 		if _, err := SendMessage(event.ReplyToken, uid, msg); err != nil { | ||||||
| 			if _, err := bot.ReplyMessage(reply, msg).Do(); err != nil { | 			panic(err) | ||||||
| 				log.Error().Err(err).Caller().Msg("reply error") |  | ||||||
| 			} |  | ||||||
| 		} else { |  | ||||||
| 			if _, err := bot.PushMessage(uid, msg).Do(); err != nil { |  | ||||||
| 				log.Error().Err(err).Caller().Msg("push error") |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,16 +9,6 @@ import ( | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var bot *linebot.Client |  | ||||||
| 
 |  | ||||||
| func setupLine() { |  | ||||||
| 	var err error |  | ||||||
| 	bot, err = linebot.New(LINE_SECRET, LINE_TOKEN) |  | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func webhook(c *gin.Context) { | func webhook(c *gin.Context) { | ||||||
| 	events, err := bot.ParseRequest(c.Request) | 	events, err := bot.ParseRequest(c.Request) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -43,7 +33,15 @@ func webhook(c *gin.Context) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func controller(event *linebot.Event) { | func controller(event *linebot.Event) { | ||||||
| 	switch event.Source.Ty { | 
 | ||||||
|  | 	msg, ok := event.Message.(*linebot.TextMessage) | ||||||
|  | 	if !ok { | ||||||
|  | 		log.Error().Msg("controller not impemented") | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	Hit(msg.Text, event.Source.UserID) | ||||||
|  | 
 | ||||||
|  | 	switch msg.Text { | ||||||
| 	case "": | 	case "": | ||||||
| 
 | 
 | ||||||
| 	default: | 	default: | ||||||
|  | @ -0,0 +1,73 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"strconv" | ||||||
|  | 	"strings" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/gin-gonic/gin" | ||||||
|  | 	"github.com/google/uuid" | ||||||
|  | 	"github.com/rs/zerolog/log" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func ApiUpdateEmail(c *gin.Context) { | ||||||
|  | 	data := struct { | ||||||
|  | 		ID    string `json:"id"` | ||||||
|  | 		Email string `json:"email"` | ||||||
|  | 	}{} | ||||||
|  | 	if err := c.ShouldBindJSON(&data); err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	usr := &User{} | ||||||
|  | 	if err := DB.First(usr, "id = ?", data.ID).Error; err != nil { | ||||||
|  | 		// create user fallback
 | ||||||
|  | 		log.Error().Err(err).Msg("No User") | ||||||
|  | 	} | ||||||
|  | 	DB.Model(&User{}).Where("id = ?", data.ID).Update("email", data.Email) | ||||||
|  | 	OK(c, "ok") | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func ApiPostReceipt(c *gin.Context) { | ||||||
|  | 	oid := c.Param("oid") | ||||||
|  | 	if oid == "" { | ||||||
|  | 		panic(ErrorBadRequest) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// order exists
 | ||||||
|  | 	order := &Order{} | ||||||
|  | 	if err := DB.First(order, "id = ?", oid).Error; err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// get file
 | ||||||
|  | 	f, err := c.FormFile("file") | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	id := uuid.New() | ||||||
|  | 	ext := filepath.Ext(f.Filename) | ||||||
|  | 	storedFileName := strings.Replace(id.String(), "-", "", -1) + ext | ||||||
|  | 	t := time.Now() | ||||||
|  | 	dir := filepath.Join( | ||||||
|  | 		strconv.Itoa(t.Year()), | ||||||
|  | 		strconv.Itoa(int(t.Month())), | ||||||
|  | 	) | ||||||
|  | 	dest := filepath.Join( | ||||||
|  | 		"attachment", | ||||||
|  | 		dir, | ||||||
|  | 	) | ||||||
|  | 	Mkdir(dest) | ||||||
|  | 
 | ||||||
|  | 	// save file
 | ||||||
|  | 	dest = filepath.Join(dest, storedFileName) | ||||||
|  | 	if err = c.SaveUploadedFile(f, dest); err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	if err = DB.Model(order).Update("attachment", filepath.Join(dir, storedFileName)). | ||||||
|  | 		Error; err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	OK(c, "ok") | ||||||
|  | } | ||||||
|  | @ -26,7 +26,7 @@ for PLATFORM in $PLATFORMS; do | ||||||
|   scp ${DIST}/${BIN_FILENAME} root@bot.ework.tw:~ |   scp ${DIST}/${BIN_FILENAME} root@bot.ework.tw:~ | ||||||
|   ssh root@bot.ework.tw chmod +x talent |   ssh root@bot.ework.tw chmod +x talent | ||||||
|   ssh root@bot.ework.tw screen -X quit |   ssh root@bot.ework.tw screen -X quit | ||||||
|   ssh root@bot.ework.tw screen -d -m bash -c './talent -dev -db-name talentdev | tee talent.log' |   ssh root@bot.ework.tw screen -d -m ./talent -dev | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| if [[ "${FAILURES}" != "" ]]; then | if [[ "${FAILURES}" != "" ]]; then | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										1
									
								
								go.mod
								
								
								
								
							|  | @ -5,6 +5,7 @@ go 1.17 | ||||||
| require ( | require ( | ||||||
| 	github.com/fatih/color v1.13.0 | 	github.com/fatih/color v1.13.0 | ||||||
| 	github.com/gin-gonic/gin v1.7.7 | 	github.com/gin-gonic/gin v1.7.7 | ||||||
|  | 	github.com/google/uuid v1.3.0 | ||||||
| 	github.com/line/line-bot-sdk-go/v7 v7.11.0 | 	github.com/line/line-bot-sdk-go/v7 v7.11.0 | ||||||
| 	github.com/rs/xid v1.3.0 | 	github.com/rs/xid v1.3.0 | ||||||
| 	github.com/rs/zerolog v1.26.1 | 	github.com/rs/zerolog v1.26.1 | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							|  | @ -48,6 +48,8 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= | ||||||
| github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||||
| github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= | ||||||
|  | github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||||||
|  | github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||||
| github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= | github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= | ||||||
| github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= | github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= | ||||||
| github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= | github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= | ||||||
|  |  | ||||||
							
								
								
									
										5
									
								
								main.go
								
								
								
								
							
							
						
						
									
										5
									
								
								main.go
								
								
								
								
							|  | @ -54,6 +54,11 @@ func main() { | ||||||
| 	// setup route
 | 	// setup route
 | ||||||
| 	server.GET("/", func(c *gin.Context) { OK(c, "ok") }) | 	server.GET("/", func(c *gin.Context) { OK(c, "ok") }) | ||||||
| 
 | 
 | ||||||
|  | 	// setup api
 | ||||||
|  | 	api := server.Group("api") | ||||||
|  | 	api.POST("/email", ApiUpdateEmail) | ||||||
|  | 	api.POST("/attach/:oid", ApiPostReceipt) | ||||||
|  | 
 | ||||||
| 	// setup bot webhook
 | 	// setup bot webhook
 | ||||||
| 	hook := server.Group("bot") | 	hook := server.Group("bot") | ||||||
| 	hook.POST("/", webhook) | 	hook.POST("/", webhook) | ||||||
|  |  | ||||||
							
								
								
									
										33
									
								
								model.go
								
								
								
								
							
							
						
						
									
										33
									
								
								model.go
								
								
								
								
							|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/rs/xid" | 	"github.com/rs/xid" | ||||||
|  | 	"github.com/rs/zerolog/log" | ||||||
| 	"gorm.io/gorm" | 	"gorm.io/gorm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -35,7 +36,7 @@ type Profile struct { | ||||||
| type Product struct { | type Product struct { | ||||||
| 	ID uint `gorm:"primaryKey"` | 	ID uint `gorm:"primaryKey"` | ||||||
| 
 | 
 | ||||||
| 	Type        string | 	Categories  []Category `gorm:"many2many:product_categories;"` | ||||||
| 	Name        string | 	Name        string | ||||||
| 	Brief       string | 	Brief       string | ||||||
| 	Description string | 	Description string | ||||||
|  | @ -44,10 +45,20 @@ type Product struct { | ||||||
| 	UpdatedAt time.Time | 	UpdatedAt time.Time | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type Category struct { | ||||||
|  | 	Name string `gorm:"primaryKey"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| type Order struct { | type Order struct { | ||||||
|  | 	ID string | ||||||
|  | 
 | ||||||
| 	UserID    string `gorm:"primaryKey"` | 	UserID    string `gorm:"primaryKey"` | ||||||
| 	ProductID uint   `gorm:"primaryKey"` | 	ProductID uint   `gorm:"primaryKey"` | ||||||
| 
 | 
 | ||||||
|  | 	Start      time.Time | ||||||
|  | 	End        time.Time | ||||||
|  | 	Attachment string | ||||||
|  | 
 | ||||||
| 	Price float32 | 	Price float32 | ||||||
| 
 | 
 | ||||||
| 	CreatedAt time.Time | 	CreatedAt time.Time | ||||||
|  | @ -61,7 +72,6 @@ type Node struct { | ||||||
| 	UserID string | 	UserID string | ||||||
| 
 | 
 | ||||||
| 	CreatedAt time.Time | 	CreatedAt time.Time | ||||||
| 	UpdatedAt time.Time |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // BeforeCreate set UID
 | // BeforeCreate set UID
 | ||||||
|  | @ -72,3 +82,22 @@ func (u *User) BeforeCreate(tx *gorm.DB) (err error) { | ||||||
| 	u.LastLogin = time.Now() | 	u.LastLogin = time.Now() | ||||||
| 	return | 	return | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (u *User) AfterFind(tx *gorm.DB) (err error) { | ||||||
|  | 	if u.ProfileID != 0 { | ||||||
|  | 		profile := &Profile{} | ||||||
|  | 		if err := tx.First(profile, "id = ?", u.ProfileID).Error; err != nil { | ||||||
|  | 			log.Error().Err(err).Msg("get profile error") | ||||||
|  | 		} else { | ||||||
|  | 			u.Profile = *profile | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (o *Order) BeforeCreate(tx *gorm.DB) (err error) { | ||||||
|  | 	if o.ID == "" { | ||||||
|  | 		o.ID = xid.New().String() | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | go run *.go -dev -db-name talentdev -addr 127.0.0.1:8000 | ||||||
|  | @ -6,6 +6,7 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fatih/color" | 	"github.com/fatih/color" | ||||||
|  | 	"github.com/line/line-bot-sdk-go/v7/linebot" | ||||||
| 	"github.com/rs/zerolog" | 	"github.com/rs/zerolog" | ||||||
| 	"github.com/rs/zerolog/log" | 	"github.com/rs/zerolog/log" | ||||||
| ) | ) | ||||||
|  | @ -52,10 +53,12 @@ func setupLog() { | ||||||
| 	zerolog.DurationFieldInteger = true | 	zerolog.DurationFieldInteger = true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Hit(name, uid string) { | var bot *linebot.Client | ||||||
| 	n := &Node{ | 
 | ||||||
| 		Name:   name, | func setupLine() { | ||||||
| 		UserID: uid, | 	var err error | ||||||
|  | 	bot, err = linebot.New(LINE_SECRET, LINE_TOKEN) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
| 	} | 	} | ||||||
| 	DB.Create(n) |  | ||||||
| } | } | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | package main | ||||||
|  | @ -0,0 +1,48 @@ | ||||||
|  | package main | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 
 | ||||||
|  | 	"github.com/line/line-bot-sdk-go/v7/linebot" | ||||||
|  | 	"github.com/rs/zerolog/log" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func Mkdir(args ...interface{}) error { | ||||||
|  | 	var path string | ||||||
|  | 	var mode os.FileMode | ||||||
|  | 	mode = 0755 | ||||||
|  | 	for _, arg := range args { | ||||||
|  | 		switch arg := arg.(type) { | ||||||
|  | 		case string: | ||||||
|  | 			path = filepath.Join(path, arg) | ||||||
|  | 		case os.FileMode: | ||||||
|  | 			mode = arg | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return os.MkdirAll(path, mode) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func Hit(name, uid string) { | ||||||
|  | 	n := &Node{ | ||||||
|  | 		Name:   name, | ||||||
|  | 		UserID: uid, | ||||||
|  | 	} | ||||||
|  | 	go DB.Create(n) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func SendMessage(replyToken string, to string, messages ...linebot.SendingMessage) (*linebot.BasicResponse, error) { | ||||||
|  | 	if replyToken != "" { | ||||||
|  | 		res, err := bot.ReplyMessage(replyToken, messages...).Do() | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Error().Err(err).Caller().Interface("response", res).Msg("reply error") | ||||||
|  | 		} | ||||||
|  | 		return res, err | ||||||
|  | 	} else { | ||||||
|  | 		res, err := bot.PushMessage(to, messages...).Do() | ||||||
|  | 		if err != nil { | ||||||
|  | 			log.Error().Err(err).Caller().Interface("response", res).Msg("push error") | ||||||
|  | 		} | ||||||
|  | 		return res, err | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue