158 lines
4.5 KiB
Go
158 lines
4.5 KiB
Go
// Package groupme defines a client capable of executing API commands for the GroupMe chat service
|
|
package groupme
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
// GroupMe documentation: https://dev.groupme.com/docs/v3#messages
|
|
|
|
/*//////// Endpoints ////////*/
|
|
const (
|
|
// Used to build other endpoints
|
|
messagesEndpointRoot = groupEndpointRoot + "/messages"
|
|
|
|
indexMessagesEndpoint = messagesEndpointRoot // GET
|
|
createMessagesEndpoint = messagesEndpointRoot // POST
|
|
)
|
|
|
|
// IndexMessagesQuery defines the optional URL parameters for IndexMessages
|
|
type IndexMessagesQuery struct {
|
|
// Returns messages created before the given message ID
|
|
BeforeID ID
|
|
// Returns most recent messages created after the given message ID
|
|
SinceID ID
|
|
// Returns messages created immediately after the given message ID
|
|
AfterID ID
|
|
// Number of messages returned. Default is 20. Max is 100.
|
|
Limit int
|
|
}
|
|
|
|
func (q IndexMessagesQuery) String() string {
|
|
return marshal(&q)
|
|
}
|
|
|
|
// IndexMessagesResponse contains the count and set of
|
|
// messages returned by the IndexMessages API request
|
|
type IndexMessagesResponse struct {
|
|
Count int `json:"count"`
|
|
Messages []*Message `json:"messages"`
|
|
}
|
|
|
|
func (r IndexMessagesResponse) String() string {
|
|
return marshal(&r)
|
|
}
|
|
|
|
/*
|
|
IndexMessages - Retrieves messages for a group.
|
|
By default, messages are returned in groups of 20, ordered by
|
|
created_at descending. This can be raised or lowered by passing
|
|
a limit parameter, up to a maximum of 100 messages.
|
|
Messages can be scanned by providing a message ID as either the
|
|
before_id, since_id, or after_id parameter. If before_id is
|
|
provided, then messages immediately preceding the given message
|
|
will be returned, in descending order. This can be used to
|
|
continually page back through a group's messages.
|
|
The after_id parameter will return messages that immediately
|
|
follow a given message, this time in ascending order (which
|
|
makes it easy to pick off the last result for continued
|
|
pagination).
|
|
Finally, the since_id parameter also returns messages created
|
|
after the given message, but it retrieves the most recent
|
|
messages. For example, if more than twenty messages are created
|
|
after the since_id message, using this parameter will omit the
|
|
messages that immediately follow the given message. This is a
|
|
bit counterintuitive, so take care.
|
|
If no messages are found (e.g. when filtering with before_id)
|
|
we return code 304.
|
|
Note that for historical reasons, likes are returned as an
|
|
array of user ids in the favorited_by key.
|
|
*/
|
|
func (c *Client) IndexMessages(ctx context.Context, groupID ID, req *IndexMessagesQuery, authToken string) (IndexMessagesResponse, error) {
|
|
url := fmt.Sprintf(c.endpointBase+indexMessagesEndpoint, groupID)
|
|
httpReq, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return IndexMessagesResponse{}, err
|
|
}
|
|
|
|
URL := httpReq.URL
|
|
query := URL.Query()
|
|
if req != nil {
|
|
if req.BeforeID != "" {
|
|
query.Add("before_id", req.BeforeID.String())
|
|
}
|
|
if req.SinceID != "" {
|
|
query.Add("since_id", req.SinceID.String())
|
|
}
|
|
if req.AfterID != "" {
|
|
query.Add("after_id", req.AfterID.String())
|
|
}
|
|
if req.Limit != 0 {
|
|
query.Add("limit", strconv.Itoa(req.Limit))
|
|
}
|
|
}
|
|
URL.RawQuery = query.Encode()
|
|
|
|
var resp IndexMessagesResponse
|
|
err = c.doWithAuthToken(ctx, httpReq, &resp, authToken)
|
|
if err != nil {
|
|
return IndexMessagesResponse{}, err
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
/*
|
|
CreateMessage - Send a message to a group
|
|
|
|
If you want to attach an image, you must first process it
|
|
through our image service.
|
|
|
|
Attachments of type emoji rely on data from emoji PowerUps.
|
|
|
|
Clients use a placeholder character in the message text and
|
|
specify a replacement charmap to substitute emoji characters
|
|
|
|
The character map is an array of arrays containing rune data
|
|
([[{pack_id,offset}],...]).
|
|
|
|
The placeholder should be a high-point/invisible UTF-8 character.
|
|
*/
|
|
func (c *Client) CreateMessage(ctx context.Context, groupID ID, m *Message, authToken string) (*Message, error) {
|
|
URL := fmt.Sprintf(c.endpointBase+createMessagesEndpoint, groupID)
|
|
|
|
m.SourceGUID = uuid.New().String()
|
|
var data = struct {
|
|
Message *Message `json:"message"`
|
|
}{
|
|
m,
|
|
}
|
|
|
|
jsonBytes, err := json.Marshal(&data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
httpReq, err := http.NewRequest("POST", URL, bytes.NewBuffer(jsonBytes))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var resp struct {
|
|
*Message `json:"message"`
|
|
}
|
|
err = c.doWithAuthToken(ctx, httpReq, &resp, authToken)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp.Message, nil
|
|
}
|