195 lines
4.9 KiB
Go
195 lines
4.9 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/alcionai/clues"
|
|
"github.com/microsoft/kiota-abstractions-go/serialization"
|
|
"github.com/microsoftgraph/msgraph-sdk-go/models"
|
|
"github.com/microsoftgraph/msgraph-sdk-go/teams"
|
|
|
|
"github.com/alcionai/corso/src/internal/common/ptr"
|
|
"github.com/alcionai/corso/src/internal/m365/graph"
|
|
"github.com/alcionai/corso/src/pkg/backup/details"
|
|
"github.com/alcionai/corso/src/pkg/fault"
|
|
"github.com/alcionai/corso/src/pkg/logger"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// controller
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func (c Client) Channels() Channels {
|
|
return Channels{c}
|
|
}
|
|
|
|
// Channels is an interface-compliant provider of the client.
|
|
type Channels struct {
|
|
Client
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// containers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func (c Channels) GetChannel(
|
|
ctx context.Context,
|
|
teamID, containerID string,
|
|
) (models.Channelable, error) {
|
|
config := &teams.ItemChannelsChannelItemRequestBuilderGetRequestConfiguration{
|
|
QueryParameters: &teams.ItemChannelsChannelItemRequestBuilderGetQueryParameters{
|
|
Select: idAnd("displayName"),
|
|
},
|
|
}
|
|
|
|
resp, err := c.Stable.
|
|
Client().
|
|
Teams().
|
|
ByTeamId(teamID).
|
|
Channels().
|
|
ByChannelId(containerID).
|
|
Get(ctx, config)
|
|
if err != nil {
|
|
return nil, graph.Stack(ctx, err)
|
|
}
|
|
|
|
return resp, nil
|
|
}
|
|
|
|
// GetChannelByName fetches a channel by name
|
|
func (c Channels) GetChannelByName(
|
|
ctx context.Context,
|
|
teamID, containerName string,
|
|
) (models.Channelable, error) {
|
|
ctx = clues.Add(ctx, "channel_name", containerName)
|
|
|
|
filter := fmt.Sprintf("displayName eq '%s'", containerName)
|
|
options := &teams.ItemChannelsRequestBuilderGetRequestConfiguration{
|
|
QueryParameters: &teams.ItemChannelsRequestBuilderGetQueryParameters{
|
|
Filter: &filter,
|
|
},
|
|
}
|
|
|
|
resp, err := c.Stable.
|
|
Client().
|
|
Teams().
|
|
ByTeamId(teamID).
|
|
Channels().
|
|
Get(ctx, options)
|
|
if err != nil {
|
|
return nil, graph.Stack(ctx, err).WithClues(ctx)
|
|
}
|
|
|
|
gv := resp.GetValue()
|
|
if len(gv) == 0 {
|
|
return nil, clues.New("channel not found").WithClues(ctx)
|
|
}
|
|
|
|
// We only allow the api to match one channel with the provided name.
|
|
// If we match multiples, we'll eagerly return the first one.
|
|
logger.Ctx(ctx).Debugw("channels matched the name search")
|
|
|
|
// Sanity check ID and name
|
|
cal := gv[0]
|
|
|
|
if err := CheckIDAndName(cal); err != nil {
|
|
return nil, clues.Stack(err).WithClues(ctx)
|
|
}
|
|
|
|
return cal, nil
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// message
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// GetMessage retrieves a ChannelMessage item.
|
|
func (c Channels) GetMessage(
|
|
ctx context.Context,
|
|
teamID, channelID, itemID string,
|
|
errs *fault.Bus,
|
|
) (serialization.Parsable, *details.GroupsInfo, error) {
|
|
var size int64
|
|
|
|
message, err := c.Stable.
|
|
Client().
|
|
Teams().
|
|
ByTeamId(teamID).
|
|
Channels().
|
|
ByChannelId(channelID).
|
|
Messages().
|
|
ByChatMessageId(itemID).
|
|
Get(ctx, nil)
|
|
if err != nil {
|
|
return nil, nil, graph.Stack(ctx, err)
|
|
}
|
|
|
|
return message, ChannelMessageInfo(message, size), nil
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// replies
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// GetReplies retrieves all replies to a Channel Message.
|
|
func (c Channels) GetReplies(
|
|
ctx context.Context,
|
|
teamID, channelID, messageID string,
|
|
) (serialization.Parsable, error) {
|
|
replies, err := c.Stable.
|
|
Client().
|
|
Teams().
|
|
ByTeamId(teamID).
|
|
Channels().
|
|
ByChannelId(channelID).
|
|
Messages().
|
|
ByChatMessageId(messageID).
|
|
Replies().
|
|
Get(ctx, nil)
|
|
if err != nil {
|
|
return nil, graph.Stack(ctx, err)
|
|
}
|
|
|
|
return replies, nil
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helpers
|
|
// ---------------------------------------------------------------------------
|
|
|
|
func ChannelMessageInfo(msg models.ChatMessageable, size int64) *details.GroupsInfo {
|
|
created := ptr.Val(msg.GetCreatedDateTime())
|
|
|
|
return &details.GroupsInfo{
|
|
ItemType: details.TeamsChannelMessage,
|
|
Size: size,
|
|
Created: created,
|
|
Modified: ptr.OrNow(msg.GetLastModifiedDateTime()),
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// helper funcs
|
|
// ---------------------------------------------------------------------------
|
|
|
|
// CheckIDAndName is a validator that ensures the ID
|
|
// and name are populated and not zero valued.
|
|
func CheckIDAndName(c models.Channelable) error {
|
|
if c == nil {
|
|
return clues.New("nil container")
|
|
}
|
|
|
|
id := ptr.Val(c.GetId())
|
|
if len(id) == 0 {
|
|
return clues.New("container missing ID")
|
|
}
|
|
|
|
dn := ptr.Val(c.GetDisplayName())
|
|
if len(dn) == 0 {
|
|
return clues.New("container missing display name").With("container_id", id)
|
|
}
|
|
|
|
return nil
|
|
}
|