2021-01-22 21:47:22 +00:00
|
|
|
// Package groupme defines a client capable of executing API commands for the GroupMe chat service
|
2020-07-30 02:20:57 +00:00
|
|
|
package groupme
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Meta is the error type returned in the GroupMe response.
|
|
|
|
// Meant for clients that can't read HTTP status codes
|
|
|
|
type Meta struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
Code HTTPStatusCode `json:"code,omitempty"`
|
|
|
|
Errors []string `json:"errors,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Error returns the code and the error list as a string.
|
|
|
|
// Satisfies the error interface
|
|
|
|
func (m Meta) Error() string {
|
|
|
|
return fmt.Sprintf("Error Code %d: %v", m.Code, m.Errors)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Group is a GroupMe group, returned in JSON API responses
|
|
|
|
type Group struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
ID ID `json:"id,omitempty"`
|
|
|
|
Name string `json:"name,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
// Type of group (private|public)
|
2020-08-29 02:04:52 +00:00
|
|
|
Type string `json:"type,omitempty"`
|
|
|
|
Description string `json:"description,omitempty"`
|
|
|
|
ImageURL string `json:"image_url,omitempty"`
|
|
|
|
CreatorUserID ID `json:"creator_user_id,omitempty"`
|
|
|
|
CreatedAt Timestamp `json:"created_at,omitempty"`
|
|
|
|
UpdatedAt Timestamp `json:"updated_at,omitempty"`
|
|
|
|
Members []*Member `json:"members,omitempty"`
|
|
|
|
ShareURL string `json:"share_url,omitempty"`
|
|
|
|
Messages GroupMessages `json:"messages,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GroupMessages is a Group field, only returned in Group JSON API responses
|
|
|
|
type GroupMessages struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
Count uint `json:"count,omitempty"`
|
|
|
|
LastMessageID ID `json:"last_message_id,omitempty"`
|
|
|
|
LastMessageCreatedAt Timestamp `json:"last_message_created_at,omitempty"`
|
|
|
|
Preview MessagePreview `json:"preview,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MessagePreview is a GroupMessages field, only returned in Group JSON API responses.
|
|
|
|
// Abbreviated form of Message type
|
|
|
|
type MessagePreview struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
Nickname string `json:"nickname,omitempty"`
|
|
|
|
Text string `json:"text,omitempty"`
|
|
|
|
ImageURL string `json:"image_url,omitempty"`
|
|
|
|
Attachments []*Attachment `json:"attachments,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetMemberByUserID gets the group member by their UserID,
|
|
|
|
// nil if no member matches
|
2021-01-22 21:47:22 +00:00
|
|
|
func (g *Group) GetMemberByUserID(userID ID) *Member {
|
2020-07-30 02:20:57 +00:00
|
|
|
for _, member := range g.Members {
|
|
|
|
if member.UserID == userID {
|
|
|
|
return member
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetMemberByNickname gets the group member by their Nickname,
|
|
|
|
// nil if no member matches
|
2021-01-22 21:47:22 +00:00
|
|
|
func (g *Group) GetMemberByNickname(nickname string) *Member {
|
2020-07-30 02:20:57 +00:00
|
|
|
for _, member := range g.Members {
|
|
|
|
if member.Nickname == nickname {
|
|
|
|
return member
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (g *Group) String() string {
|
|
|
|
return marshal(g)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Member is a GroupMe group member, returned in JSON API responses
|
|
|
|
type Member struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
ID ID `json:"id,omitempty"`
|
|
|
|
UserID ID `json:"user_id,omitempty"`
|
|
|
|
Nickname string `json:"nickname,omitempty"`
|
|
|
|
Muted bool `json:"muted,omitempty"`
|
|
|
|
ImageURL string `json:"image_url,omitempty"`
|
|
|
|
AutoKicked bool `json:"autokicked,omitempty"`
|
|
|
|
AppInstalled bool `json:"app_installed,omitempty"`
|
|
|
|
GUID string `json:"guid,omitempty"`
|
2020-12-13 19:00:44 +00:00
|
|
|
PhoneNumber string `json:"phone_number,omitempty"` // Only used when searching for the member to add to a group.
|
|
|
|
Email string `json:"email,omitempty"` // Only used when searching for the member to add to a group.
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (m *Member) String() string {
|
|
|
|
return marshal(m)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Message is a GroupMe group message, returned in JSON API responses
|
|
|
|
type Message struct {
|
2021-05-08 19:36:50 +00:00
|
|
|
ID ID `json:"id,omitempty"`
|
|
|
|
SourceGUID string `json:"source_guid,omitempty"`
|
|
|
|
CreatedAt Timestamp `json:"created_at,omitempty"`
|
|
|
|
GroupID ID `json:"group_id,omitempty"`
|
|
|
|
UserID ID `json:"user_id,omitempty"`
|
|
|
|
BotID ID `json:"bot_id,omitempty"`
|
|
|
|
SenderID ID `json:"sender_id,omitempty"`
|
|
|
|
SenderType senderType `json:"sender_type,omitempty"`
|
|
|
|
System bool `json:"system,omitempty"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
RecipientID ID `json:"recipient_id,omitempty"`
|
|
|
|
//ChatID - over push ConversationID seems to be called ChatID
|
|
|
|
ChatID ID `json:"chat_id,omitempty"`
|
|
|
|
ConversationID ID `json:"conversation_id,omitempty"`
|
|
|
|
AvatarURL string `json:"avatar_url,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
// Maximum length of 1000 characters
|
2020-08-29 02:04:52 +00:00
|
|
|
Text string `json:"text,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
// Must be an image service URL (i.groupme.com)
|
2020-08-29 02:04:52 +00:00
|
|
|
ImageURL string `json:"image_url,omitempty"`
|
|
|
|
FavoritedBy []string `json:"favorited_by,omitempty"`
|
|
|
|
Attachments []*Attachment `json:"attachments,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (m *Message) String() string {
|
|
|
|
return marshal(m)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
type senderType string
|
2020-07-30 02:20:57 +00:00
|
|
|
|
|
|
|
// SenderType constants
|
|
|
|
const (
|
2021-01-22 21:47:22 +00:00
|
|
|
SenderTypeUser senderType = "user"
|
|
|
|
SenderTypeBot senderType = "bot"
|
|
|
|
SenderTypeSystem senderType = "system"
|
2020-07-30 02:20:57 +00:00
|
|
|
)
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
type attachmentType string
|
2020-07-30 02:20:57 +00:00
|
|
|
|
|
|
|
// AttachmentType constants
|
|
|
|
const (
|
2021-01-22 21:47:22 +00:00
|
|
|
Mentions attachmentType = "mentions"
|
|
|
|
Image attachmentType = "image"
|
|
|
|
Location attachmentType = "location"
|
|
|
|
Emoji attachmentType = "emoji"
|
2020-07-30 02:20:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Attachment is a GroupMe message attachment, returned in JSON API responses
|
|
|
|
type Attachment struct {
|
2021-05-08 19:38:54 +00:00
|
|
|
Type attachmentType `json:"type,omitempty"`
|
|
|
|
Loci [][]int `json:"loci,omitempty"`
|
|
|
|
UserIDs []ID `json:"user_ids,omitempty"`
|
|
|
|
URL string `json:"url,omitempty"`
|
|
|
|
FileID string `json:"file_id,omitempty"`
|
|
|
|
VideoPreviewURL string `json:"preview_url,omitempty"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
Latitude string `json:"lat,omitempty"`
|
|
|
|
Longitude string `json:"lng,omitempty"`
|
|
|
|
Placeholder string `json:"placeholder,omitempty"`
|
|
|
|
Charmap [][]int `json:"charmap,omitempty"`
|
|
|
|
ReplyID ID `json:"reply_id,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (a *Attachment) String() string {
|
|
|
|
return marshal(a)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// User is a GroupMe user, returned in JSON API responses
|
|
|
|
type User struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
ID ID `json:"id,omitempty"`
|
|
|
|
PhoneNumber PhoneNumber `json:"phone_number,omitempty"`
|
|
|
|
ImageURL string `json:"image_url,omitempty"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
CreatedAt Timestamp `json:"created_at,omitempty"`
|
|
|
|
UpdatedAt Timestamp `json:"updated_at,omitempty"`
|
|
|
|
AvatarURL string `json:"avatar_url,omitempty"`
|
|
|
|
Email string `json:"email,omitempty"`
|
|
|
|
SMS bool `json:"sms,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (u *User) String() string {
|
|
|
|
return marshal(u)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Chat is a GroupMe direct message conversation between two users,
|
|
|
|
// returned in JSON API responses
|
|
|
|
type Chat struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
CreatedAt Timestamp `json:"created_at,omitempty"`
|
|
|
|
UpdatedAt Timestamp `json:"updated_at,omitempty"`
|
|
|
|
LastMessage *Message `json:"last_message,omitempty"`
|
|
|
|
MessagesCount int `json:"messages_count,omitempty"`
|
|
|
|
OtherUser User `json:"other_user,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (c *Chat) String() string {
|
|
|
|
return marshal(c)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
// Bot is a GroupMe bot, it is connected to a specific group which it can send messages to
|
2020-07-30 02:20:57 +00:00
|
|
|
type Bot struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
BotID ID `json:"bot_id,omitempty"`
|
|
|
|
GroupID ID `json:"group_id,omitempty"`
|
|
|
|
Name string `json:"name,omitempty"`
|
|
|
|
AvatarURL string `json:"avatar_url,omitempty"`
|
|
|
|
CallbackURL string `json:"callback_url,omitempty"`
|
|
|
|
DMNotification bool `json:"dm_notification,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
func (b *Bot) String() string {
|
|
|
|
return marshal(b)
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 21:47:22 +00:00
|
|
|
// Block is a GroupMe block between two users, direct messages are not allowed
|
2020-07-30 02:20:57 +00:00
|
|
|
type Block struct {
|
2020-08-29 02:04:52 +00:00
|
|
|
UserID ID `json:"user_id,omitempty"`
|
|
|
|
BlockedUserID ID `json:"blocked_user_id,omitempty"`
|
|
|
|
CreatedAT Timestamp `json:"created_at,omitempty"`
|
2020-07-30 02:20:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b Block) String() string {
|
|
|
|
return marshal(&b)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Superficially increases test coverage
|
|
|
|
func marshal(i interface{}) string {
|
|
|
|
bytes, err := json.MarshalIndent(i, "", "\t")
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(bytes)
|
|
|
|
}
|