tamtam/api.go

221 lines
5.5 KiB
Go
Raw Permalink Normal View History

2019-08-09 02:23:30 +03:00
//Package tamtam implements TamTam Bot API.
//Official documentation: https://dev.tamtam.chat/
2019-03-28 17:51:39 +03:00
package tamtam
2019-03-29 01:55:21 +03:00
import (
2019-03-29 17:51:51 +03:00
"context"
2019-03-29 01:55:21 +03:00
"encoding/json"
"io/ioutil"
2019-03-30 22:12:37 +03:00
"log"
2019-03-29 01:55:21 +03:00
"net/http"
"net/url"
"strconv"
2019-03-29 17:51:51 +03:00
"time"
2019-09-05 22:43:32 +03:00
"github.com/neonxp/tamtam/schemes"
2019-03-29 01:55:21 +03:00
)
2019-08-09 02:16:08 +03:00
//Api implements main part of TamTam API
2019-03-29 01:55:21 +03:00
type Api struct {
2019-08-09 02:02:05 +03:00
Bots *bots
Chats *chats
Messages *messages
Subscriptions *subscriptions
Uploads *uploads
client *client
timeout int
pause int
2019-03-29 01:55:21 +03:00
}
// New TamTam Api object
func New(key string) *Api {
2019-08-09 17:52:33 +03:00
timeout := 30
2019-03-29 01:55:21 +03:00
u, _ := url.Parse("https://botapi.tamtam.chat/")
2019-08-09 17:52:33 +03:00
cl := newClient(key, "0.1.8", u, &http.Client{Timeout: time.Duration(timeout) * time.Second})
2019-03-29 01:55:21 +03:00
return &Api{
2019-08-09 02:02:05 +03:00
Bots: newBots(cl),
Chats: newChats(cl),
Uploads: newUploads(cl),
Messages: newMessages(cl),
Subscriptions: newSubscriptions(cl),
client: cl,
2019-08-09 17:52:33 +03:00
timeout: timeout,
2019-08-09 02:02:05 +03:00
pause: 1,
2019-03-29 01:55:21 +03:00
}
}
2019-09-05 22:43:32 +03:00
func (a *Api) bytesToProperUpdate(b []byte) schemes.UpdateInterface {
u := new(schemes.Update)
2019-03-29 17:51:51 +03:00
_ = json.Unmarshal(b, u)
2019-08-09 02:02:05 +03:00
switch u.GetUpdateType() {
2019-09-05 22:43:32 +03:00
case schemes.TypeMessageCallback:
upd := new(schemes.MessageCallbackUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeMessageCreated:
upd := new(schemes.MessageCreatedUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-08-09 17:59:16 +03:00
for _, att := range upd.Message.Body.RawAttachments {
2019-03-29 18:52:22 +03:00
upd.Message.Body.Attachments = append(upd.Message.Body.Attachments, a.bytesToProperAttachment(att))
}
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeMessageRemoved:
upd := new(schemes.MessageRemovedUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeMessageEdited:
upd := new(schemes.MessageEditedUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-08-09 17:59:16 +03:00
for _, att := range upd.Message.Body.RawAttachments {
2019-03-29 18:52:22 +03:00
upd.Message.Body.Attachments = append(upd.Message.Body.Attachments, a.bytesToProperAttachment(att))
}
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeBotAdded:
upd := new(schemes.BotAddedToChatUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeBotRemoved:
upd := new(schemes.BotRemovedFromChatUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeUserAdded:
upd := new(schemes.UserAddedToChatUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeUserRemoved:
upd := new(schemes.UserRemovedFromChatUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeBotStarted:
upd := new(schemes.BotStartedUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
2019-09-05 22:43:32 +03:00
case schemes.TypeChatTitleChanged:
upd := new(schemes.ChatTitleChangedUpdate)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, upd)
2019-03-29 17:51:51 +03:00
return upd
}
return nil
}
2019-09-05 22:43:32 +03:00
func (a *Api) bytesToProperAttachment(b []byte) schemes.AttachmentInterface {
attachment := new(schemes.Attachment)
2019-03-29 18:52:22 +03:00
_ = json.Unmarshal(b, attachment)
2019-08-09 02:02:05 +03:00
switch attachment.GetAttachmentType() {
2019-09-05 22:43:32 +03:00
case schemes.AttachmentAudio:
res := new(schemes.AudioAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentContact:
res := new(schemes.ContactAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentFile:
res := new(schemes.FileAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentImage:
res := new(schemes.PhotoAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentKeyboard:
res := new(schemes.InlineKeyboardAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentLocation:
res := new(schemes.LocationAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentShare:
res := new(schemes.ShareAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentSticker:
res := new(schemes.StickerAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
2019-09-05 22:43:32 +03:00
case schemes.AttachmentVideo:
res := new(schemes.VideoAttachment)
2019-08-09 02:02:05 +03:00
_ = json.Unmarshal(b, res)
2019-03-29 18:52:22 +03:00
return res
}
return attachment
}
2019-11-20 15:14:54 +03:00
func (a *Api) getUpdates(limit int, timeout int, marker int64, types []string) (*schemes.UpdateList, error) {
2019-09-05 22:43:32 +03:00
result := new(schemes.UpdateList)
2019-03-29 01:55:21 +03:00
values := url.Values{}
if limit > 0 {
values.Set("limit", strconv.Itoa(limit))
}
if timeout > 0 {
values.Set("timeout", strconv.Itoa(timeout))
}
if marker > 0 {
2019-11-20 15:14:54 +03:00
values.Set("marker", strconv.Itoa(int(marker)))
2019-03-29 01:55:21 +03:00
}
if len(types) > 0 {
for _, t := range types {
values.Add("types", t)
}
}
2019-08-09 02:02:05 +03:00
body, err := a.client.request(http.MethodGet, "updates", values, nil)
2019-03-29 01:55:21 +03:00
if err != nil {
2021-02-14 13:21:37 +03:00
if err == errLongPollTimeout {
return result, nil
}
2019-03-29 01:55:21 +03:00
return result, err
}
2019-08-09 02:02:05 +03:00
defer func() {
if err := body.Close(); err != nil {
log.Println(err)
}
}()
2019-03-30 22:12:37 +03:00
jb, _ := ioutil.ReadAll(body)
return result, json.Unmarshal(jb, result)
2019-03-29 01:55:21 +03:00
}
//GetUpdates returns updates channel
2019-09-05 22:43:32 +03:00
func (a *Api) GetUpdates(ctx context.Context) chan schemes.UpdateInterface {
ch := make(chan schemes.UpdateInterface)
go func() {
for {
select {
case <-ctx.Done():
close(ch)
return
case <-time.After(time.Duration(a.pause) * time.Second):
2019-11-20 15:14:54 +03:00
var marker int64
for {
upds, err := a.getUpdates(50, a.timeout, marker, []string{})
if err != nil {
log.Println(err)
break
}
if len(upds.Updates) == 0 {
break
}
for _, u := range upds.Updates {
ch <- a.bytesToProperUpdate(u)
}
marker = *upds.Marker
2019-08-09 02:02:05 +03:00
}
}
}
}()
return ch
2019-03-29 01:55:21 +03:00
}
2019-08-09 02:16:08 +03:00
//GetHandler returns http handler for webhooks
2019-08-09 02:02:05 +03:00
func (a *Api) GetHandler(updates chan interface{}) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := r.Body.Close(); err != nil {
log.Println(err)
}
}()
b, _ := ioutil.ReadAll(r.Body)
updates <- a.bytesToProperUpdate(b)
}
}