Message handling: Listen(), AddListener(), Listener

pull/3/head
Ilya Kowalewski 9 years ago
parent 37f537bfab
commit 25b2575f10

@ -0,0 +1,78 @@
package telebot
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func api_getMe(token string) (User, error) {
request := "https://api.telegram.org/bot" + token + "/getMe"
resp, err := http.Get(request)
if err != nil {
return User{}, err
}
defer resp.Body.Close()
me_json, err := ioutil.ReadAll(resp.Body)
if err != nil {
return User{}, err
}
var bot_info struct {
Ok bool
Result User
Description string
}
err = json.Unmarshal(me_json, &bot_info)
if err != nil {
return User{}, err
}
if bot_info.Ok {
return bot_info.Result, nil
} else {
return User{}, AuthError{bot_info.Description}
}
}
func api_getUpdates(token string,
offset int,
updates chan<- Update) error {
command := fmt.Sprintf("getUpdates?offset=%d", offset)
request := "https://api.telegram.org/bot" + token + "/" + command
resp, err := http.Get(request)
if err != nil {
return err
}
defer resp.Body.Close()
updates_json, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
var updates_recieved struct {
Ok bool
Result []Update
Description string
}
err = json.Unmarshal(updates_json, &updates_recieved)
if !updates_recieved.Ok {
log.Println(FetchError{updates_recieved.Description})
return FetchError{updates_recieved.Description}
}
for _, update := range updates_recieved.Result {
updates <- update
}
return nil
}

@ -0,0 +1,44 @@
package telebot
import (
"time"
)
type Bot struct {
Token string
// Bot as `User` on API level.
Identity User
listeners []Listener
}
type Listener func(*Bot, Message)
func (b *Bot) Listen(interval time.Duration) {
updates := make(chan Update, 1000)
var latest_update int
pulse := time.NewTicker(interval)
go func() {
for range pulse.C {
go api_getUpdates(b.Token,
latest_update+1,
updates)
}
}()
for update := range updates {
if update.Id > latest_update {
latest_update = update.Id
}
for _, ear := range b.listeners {
go ear(b, update.Payload)
}
}
}
func (b *Bot) AddListener(ear Listener) {
b.listeners = append(b.listeners, ear)
}

@ -5,6 +5,14 @@ type AuthError struct {
Payload string
}
type FetchError struct {
Payload string
}
func (e AuthError) Error() string {
return "AuthError: " + e.Payload
}
func (e FetchError) Error() string {
return "FetchError: " + e.Payload
}

@ -0,0 +1,9 @@
package telebot
type Message struct {
Id int `json:"message_id"`
Sender User `json:"from"`
Unixtime int `json:"date"`
Text string `json:"text"`
// TBA: `chat`
}

@ -2,51 +2,15 @@
// with Telegram bots.
package telebot
import (
"encoding/json"
"io/ioutil"
"net/http"
)
type Bot struct {
Token string
// Bot as `User` on API level.
Identity User
}
// Attempts to construct a Bot with `token` given.
func Create(token string) (Bot, error) {
request := "https://api.telegram.org/bot" + token + "/getMe"
resp, err := http.Get(request)
if err != nil {
return Bot{}, err
}
defer resp.Body.Close()
me_json, err := ioutil.ReadAll(resp.Body)
if err != nil {
return Bot{}, err
}
var bot_info struct {
Ok bool
Result User
Description string
}
err = json.Unmarshal(me_json, &bot_info)
user, err := api_getMe(token)
if err != nil {
return Bot{}, err
}
if bot_info.Ok {
return Bot{
Token: token,
Identity: bot_info.Result,
}, nil
} else {
return Bot{}, AuthError{bot_info.Description}
}
return Bot{
Token: token,
Identity: user,
}, nil
}

@ -1,6 +1,10 @@
package telebot
import "testing"
import (
"log"
"testing"
"time"
)
const TESTING_TOKEN = "107177593:AAHBJfF3nv3pZXVjXpoowVhv_KSGw56s8zo"
@ -10,3 +14,22 @@ func TestCreate(t *testing.T) {
t.Fatal(err)
}
}
func TestListen(t *testing.T) {
if testing.Short() {
t.Skip("Skipping test in short mode.")
}
bot, err := Create(TESTING_TOKEN)
if err != nil {
t.Fatal(err)
}
bot.AddListener(func(bot *Bot, message Message) {
log.Printf("Recieved a message \"%s\" from user \"%s\"\n",
message.Text, message.Sender.Username)
})
log.Println("Listening...")
bot.Listen(1 * time.Second)
}

@ -0,0 +1,6 @@
package telebot
type Update struct {
Id int `json:"update_id"`
Payload Message `json:"message"`
}
Loading…
Cancel
Save