Skip to content

Commit be5452a

Browse files
committed
add a cryptocurrency feature
which is able to fetch cryptocurrency price
1 parent ffd3539 commit be5452a

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

discord_bot.go

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ func main() {
2323

2424
store := refs.Store{
2525
Asset: &refs.AssetStore{},
26+
Ticker: &refs.TickerStore{},
2627
}
2728

2829
// Add handler

handlers/cryptocurrency/filter.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cryptocurrency
2+
3+
import (
4+
coreCrypto "github.com/QOLPlus/core/commands/cryptocurrency"
5+
)
6+
7+
func arrowOfTicker(ticker coreCrypto.Ticker) string {
8+
switch ticker.Change {
9+
case "EVEN":
10+
return "-"
11+
case "RISE":
12+
return "▲"
13+
case "FALL":
14+
return "▼"
15+
default:
16+
return ""
17+
}
18+
}
19+
func pmChangeRate(ticker coreCrypto.Ticker) float64 {
20+
switch ticker.Change {
21+
case "FALL":
22+
return -1 * ticker.ChangeRate
23+
default:
24+
return ticker.ChangeRate
25+
}
26+
}

handlers/cryptocurrency/process.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package cryptocurrency
2+
3+
import (
4+
"fmt"
5+
coreCrypto "github.com/QOLPlus/core/commands/cryptocurrency"
6+
"github.com/QOLPlus/discord-bot/refs"
7+
"github.com/bwmarrin/discordgo"
8+
"github.com/dustin/go-humanize"
9+
"math"
10+
"regexp"
11+
"strings"
12+
)
13+
14+
15+
var commands = []string{"코인", "크립토", "가상자산", "가상화폐", "CC", "cc", "c"}
16+
17+
var Registry = &refs.HandlerRegistry{
18+
Commands: commands,
19+
Proc: Process,
20+
}
21+
22+
var notFoundMessage string = fmt.Sprintf(
23+
"가상자산 정보를 찾을 수 없습니다. `[(%s) 검색어]`",
24+
strings.Join(commands, "|"),
25+
)
26+
27+
var KRW string = "KRW"
28+
29+
func Process(store *refs.Store, s *discordgo.Session, m *discordgo.MessageCreate, data []string) {
30+
tickerStore := store.Ticker
31+
tickerStore.Reload(3600)
32+
33+
var selectedMarkets []coreCrypto.MarketMaster
34+
for _, phrase := range data {
35+
if len(phrase) == 0 || KRW == phrase {
36+
continue
37+
}
38+
39+
for _, master := range *tickerStore.Data {
40+
if similar(master, phrase) && strings.HasPrefix(master.Market, KRW){
41+
selectedMarkets = append(selectedMarkets, master)
42+
}
43+
}
44+
}
45+
46+
if len(selectedMarkets) == 0 {
47+
_, _ = s.ChannelMessageSend(m.ChannelID, notFoundMessage)
48+
return
49+
}
50+
51+
for _, market := range selectedMarkets {
52+
tickers, err := market.FetchTicker()
53+
54+
if err != nil {
55+
continue
56+
}
57+
58+
for _, ticker := range *tickers {
59+
_, _ = s.ChannelMessageSend(m.ChannelID, buildSimpleMessage(market, ticker))
60+
}
61+
}
62+
}
63+
64+
func similar(market coreCrypto.MarketMaster, keyword string) bool {
65+
match, _ := regexp.MatchString(
66+
keyword,
67+
strings.Join([]string{
68+
market.KoreanName,
69+
market.EnglishName,
70+
market.Market,
71+
}, "|"),
72+
)
73+
return match
74+
}
75+
76+
func buildSimpleMessage(market coreCrypto.MarketMaster, ticker coreCrypto.Ticker) string {
77+
return fmt.Sprintf(
78+
"**%s**: %s %s",
79+
market.KoreanName,
80+
strings.Join([]string{
81+
humanize.Commaf(ticker.TradePrice),
82+
fmt.Sprintf("%s%s", arrowOfTicker(ticker), humanize.CommafWithDigits(math.Abs(ticker.ChangePrice), 2)),
83+
"(" + fmt.Sprintf("%.2f", pmChangeRate(ticker) * 100) + "%)",
84+
}, " "),
85+
fmt.Sprintf(
86+
"%s / 52주 신고가: %s(%s) / 52주 신저가: %s(%s)",
87+
ticker.Market,
88+
humanize.CommafWithDigits(ticker.Highest52WeekPrice, 2),
89+
ticker.Highest52WeekDate,
90+
humanize.CommafWithDigits(ticker.Lowest52WeekPrice, 2),
91+
ticker.Lowest52WeekDate,
92+
),
93+
)
94+
}

handlers/handler.go

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package handlers
22

33
import (
4+
"github.com/QOLPlus/discord-bot/handlers/cryptocurrency"
45
"github.com/QOLPlus/discord-bot/handlers/stock_trend"
56
"github.com/QOLPlus/discord-bot/handlers/weather"
67
"github.com/bwmarrin/discordgo"
@@ -16,6 +17,7 @@ func HandlerFactory(store *refs.Store) interface{} {
1617
onHandlers.Register(stock_trend.Registry)
1718
onHandlers.Register(weather.Registry)
1819
onHandlers.Register(asset.Registry)
20+
onHandlers.Register(cryptocurrency.Registry)
1921
onCommands := onHandlers.GetKeys()
2022

2123
return func(s *discordgo.Session, m *discordgo.MessageCreate) {

refs/store.go

+23
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,25 @@ package refs
22

33
import (
44
coreAsset "github.com/QOLPlus/core/commands/asset"
5+
coreCrypto "github.com/QOLPlus/core/commands/cryptocurrency"
56
"time"
67
)
78

89
type Store struct {
910
Asset *AssetStore
11+
Ticker *TickerStore
1012
}
1113

1214
type AssetStore struct {
1315
Timestamp int64
1416
Data *[]AssetData
1517
}
1618

19+
type TickerStore struct {
20+
Timestamp int64
21+
Data *[]coreCrypto.MarketMaster
22+
}
23+
1724
type AssetData struct {
1825
Master *coreAsset.StockMaster
1926
Assets *[]coreAsset.Asset
@@ -47,3 +54,19 @@ func (as *AssetStore) Reload(offset int64) {
4754
as.Timestamp = now
4855
}
4956
}
57+
func (ts *TickerStore) Reload(offset int64) {
58+
now := time.Now().Unix()
59+
if (now - ts.Timestamp) < offset {
60+
return
61+
}
62+
63+
masters, err := coreCrypto.FetchMarketMasters()
64+
if err != nil {
65+
return
66+
}
67+
68+
if len(*masters) > 0 {
69+
ts.Data = masters
70+
ts.Timestamp = now
71+
}
72+
}

0 commit comments

Comments
 (0)