feat: Initial commit
This commit is contained in:
commit
1ac8367a50
5 changed files with 307 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
uber-tracker
|
5
go.mod
Normal file
5
go.mod
Normal file
|
@ -0,0 +1,5 @@
|
|||
module uber-tracker
|
||||
|
||||
go 1.15
|
||||
|
||||
require git.ddd.rip/ptrcnull/telegram v0.0.4
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
|||
git.ddd.rip/ptrcnull/telegram v0.0.4 h1:b4VaLAdIUuEFG5DRM+JzfLEVoe4tdHhrgxtmoF2UJOQ=
|
||||
git.ddd.rip/ptrcnull/telegram v0.0.4/go.mod h1:SSSKvfhw7mDx/8UPoLdtP9J74z2/pXccHnKzdi16nLA=
|
145
main.go
Normal file
145
main.go
Normal file
|
@ -0,0 +1,145 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"git.ddd.rip/ptrcnull/telegram"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func GetUberData(uuid string) (*UberDataOrder, error) {
|
||||
requestBody := []byte(fmt.Sprintf("{\"orderUuid\":\"%s\"}", uuid))
|
||||
req, err := http.NewRequest("POST", "https://www.ubereats.com/api/getActiveOrdersV1", bytes.NewBuffer(requestBody))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("x-csrf-token", "x")
|
||||
|
||||
res, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if res.StatusCode != 200 {
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
log.Println(string(body), err)
|
||||
return nil, fmt.Errorf("unexpected status code: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
var data UberResponse
|
||||
err = json.NewDecoder(res.Body).Decode(&data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, order := range data.Data.Orders {
|
||||
if order.UUID == uuid {
|
||||
return &order, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("order not found: %s", uuid)
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
ChatID string
|
||||
UberData *UberDataOrder
|
||||
MessageID string
|
||||
}
|
||||
|
||||
func main() {
|
||||
c := telegram.Client{
|
||||
Token: os.Getenv("TELEGRAM_TOKEN"),
|
||||
}
|
||||
sendMessage := func(chatId, body string) *telegram.SendMessageResponse {
|
||||
res, err := c.SendMessage(chatId, body)
|
||||
if err != nil {
|
||||
log.Println("error sending message:", err)
|
||||
return nil
|
||||
}
|
||||
return res
|
||||
}
|
||||
var orders []*Order
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(1 * time.Second)
|
||||
for i, order := range orders {
|
||||
log.Println("Getting data for order", order.UberData.UUID)
|
||||
newData, err := GetUberData(order.UberData.UUID)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sendMessage(order.ChatID, "order completed: "+order.UberData.UUID)
|
||||
orders = append(orders[:i], orders[i+1:]...)
|
||||
continue
|
||||
}
|
||||
oldStatus := order.UberData.Status()
|
||||
newStatus := newData.Status()
|
||||
if oldStatus != newStatus {
|
||||
_, err := c.EditMessageText(order.ChatID, order.MessageID, newStatus)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
order.UberData = newData
|
||||
}
|
||||
}
|
||||
}()
|
||||
for {
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
log.Println("Getting updates...")
|
||||
upd, err := c.GetUpdates()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
log.Println("updates:", len(upd.Result))
|
||||
for _, update := range upd.Result {
|
||||
if update.Message != nil && strings.HasPrefix(update.Message.Text, "/add") {
|
||||
chatId := strconv.FormatInt(update.Message.Chat.ID, 10)
|
||||
|
||||
orderId := strings.Split(update.Message.Text, " ")[1]
|
||||
data, err := GetUberData(orderId)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sendMessage(chatId, "error: "+err.Error())
|
||||
continue
|
||||
}
|
||||
log.Printf("%#v\n", data)
|
||||
sendMessage(chatId, "added new order: "+data.OrderInfo.StoreInfo.Name)
|
||||
status := data.Status()
|
||||
res := sendMessage(chatId, status)
|
||||
if res != nil {
|
||||
orders = append(orders, &Order{
|
||||
ChatID: chatId,
|
||||
UberData: data,
|
||||
MessageID: strconv.FormatInt(res.Result.MessageID, 10),
|
||||
})
|
||||
}
|
||||
}
|
||||
if update.Message != nil && strings.HasPrefix(update.Message.Text, "/contact") {
|
||||
chatId := strconv.FormatInt(update.Message.Chat.ID, 10)
|
||||
|
||||
orderId := strings.Split(update.Message.Text, " ")[1]
|
||||
data, err := GetUberData(orderId)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
sendMessage(chatId, "error: "+err.Error())
|
||||
continue
|
||||
}
|
||||
for _, contact := range data.Contacts {
|
||||
sendMessage(chatId, contact.Title + ": " + contact.FormattedPhoneNumber)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
154
types.go
Normal file
154
types.go
Normal file
|
@ -0,0 +1,154 @@
|
|||
package main
|
||||
|
||||
type UberResponse struct {
|
||||
Status string `json:"status"`
|
||||
Data UberData `json:"data"`
|
||||
}
|
||||
|
||||
type UberData struct {
|
||||
Orders []UberDataOrder `json:"orders"`
|
||||
}
|
||||
|
||||
type Contact struct {
|
||||
Type string `json:"type"`
|
||||
Title string `json:"title"`
|
||||
PhoneNumber string `json:"phoneNumber"`
|
||||
FormattedPhoneNumber string `json:"formattedPhoneNumber"`
|
||||
}
|
||||
|
||||
type ActiveOrderOverview struct {
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
BackgroundImageURL string `json:"backgroundImageUrl"`
|
||||
Items []struct {
|
||||
ShoppingCartItemUUID string `json:"shoppingCartItemUUID"`
|
||||
Title string `json:"title"`
|
||||
Quantity int `json:"quantity"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
} `json:"items"`
|
||||
Actions interface{} `json:"actions"`
|
||||
}
|
||||
|
||||
type InAppNotification struct {
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
}
|
||||
|
||||
type FeedCardStatus struct {
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
TimelineSummary string `json:"timelineSummary"`
|
||||
StatusSummary struct {
|
||||
Text string `json:"text"`
|
||||
InfoText string `json:"infoText"`
|
||||
InfoBody string `json:"infoBody"`
|
||||
} `json:"statusSummary"`
|
||||
CurrentProgress int `json:"currentProgress"`
|
||||
TotalProgressSegments int `json:"totalProgressSegments"`
|
||||
AnimateCurrentProgressSegment bool `json:"animateCurrentProgressSegment"`
|
||||
Actions interface{} `json:"actions"`
|
||||
}
|
||||
|
||||
type FeedCard struct {
|
||||
Status FeedCardStatus `json:"status,omitempty"`
|
||||
MapEntity interface{} `json:"mapEntity"`
|
||||
Courier interface{} `json:"courier"`
|
||||
Type string `json:"type"`
|
||||
Savings struct {
|
||||
Title string `json:"title"`
|
||||
IconImageURL string `json:"iconImageUrl"`
|
||||
} `json:"savings,omitempty"`
|
||||
Delivery struct {
|
||||
FormattedAddress string `json:"formattedAddress"`
|
||||
DeliveryTypeDescription string `json:"deliveryTypeDescription"`
|
||||
SpecialInstructions string `json:"specialInstructions"`
|
||||
Title string `json:"title"`
|
||||
Paragraphs []struct {
|
||||
Title string `json:"title"`
|
||||
Subtitle string `json:"subtitle,omitempty"`
|
||||
} `json:"paragraphs"`
|
||||
} `json:"delivery,omitempty"`
|
||||
OrderSummary struct {
|
||||
RestaurantName string `json:"restaurantName"`
|
||||
Items []struct {
|
||||
ShoppingCartItemUUID string `json:"shoppingCartItemUUID"`
|
||||
Title string `json:"title"`
|
||||
Quantity int `json:"quantity"`
|
||||
Subtitle string `json:"subtitle"`
|
||||
} `json:"items"`
|
||||
Total string `json:"total"`
|
||||
Sections []interface{} `json:"sections"`
|
||||
TotalLabel string `json:"totalLabel"`
|
||||
} `json:"orderSummary,omitempty"`
|
||||
}
|
||||
|
||||
type BackgroundFeedCard struct {
|
||||
MapEntity []struct {
|
||||
UUID string `json:"uuid"`
|
||||
Type string `json:"type"`
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
Course float64 `json:"course,omitempty"`
|
||||
Subtitle interface{} `json:"subtitle"`
|
||||
PathPoints []struct {
|
||||
Epoch int64 `json:"epoch"`
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
Course float64 `json:"course"`
|
||||
} `json:"pathPoints"`
|
||||
IconURL string `json:"iconUrl,omitempty"`
|
||||
SpriteCount int `json:"spriteCount,omitempty"`
|
||||
SpriteSize int `json:"spriteSize,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
} `json:"mapEntity"`
|
||||
Courier interface{} `json:"courier"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type UberDataOrder struct {
|
||||
UUID string `json:"uuid"`
|
||||
Contacts []Contact `json:"contacts"`
|
||||
Actions interface{} `json:"actions"`
|
||||
BottomSheets interface{} `json:"bottomSheets"`
|
||||
OrderInfo OrderInfo `json:"orderInfo"`
|
||||
ActiveOrderOverview ActiveOrderOverview `json:"activeOrderOverview"`
|
||||
InAppNotification InAppNotification `json:"inAppNotification"`
|
||||
FeedCards []FeedCard `json:"feedCards"`
|
||||
BackgroundFeedCards []BackgroundFeedCard `json:"backgroundFeedCards"`
|
||||
Layout string `json:"layout"`
|
||||
}
|
||||
|
||||
func (o *UberDataOrder) Status() string {
|
||||
for _, feedCard := range o.FeedCards {
|
||||
if feedCard.Type == "status" {
|
||||
c := feedCard.Status
|
||||
return c.Subtitle + " " + c.Title + "\n" + c.TimelineSummary
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type OrderInfo struct {
|
||||
OrderPhase string `json:"orderPhase"`
|
||||
StoreInfo struct {
|
||||
StoreUUID string `json:"storeUUID"`
|
||||
TerritoryUUID string `json:"territoryUUID"`
|
||||
Location struct {
|
||||
Address struct {
|
||||
Address1 string `json:"address1"`
|
||||
City string `json:"city"`
|
||||
Country string `json:"country"`
|
||||
PostalCode string `json:"postalCode"`
|
||||
Region string `json:"region"`
|
||||
UUID string `json:"uuid"`
|
||||
} `json:"address"`
|
||||
Latitude float64 `json:"latitude"`
|
||||
Longitude float64 `json:"longitude"`
|
||||
} `json:"location"`
|
||||
WebURL string `json:"webURL"`
|
||||
HeroImageURL string `json:"heroImageURL"`
|
||||
Name string `json:"name"`
|
||||
} `json:"storeInfo"`
|
||||
OrderCategory string `json:"orderCategory"`
|
||||
CustomerInfos interface{} `json:"customerInfos"`
|
||||
}
|
Loading…
Reference in a new issue