Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new Auction #3

Merged
merged 5 commits into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix messages and replies
  • Loading branch information
AtreusSoltani committed Feb 29, 2024
commit e0e4be592b658f3b49bfa62bde910c9cc83eb058
12 changes: 10 additions & 2 deletions auction/auctioneer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func NewAuctioneer(config StartAuctionConfig, chatID int64, send chan tgbotapi.C
case "special_auction":
auction = NewSpecialAuction(config.Name, config.StartPrice, config.MinStep)
}

stopChannel := make(chan string)
bids := make(chan Bid)

Expand All @@ -49,7 +50,13 @@ func (a *Auctioneer) Run(receive tgbotapi.UpdatesChannel) {
activeAuction = a.auction
a.auction.Start()

startingMessage := tgbotapi.NewMessage(a.chatID, fmt.Sprintf(messages.START_AUCTION_MESSAGE, a.auction.Name(), a.auction.StartPrice(), a.auction.MinStep()))
var startingMessage tgbotapi.Chattable
switch a.auction.(type) {
case *ReverseAuction:
startingMessage = tgbotapi.NewMessage(a.chatID, fmt.Sprintf(messages.START_REVERSE_AUCTION_MESSAGE, a.auction.Name(), a.auction.StartPrice(), a.auction.MinStep(), a.auction.Name()))
case *SpecialAuction:
startingMessage = tgbotapi.NewMessage(a.chatID, fmt.Sprintf(messages.START_SPECIAL_AUCTION_MESSAGE, a.auction.Name(), a.auction.StartPrice(), a.auction.MinStep(), a.auction.Name()))
}
a.send <- startingMessage

go a.auction.Auctioneer()(a)
Expand Down Expand Up @@ -77,6 +84,7 @@ func (a *Auctioneer) Run(receive tgbotapi.UpdatesChannel) {
case update := <-receive:
if update.Message != nil {
bid, err := activeAuction.ParseBid(update)
bid.Update = update
if err != nil {
message := tgbotapi.NewMessage(update.Message.Chat.ID, messages.INVALID_BID_MESSAGE)
message.ReplyToMessageID = update.Message.MessageID
Expand All @@ -89,7 +97,7 @@ func (a *Auctioneer) Run(receive tgbotapi.UpdatesChannel) {
a.send <- message
continue
}
if update.Message.Chat.ID != a.chatID {
if update.Message.Chat.ID != a.chatID && a.auction.IsPrivateAllowed() {
message := tgbotapi.NewMessage(update.Message.Chat.ID, messages.INVALID_CHAT_ID_MESSAGE)
message.ReplyToMessageID = update.Message.MessageID
a.send <- message
Expand Down
2 changes: 2 additions & 0 deletions auction/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ type Auction interface {
Auctioneer() func(auctioneer *Auctioneer)
// ParseBid Parse Bid from string
ParseBid(bid tgbotapi.Update) (Bid, error)
// IsPrivateAllowed Is private allowed
IsPrivateAllowed() bool
}
7 changes: 7 additions & 0 deletions auction/reverse_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func NewReverseAuction(name string, startPrice float64, minStep float64) Auction
Bidder: "System",
Amount: startPrice + minStep,
Status: "Active",
Time: time.Now(),
}
return &ReverseAuction{
name: name,
Expand Down Expand Up @@ -142,10 +143,12 @@ func (a *ReverseAuction) Auctioneer() func(auctioneer *Auctioneer) {
result, err := auctioneer.auction.Bid(bid.Bidder, bid.Amount)
if err != nil {
message := tgbotapi.NewMessage(auctioneer.chatID, err.Error())
message.ReplyToMessageID = bid.Update.Message.MessageID
auctioneer.send <- message
continue
}
message := tgbotapi.NewMessage(auctioneer.chatID, result)
message.ReplyToMessageID = bid.Update.Message.MessageID
auctioneer.send <- message

countDown.Reset(duration)
Expand All @@ -169,3 +172,7 @@ func (a *ReverseAuction) Auctioneer() func(auctioneer *Auctioneer) {
}
}
}

func (a *ReverseAuction) IsPrivateAllowed() bool {
return false
}
23 changes: 22 additions & 1 deletion auction/special_auction.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"AuctionBot/messages"
"fmt"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
"github.com/sirupsen/logrus"
"os"
"regexp"
"time"
)
Expand All @@ -23,6 +25,7 @@ func NewSpecialAuction(name string, startPrice float64, minStep float64) Auction
Bidder: "System",
Amount: startPrice,
Status: "Active",
Time: time.Now(),
}
return &SpecialAuction{
name: name,
Expand Down Expand Up @@ -67,6 +70,7 @@ func (a *SpecialAuction) Bid(bidder string, amount float64) (string, error) {
Bidder: bidder,
Amount: amount,
Status: "Active",
Time: time.Now(),
}

a.history[len(a.history)-1].Status = "Inactive"
Expand All @@ -87,7 +91,17 @@ func (a *SpecialAuction) WinnerPrice() float64 {
}

func (a *SpecialAuction) WriteLog() {
// Write log
name := fmt.Sprintf("./log/%s-%s.log", time.Now().Format("2006-01-02-15-04-05"), a.Name())
file, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
logrus.Warn("could not open log file")
}
defer file.Close()
for _, bid := range a.history {
file.WriteString(fmt.Sprintf("%s %s %f %s\n", bid.Time.Format("2006-01-02-15-04-05"), bid.Bidder, bid.Amount, bid.Status))
}
file.WriteString(fmt.Sprintf("Winner: %s\n", a.history[len(a.history)-1].Bidder))
file.WriteString(fmt.Sprintf("Winner price: %f\n", a.history[len(a.history)-1].Amount))
}

var specialAuctionBidPattern = regexp.MustCompile(`^/bid (\w+)$`)
Expand Down Expand Up @@ -121,9 +135,16 @@ func (a *SpecialAuction) Auctioneer() func(auctioneer *Auctioneer) {
auctioneer.send <- tgbotapi.NewMessage(auctioneer.chatID, fmt.Sprintf(messages.SPECIAL_AUCTION_PRICE_RAISED_MESSAGE, a.CurrentPrice()))
case bid := <-auctioneer.bidsChannel:
a.Bid(bid.Bidder, a.CurrentPrice())
message := tgbotapi.NewMessage(auctioneer.chatID, fmt.Sprintf(messages.SPECIAL_AUCTION_BID_ACCEPTED_MESSAGE, bid.Bidder))
message.ReplyToMessageID = bid.Update.Message.MessageID
auctioneer.send <- message
auctioneer.stopChannel <- "Auction finished"
return
}
}
}
}

func (a *SpecialAuction) IsPrivateAllowed() bool {
return false
}
47 changes: 31 additions & 16 deletions messages/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,38 @@ package messages

const (
HELP_MESSAGE = "راهنمای استفاده از ربات\n\n" +
"1️⃣ برای شروع یک مناقصه جدید از دستور /start استفاده کنید.\n" +
"این دستور به سه ورودی نام مناقصه (شامل حروف و ارقام)، نمره اولیه (float) و حداقل اختلاف پیشنهاد (float) احتیاج دارد. مثال:\n" +
"/start hw1 3.0 0.05\n\n" +
"2️⃣ برای شرکت در مناقصه فعال از دستور /bid استفاده کنید.\n" +
"این دستور دو ورودی نام مناقصه و نمره پیشنهادی احتیاج دارد. مثال:\n" +
"/bid hw1 2.5"

START_AUCTION_MESSAGE = " مناقصه جدید %s شروع شد.\n\n" +
"نمره اولیه مناقصه: %f\n" +
"حداقل اختلاف میان دو پیشنهاد: %f\n\n" +
"برای شرکت در مناقصه از دستور /bid استفاده کنید.\n"

COUNTDOWN_THREE_MESSAGE = "%f نمره برای این سوال 3️⃣\n" +
"1️⃣ مناقصه عادی همان reverse auction است که در آن نمره‌ی اولیه و حداقل اختلاف اعلام می‌شود؛ سپس افراد پیشنهاد خود را ارسال می‌کنند و وقتی کسی دیگر پیشنهاد جدیدی وارد نکند، پیشنهاد آخر برنده مناقصه می‌شود.\n" +
"برای شروع کردن چنین مناقصه‌ای به سه ورودی نام مناقصه (شامل حروف و ارقام)، نمره اولیه (float) و حداقل اختلاف پیشنهاد (float) احتیاج دارد. مثال:\n" +
"/start reverse_auction hw1 3.0 0.02\n" +
"همچنین برای شرکت در مناقصه باید از دستور /bid استفاده کنید و در ادامه نام مناقصه و نمره پیشنهادی خود را وارد کنید. مثال:\n" +
"/bid hw1 2.9\n\n" +
"2️⃣ مناقصه خاص به این صورت است که از یک نمره کم شروع می‌شود و ذره ذره افزایش می‌یابد. اولین کسی که با توجه به نمره فعلی پیشنهاد را قبول کند، برنده مناقصه خواهد بود.\n" +
"این نوع مناقصه نیز به سه ورودی نام مناقصه (شامل حروف و ارقام)، نمره اولیه (float) و مقدار افزایش در هر گام (float) احتیاج دارد. مثال:\n" +
"/start special_auction hw2 0 0.02\n\n" +
"برای شرکت در مناقصه باید از دستور /bid استفاده کنید و در ادامه نام مناقصه را وارد کنید. مثال:\n" +
"/bid hw2\n"

START_REVERSE_AUCTION_MESSAGE = " مناقصه جدید %s شروع شد.\n\n" +
"در این مناقصه از نمره %f شروع می‌کنیم. در هر لحظه، هر کس می‌تواند پیشنهاد جدیدی ثبت کند، پیشنهاداتی که از آخرین پیشنهاد پذیرفته شده حداقل %f کمتر باشد، پذیرفته می‌شوند.\n" +
"اگر به مدت یک دقیقه هیچ پیشنهادی ثبت نشود، پیشنهاد آخر برنده مناقصه خواهد بود.\n" +
"برای شرکت در مناقصه باید از دستور /bid استفاده کنید و بعد از آن نام مناقصه و نمره پیشنهادی خود را وارد کنید. مثال:\n" +
"/bid %s 2.9\n\n" +
"موفق باشید! 🍀"

START_SPECIAL_AUCTION_MESSAGE = " مناقصه خاص جدید %s شروع شد.\n\n" +
"در این مناقصه از نمره %f شروع می‌کنیم و هر ۱۵ ثانیه ارزش سوال %f افزایش می‌یابد.\n" +
"اولین کسی که پیشنهاد را قبول کند، برنده مناقصه با همان نمره خواهد بود.\n" +
"حواستون باشه که در این نوع از مناقصه شما هیچ عددی را وارد نمی‌کنید. در واقع کافی است که پیام زیر را ارسال کنید تا پیشنهادتان پذیرفته شود.\n" +
"/bid %s\n\n" +
"موفق باشید! 🍀"

COUNTDOWN_THREE_MESSAGE = "3️⃣ پیشنهاد %f نمره برای این سوال داریم! \n" +
"بشتابید و نمره کمتری پیشنهاد دهید."

COUNTDOWN_TWO_MESSAGE = "%f نمره برای این سوال 2️⃣\n" +
COUNTDOWN_TWO_MESSAGE = "2️⃣ پیشنهاد %f نمره برای این سوال \n" +
"کسی نمی‌خواهد پیشنهاد کمتری دهد؟"

COUNTDOWN_ONE_MESSAGE = "%f نمره برای این سوال 1️⃣\n" +
COUNTDOWN_ONE_MESSAGE = "1️⃣ پیشنهاد %f نمره برای این سوال \n" +
"آخرین فرصت برای پیشهاد کمتر رو از دست نده!"

NO_ACTIVE_AUCTION_MESSAGE = "هیچ مناقصه فعالی وجود ندارد."
Expand All @@ -46,5 +59,7 @@ const (

INVALID_START_MESSAGE = "❗️ فرمت شروع یک مناقصه را درست وارد کنید. با استفاده از /help می‌توانید فرمت صحیح را پیدا کنید."

SPECIAL_AUCTION_PRICE_RAISED_MESSAGE = "نمره باری دیگر افزایش یافت و ارزش فعلی آن %f است.\n"
SPECIAL_AUCTION_PRICE_RAISED_MESSAGE = "نمره سوال افزایش یافت و ارزش فعلی سوال %f است.\n"

SPECIAL_AUCTION_BID_ACCEPTED_MESSAGE = "پیشنهاد %s با موفقیت پذیرفته شد!\n"
)
Loading