Skip to content

Commit

Permalink
Merge pull request #79 from Warkeeper/master
Browse files Browse the repository at this point in the history
feat: support push notification to ios devices when stock is available
  • Loading branch information
hteen authored Sep 25, 2023
2 parents 28870ac + fe8338a commit 02dacf3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 11 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,18 @@ GOROOT 为 GO 安装目录,根据实际安装位置修改
4. 点击`开始`按钮开始监听,检测到有货时会自动打开购物车页面
5. 匹配到有货后会自动暂停监听,直到再次点击 `开始`

### 有货时推送通知到 iOS 设备
1. App Store 下载并安装 App 「Bark」,并允许「Bark」进行推送
2. 打开「Bark」,复制应用中代表你自己设备的地址(格式如` https://api.day.app/xxxxxxxxx `),粘贴至本应用的`Bark 通知地址`
3. 点击 `测试 Bark 通知`,确认应用能够通知到你的 iOS 设备
4. 更多内容请参考 `https://bark.day.app/`

## Contributors
- [@Hteen](https://github.com/hteen)
- [@Timssse](https://github.com/Timssse)
- [@Black-Hole](https://github.com/BlackHole1)
- [@RayJason](https://github.com/RayJason)
- [@Warkeeper](https://github.com/Warkeeper)

## 一杯卡布奇诺 ☕️

Expand Down
23 changes: 18 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ func main() {
productWidget := widget.NewSelect(services.Product.ByAreaTitleForOptions(defaultArea), nil)
productWidget.PlaceHolder = "请选择 iPhone 型号"

// Bark 通知输入框
barkWidget := widget.NewEntry()
barkWidget.SetPlaceHolder("https://api.day.app/你的BarkKey")

// 地区选择器 (Area Selector)
areaWidget := widget.NewRadioGroup(services.Area.ForOptions(), func(value string) {
storeWidget.Options = services.Store.ByAreaTitleForOptions(value)
Expand All @@ -45,24 +49,26 @@ func main() {
services.Listen.Area = services.Area.GetArea(value)
services.Listen.Clean()
})

areaWidget.Horizontal = true

help := `1. 在 Apple 官网将需要购买的型号加入购物车
2. 选择地区、门店和型号,点击“添加”按钮,将需要监听的型号添加到监听列表
3. 点击“开始”按钮开始监听,检测到有货时会自动打开购物车页面
`

loadUserSettingsCache(areaWidget, storeWidget, productWidget)
loadUserSettingsCache(areaWidget, storeWidget, productWidget, barkWidget)

// 初始化 GUI 窗口内容 (Initialize GUI)
view.Window.SetContent(container.NewVBox(
widget.NewLabel(help),
container.New(layout.NewFormLayout(), widget.NewLabel("选择地区:"), areaWidget),
container.New(layout.NewFormLayout(), widget.NewLabel("选择门店:"), storeWidget),
container.New(layout.NewFormLayout(), widget.NewLabel("选择型号:"), productWidget),
container.New(layout.NewFormLayout(), widget.NewLabel("Bark 通知地址"), barkWidget),

container.NewBorder(nil, nil,
createActionButtons(areaWidget, storeWidget, productWidget),
createActionButtons(areaWidget, storeWidget, productWidget, barkWidget),
createControlButtons(),
),

Expand Down Expand Up @@ -90,30 +96,33 @@ func initFyneApp() {
}

// 加载用户设置缓存 (Load user settings cache)
func loadUserSettingsCache(areaWidget *widget.RadioGroup, storeWidget *widget.Select, productWidget *widget.Select) {
func loadUserSettingsCache(areaWidget *widget.RadioGroup, storeWidget *widget.Select, productWidget *widget.Select, barkNotifyWidget *widget.Entry) {
settings, err := services.LoadSettings()
if err == nil {
areaWidget.SetSelected(settings.SelectedArea)
storeWidget.SetSelected(settings.SelectedStore)
productWidget.SetSelected(settings.SelectedProduct)
services.Listen.SetListenItems(settings.ListenItems)
barkNotifyWidget.Text = settings.BarkNotifyUrl
services.Listen.BarkNotifyUrl = settings.BarkNotifyUrl
} else {
areaWidget.SetSelected(services.Listen.Area.Title)
}
}

// 创建动作按钮 (Create action buttons)
func createActionButtons(areaWidget *widget.RadioGroup, storeWidget *widget.Select, productWidget *widget.Select) *fyne.Container {
func createActionButtons(areaWidget *widget.RadioGroup, storeWidget *widget.Select, productWidget *widget.Select, barkNotifyWidget *widget.Entry) *fyne.Container {
return container.NewHBox(
widget.NewButton("添加", func() {
if storeWidget.Selected == "" || productWidget.Selected == "" {
dialog.ShowError(errors.New("请选择门店和型号"), view.Window)
} else {
services.Listen.Add(areaWidget.Selected, storeWidget.Selected, productWidget.Selected)
services.Listen.Add(areaWidget.Selected, storeWidget.Selected, productWidget.Selected, barkNotifyWidget.Text)
services.SaveSettings(services.UserSettings{
SelectedArea: areaWidget.Selected,
SelectedStore: storeWidget.Selected,
SelectedProduct: productWidget.Selected,
BarkNotifyUrl: barkNotifyWidget.Text,
ListenItems: services.Listen.GetListenItems(),
})
}
Expand All @@ -125,6 +134,10 @@ func createActionButtons(areaWidget *widget.RadioGroup, storeWidget *widget.Sele
widget.NewButton("试听(有货提示音)", func() {
go services.Listen.AlertMp3()
}),
widget.NewButton("测试 Bark 通知", func() {
services.Listen.BarkNotifyUrl = barkNotifyWidget.Text
services.Listen.SendPushNotificationByBark("有货提醒(测试)", "此为测试提醒,点击通知将跳转到相关链接", "https://www.apple.com.cn/")
}),
)
}

Expand Down
34 changes: 28 additions & 6 deletions services/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strconv"
"strings"
"time"

"fyne.io/fyne/v2"
Expand Down Expand Up @@ -42,10 +44,11 @@ var Listen = listenService{
}

type listenService struct {
items map[string]ListenItem
Status binding.String
Area model.Area
Logs *widget.Label
items map[string]ListenItem
Status binding.String
Area model.Area
Logs *widget.Label
BarkNotifyUrl string
}

type ListenItem struct {
Expand All @@ -55,7 +58,7 @@ type ListenItem struct {
Time carbon.DateTime
}

func (s *listenService) Add(areaTitle string, storeTitle string, productTitle string) {
func (s *listenService) Add(areaTitle string, storeTitle string, productTitle string, barkNotifyUrl string) {

store := Store.GetStore(areaTitle, storeTitle)
product := Product.GetProduct(areaTitle, productTitle)
Expand All @@ -70,6 +73,7 @@ func (s *listenService) Add(areaTitle string, storeTitle string, productTitle st
}
}

s.BarkNotifyUrl = barkNotifyUrl
s.UpdateLogStr()
}

Expand Down Expand Up @@ -127,15 +131,17 @@ func (s *listenService) Run() {
s.UpdateStatus(key, StatusInStock)
s.Status.Set(Pause)

var bagUrl = fmt.Sprintf("https://www.apple.com/%s/shop/bag", s.Area.ShortCode)
// 进入购物袋
s.openBrowser(fmt.Sprintf("https://www.apple.com/%s/shop/bag", s.Area.ShortCode))
s.openBrowser(bagUrl)
msg := fmt.Sprintf("%s %s 有货", item.Store.CityStoreName, item.Product.Title)
dialog.ShowInformation("匹配成功", msg, view.Window)
view.App.SendNotification(&fyne.Notification{
Title: "有货提醒",
Content: msg,
})
go s.AlertMp3()
go s.SendPushNotificationByBark("有货提醒", msg, bagUrl)
break
} else {
s.UpdateStatus(key, StatusOutStock)
Expand Down Expand Up @@ -282,3 +288,19 @@ func (s *listenService) AlertMp3() {
})))
<-done
}

func (s *listenService) SendPushNotificationByBark(title string, content string, bagUrl string) {

if len(s.BarkNotifyUrl) <= 0 {
return
}

apiUrl := fmt.Sprintf("%s/%s/%s?url=%s", strings.TrimRight(s.BarkNotifyUrl, "/"), title, content, bagUrl)

response, err := http.Get(apiUrl)
if err != nil {
panic(err)
return
}
defer response.Body.Close()
}
1 change: 1 addition & 0 deletions services/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type UserSettings struct {
SelectedArea string `json:"selected_area"`
SelectedStore string `json:"selected_store"`
SelectedProduct string `json:"selected_product"`
BarkNotifyUrl string `json:"bark_notify_url"`
ListenItems map[string]ListenItem `json:"listen_items"`
}

Expand Down

0 comments on commit 02dacf3

Please sign in to comment.