Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
48 changes: 44 additions & 4 deletions auth/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,29 @@ func (m *MailNotificationConfig) Customize(ctx context.Context, msg *sendgrid.SG
}
}

type TelegramNotificationConfig struct {
BodyTemplate string `methods:"PUT" datastore:",noindex"`
}

func (m *TelegramNotificationConfig) Validate() error {
if m.BodyTemplate != "" {
if _, err := raymond.Parse(m.BodyTemplate); err != nil {
return err
}
}
return nil
}

func (m *TelegramNotificationConfig) Customize(ctx context.Context, msg *string, data interface{}) {
if m.BodyTemplate != "" {
if customTextBody, err := raymond.Render(m.BodyTemplate, data); err == nil {
*msg = customTextBody
} else {
log.Infof(ctx, "Broken BodyTemplate %q: %v", m.BodyTemplate, err)
}
}
}

type FCMToken struct {
Value string `methods:"PUT"`
Disabled bool `methods:"PUT"`
Expand Down Expand Up @@ -173,12 +196,29 @@ func (m *MailConfig) Validate() error {
return nil
}

type TelegramConfig struct {
Enabled bool `methods:"PUT"`
MessageConfig TelegramNotificationConfig `methods:"PUT"`
PhaseConfig TelegramNotificationConfig `methods:"PUT"`
}

func (m *TelegramConfig) Validate() error {
if err := m.MessageConfig.Validate(); err != nil {
return err
}
if err := m.PhaseConfig.Validate(); err != nil {
return err
}
return nil
}

type UserConfig struct {
UserId string
FCMTokens []FCMToken `methods:"PUT"`
MailConfig MailConfig `methods:"PUT"`
Colors []string `methods:"PUT"`
PhaseDeadlineWarningMinutesAhead int `methods:"PUT"`
FCMTokens []FCMToken `methods:"PUT"`
MailConfig MailConfig `methods:"PUT"`
TelegramConfig TelegramConfig `methods:"PUT"`
Colors []string `methods:"PUT"`
PhaseDeadlineWarningMinutesAhead int `methods:"PUT"`
}

func (u *UserConfig) Load(props []datastore.Property) error {
Expand Down
16 changes: 12 additions & 4 deletions game/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ const (
RemoveDIASFromSoloGamesRoute = "RemoveDIASFromSoloGamesRoute"
ReComputeAllDIASUsersRoute = "ReComputeAllDIASUsers"
SendSystemMessageRoute = "SendSystemMessage"
TelegramWebhookRoute = "TelegramWebhook"
)

type userStatsHandler struct {
Expand Down Expand Up @@ -567,10 +568,11 @@ func createAllocation(w ResponseWriter, r Request) (*Allocation, error) {
}

type configuration struct {
OAuth *auth.OAuth
FCMConf *FCMConf
SendGrid *SendGrid
Superusers *auth.Superusers
OAuth *auth.OAuth
FCMConf *FCMConf
SendGrid *SendGrid
Superusers *auth.Superusers
TelegramConf *TelegramConf
}

func handleConfigure(w ResponseWriter, r Request) error {
Expand Down Expand Up @@ -600,6 +602,11 @@ func handleConfigure(w ResponseWriter, r Request) error {
return err
}
}
if conf.TelegramConf != nil {
if err := SetTelegramConf(ctx, conf.TelegramConf); err != nil {
return err
}
}
return nil
}

Expand Down Expand Up @@ -1256,6 +1263,7 @@ func ejectMember(ctx context.Context, gameID *datastore.Key, userId string) erro

func SetupRouter(r *mux.Router) {
router = r
Handle(r, "/_telegram_webhook", []string{"POST"}, TelegramWebhookRoute, handleTelegramWebhook)
Handle(r, "/_reap-inactive-waiting-players", []string{"GET"}, ReapInactiveWaitingPlayersRoute, handleReapInactiveWaitingPlayers)
Handle(r, "/_test_reap-inactive-waiting-players", []string{"GET"}, TestReapInactiveWaitingPlayersRoute, handleTestReapInactiveWaitingPlayers)
Handle(r, "/_re-save", []string{"GET"}, ReSaveRoute, handleReSave)
Expand Down
85 changes: 85 additions & 0 deletions game/telegram.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package game

import (
"encoding/json"
"net/http"

"golang.org/x/net/context"
"google.golang.org/appengine"
"google.golang.org/appengine/datastore"
"google.golang.org/appengine/log"

. "github.com/zond/goaeoas"
)

const (
telegramConfKind = "TelegramConf"
)

type TelegramConf struct {
BotToken string
}

func getTelegramConfKey(ctx context.Context) *datastore.Key {
return datastore.NewKey(ctx, telegramConfKind, prodKey, 0, nil)
}

func SetTelegramConf(ctx context.Context, telegramConf *TelegramConf) error {
return datastore.RunInTransaction(ctx, func(ctx context.Context) error {
currentTelegramConf := &TelegramConf{}
if err := datastore.Get(ctx, getTelegramConfKey(ctx), currentTelegramConf); err == nil {
return HTTPErr{"TelegramConf already configured", http.StatusBadRequest}
}
if _, err := datastore.Put(ctx, getTelegramConfKey(ctx), telegramConf); err != nil {
return err
}
return nil
}, &datastore.TransactionOptions{XG: false})
}

type TelegramUser struct {
ID int64 `json:"id"`
IsBot bool `json:"is_bot"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
LanguageCode string `json:"language_code"`
}

type TelegramChat struct {
ID int64 `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
Type string `json:"type"`
}

type TelegramEntity struct {
Offset int64 `json:"offset"`
Length int64 `json:"length"`
Type string `json:"type"`
}

type TelegramMessage struct {
MessageID int64 `json:"message"`
From TelegramUser `json:"from"`
Chat TelegramChat `json:"chat"`
Date int64 `json:"date"`
Text string `json:"text"`
Entities []TelegramEntity `json:"entities"`
}

type TelegramUpdate struct {
UpdateID int64 `json:"update_id"`
Message TelegramMessage `json:"message"`
}

func handleTelegramWebhook(w ResponseWriter, r Request) error {
ctx := appengine.NewContext(r.Req())

update := &TelegramUpdate{}
if err := json.NewDecoder(r.Req().Body).Decode(update); err != nil {
return err
}

log.Infof(ctx, "Got telegram update %+v", update)
return nil
}