From cac52711e333ea0287a2526426637e4e76b4219a Mon Sep 17 00:00:00 2001 From: Hamcha Date: Mon, 8 Feb 2016 16:52:13 +0000 Subject: [PATCH] More work, too many changes to list --- .gitignore | 1 + broker/main.go | 9 ++++ broker/telegram.go | 43 ++++++++++++++++ broker/webhook.go | 23 +++++++++ config.json.sample | 6 ++- tg/api.go | 120 +++++++++++++++++++++++++++++++++++++++++++++ tg/command.go | 14 +++++- 7 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 broker/telegram.go create mode 100644 broker/webhook.go create mode 100644 tg/api.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0cffcb3 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +config.json \ No newline at end of file diff --git a/broker/main.go b/broker/main.go index 8697b1e..730c316 100644 --- a/broker/main.go +++ b/broker/main.go @@ -11,6 +11,7 @@ type Config struct { BindServer string /* Address:Port to bind for Telegram */ BindClients string /* Address:Port to bind for clients */ Token string /* Telegram bot token */ + BaseURL string /* Base URL for webhook */ WebhookURL string /* Webhook URL */ } @@ -20,6 +21,8 @@ func assert(err error) { } } +var api Telegram + func main() { cfgpath := flag.String("config", "config.json", "Path to configuration file") flag.Parse() @@ -31,6 +34,9 @@ func main() { err = json.NewDecoder(file).Decode(&config) assert(err) + // Create Telegram API object + api = mkAPI(config.Token) + // Setup webhook handler go func() { http.HandlerFunc(config.Token, webhook) @@ -38,6 +44,9 @@ func main() { assert(err) }() + // Register webhook @ Telegram + api.setWebhook(config.BaseURL + config.WebhookURL) + // Create server for clients startClientsServer(config.BindClients) } diff --git a/broker/telegram.go b/broker/telegram.go new file mode 100644 index 0000000..087efba --- /dev/null +++ b/broker/telegram.go @@ -0,0 +1,43 @@ +package main + +import ( + "io/ioutil" + "log" + "net/http" + "net/url" +) + +const APIEndpoint = "https://api.telegram.org/" + +type Telegram struct { + Token string +} + +func mkAPI(token string) *Telegram { + tg := new(Telegram) + tg.Token = token + return tg +} + +func (t Telegram) setWebhook(webhook string) { + resp, err := http.PostForm(t.apiURL("setWebhook"), url.Values{"url": {webhook}}) + if !checkerr("setWebhook", err) { + defer resp.Body.Close() + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Printf("setWebhook result: %s\n", string(data)) + } + } +} + +func (t Telegram) apiURL(method string) { + return APIEndpoint + "bot" + t.Token + "/" + method +} + +func checkerr(method string, err error) { + if err != nil { + log.Printf("Received error with call to %s: %s\n", method, err.Error()) + return true + } + return false +} diff --git a/broker/webhook.go b/broker/webhook.go new file mode 100644 index 0000000..3a1b991 --- /dev/null +++ b/broker/webhook.go @@ -0,0 +1,23 @@ +package main + +import ( + "encoding/json" + "log" + "net/http" +) + +func webhook(rw http.ResponseWriter, req *http.Request) { + log.Println("Received request! Details follow:") + defer req.Body.Close() + + var update tg.APIUpdate + + err := json.NewDecoder(req.Body).Decode(&update) + if err != nil { + log.Println("ERR: Not JSON!") + return + } + + jenc, _ := json.Marshal(update) + log.Println(jenc) +} diff --git a/config.json.sample b/config.json.sample index 4eb7c3f..da4887c 100644 --- a/config.json.sample +++ b/config.json.sample @@ -1,3 +1,7 @@ { - + "BindServer" : ":7313", + "BindClients": "127.0.0.1:7314", + "Token" : "Bot token here", + "BaseURL" : "https://my.bot.host", + "WebhookURL" : "/secret_url_here" } \ No newline at end of file diff --git a/tg/api.go b/tg/api.go new file mode 100644 index 0000000..0e01927 --- /dev/null +++ b/tg/api.go @@ -0,0 +1,120 @@ +package tg + +type APIUser struct { + UserID int `json:"id"` + FirstName string `json:"first_name"` + LastName string `json:"last_name,omitempty"` + Username string `json:"username,omitempty"` +} + +type ChatType string + +const ( + ChatTypePrivate ChatType = "private" + ChatTypeGroup ChatType = "group" + ChatTypeSupergroup ChatType = "supergroup" + ChatTypeChannel ChatType = "channel" +) + +type APIChat struct { + UserID int `json:"id"` + Type ChatType `json:"type"` + Title string `json:"title,omitempty"` + Username string `json:"username,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` +} + +type APIMessage struct { + MessageID int `json:"message_id"` + User APIUser `json:"from"` + Time int `json:"date"` + Chat APIChat `json:"chat"` + FwdUser APIUpdate `json:"forward_from,omitempty"` + FwdTime int `json:"forward_date,omitempty"` + ReplyTo APIMessage `json:"reply_to_message,omitempty"` + Text string `json:"text,omitempty"` + Audio APIAudio `json:"audio,omitempty"` + Document APIDocument `json:"document,omitempty"` + Photo []APIPhotoSize `json:"photo,omitempty"` + Sticker APISticker `json:"sticker,omitempty"` + Video APIVideo `json:"video,omitempty"` + Voice APIVoice `json:"voice,omitempty"` + Caption string `json:"caption,omitempty"` + Contact APIContact `json:"contact,omitempty"` + Location APILocation `json:"location,omitempty"` + NewUser APIUser `json:"new_chat_partecipant",omitempty"` + LeftUser APIUser `json:"left_chat_partecipant,omitempty"` + PhotoDeleted bool `json:"delete_chat_photo,omitempty"` + GroupCreated bool `json:"group_chat_created,omitempty"` + SupergroupCreated bool `json:"supergroup_chat_created,omitempty"` + ChannelCreated bool `json:"channel_chat_created,omitempty"` + GroupToSuper int `json:"migrate_to_chat_id,omitempty"` + GroupFromSuper int `json:"migrate_from_chat_id,omitempty"` +} + +type APIPhotoSize struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + FileSize int `json:"file_size,omitempty"` +} + +type APIAudio struct { + FileID string `json:"file_id"` + Duration int `json:"duration"` + Performer string `json:"performer,omitempty"` + Title string `json:"title,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +type APIDocument struct { + FileID string `json:"file_id"` + Thumbnail APIPhotoSize `json:"thumb,omitempty"` + Filename string `json:"file_name"` + MimeType string `json:"mime_type,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +type APISticker struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Thumbnail APIPhotoSize `json:"thumb,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +type APIVideo struct { + FileID string `json:"file_id"` + Width int `json:"width"` + Height int `json:"height"` + Duration int `json:"duration"` + Thumbnail APIPhotoSize `json:"thumb,omitempty"` + MimeType string `json:"mime_type,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +type APIVoice struct { + FileID string `json:"file_id"` + Duration int `json:"duration"` + MimeType string `json:"mime_type,omitempty"` + FileSize int `json:"file_size,omitempty"` +} + +type APIContact struct { + PhoneNumber string `json:"phone_number"` + FirstName string `json:"first_name"` + LastName string `json:"last_name,omitempty"` + UserID int `json:"user_id,omitempty"` +} + +type APILocation struct { + Longitude float64 `json:"longitude"` + Latitude float64 `json:"latitude"` +} + +type APIUpdate struct { + UpdateID int `json:"update_id"` + Message APIMessage `json:"message"` +} diff --git a/tg/command.go b/tg/command.go index 638a279..5b7d02c 100644 --- a/tg/command.go +++ b/tg/command.go @@ -1,4 +1,16 @@ package tg -type ClientCommand struct { +type ClientCommandType uint + +const ( + CmdSendMessage ClientCommandType = 1 +) + +type ClientCommandMessageData struct { + MessageText string +} + +type ClientCommand struct { + Type ClientCommandType + MessageData *ClientCommandMessageData }