msteams

package
v0.18.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package msteams implements the Microsoft Teams channel plugin via Graph API polling. It is outbound-only — no inbound webhooks, no public endpoint. See FORGE_MSTEAMS_CHANNEL_GRAPH_POLLING.md for the design.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AdmitMode

type AdmitMode string

AdmitMode is the inbound message gating policy.

const (
	// AdmitMention drops every message except those that @-mention the agent.
	AdmitMention AdmitMode = "mention"
	// AdmitDM drops every message except 1:1 chat messages.
	AdmitDM AdmitMode = "dm"
	// AdmitMentionOrDM admits messages that satisfy either condition.
	AdmitMentionOrDM AdmitMode = "mention_or_dm"
)

type AuthFlow

type AuthFlow string

AuthFlow identifies the OAuth2 grant the adapter uses.

const (
	// FlowDelegated uses a long-lived refresh token captured at setup time
	// (via the device-code flow) to obtain access tokens that act as a
	// specific user. Refresh tokens rotate — the new token returned with
	// each refresh response should be persisted back to the secret store.
	FlowDelegated AuthFlow = "delegated"

	// FlowClientCredentials uses a client_id + client_secret pair to obtain
	// app-only tokens. Requires admin consent + appropriate application
	// permissions (RSC) on chats. user_id must be configured explicitly.
	FlowClientCredentials AuthFlow = "client_credentials"
)

type ChatMessage

type ChatMessage struct {
	ID                   string `json:"id"`
	ChatID               string `json:"chatId"`
	ChannelIdentity      any    `json:"channelIdentity,omitempty"` // present for team-channel messages; we ignore them
	ChatType             string `json:"chatType,omitempty"`        // sometimes inlined; usually fetched separately
	CreatedDateTime      string `json:"createdDateTime"`
	LastModifiedDateTime string `json:"lastModifiedDateTime"`
	Subject              string `json:"subject,omitempty"`
	MessageType          string `json:"messageType,omitempty"`
	Importance           string `json:"importance,omitempty"`
	From                 *struct {
		User *struct {
			ID               string `json:"id"`
			DisplayName      string `json:"displayName"`
			UserIdentityType string `json:"userIdentityType,omitempty"`
			TenantID         string `json:"tenantId,omitempty"`
		} `json:"user,omitempty"`
		Application *struct {
			ID                  string `json:"id"`
			DisplayName         string `json:"displayName"`
			ApplicationIdentity string `json:"applicationIdentityType,omitempty"`
		} `json:"application,omitempty"`
	} `json:"from,omitempty"`
	Body struct {
		ContentType string `json:"contentType"` // "html" or "text"
		Content     string `json:"content"`
	} `json:"body"`
	Mentions []markdown.TeamsMention `json:"mentions,omitempty"`
}

ChatMessage is the trimmed Graph chatMessage representation the adapter cares about. Fields not modelled here decode silently.

type ChatRef

type ChatRef struct {
	ID       string `json:"id"`
	Topic    string `json:"topic,omitempty"`
	ChatType string `json:"chatType"`
}

ChatRef is the minimal shape returned by GET /me/chats / /chats — enough to drive per-chat polling. ChatType discriminates oneOnOne/group/meeting.

type DeltaPage

type DeltaPage struct {
	Messages  []ChatMessage `json:"value"`
	NextLink  string        `json:"@odata.nextLink,omitempty"`
	DeltaLink string        `json:"@odata.deltaLink,omitempty"`
}

DeltaPage is one page of a getAllMessages/delta response. Exactly one of NextLink or DeltaLink is set per page; the poll loop continues paging until DeltaLink appears, then persists it.

type MeResponse

type MeResponse struct {
	ID                string `json:"id"`
	DisplayName       string `json:"displayName"`
	UserPrincipalName string `json:"userPrincipalName"`
}

MeResponse is the trimmed Graph /me payload — only the fields the adapter caches at startup.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin implements channels.ChannelPlugin for Microsoft Teams.

func New

func New() *Plugin

New returns an uninitialised plugin. Init must be called before Start.

func (*Plugin) Init

func (p *Plugin) Init(cfg channels.ChannelConfig) error

func (*Plugin) Name

func (p *Plugin) Name() string

func (*Plugin) NormalizeEvent

func (p *Plugin) NormalizeEvent(raw []byte) (*channels.ChannelEvent, error)

NormalizeEvent decodes a raw Graph chatMessage JSON into a ChannelEvent. Used by the polling loop and by tests that want to feed a stored payload through the adapter.

func (*Plugin) SendResponse

func (p *Plugin) SendResponse(event *channels.ChannelEvent, response *a2a.Message) error

SendResponse delivers an agent reply back to the Teams chat. Mirrors the Slack/Telegram large-response handling: small responses inline, large responses summary + hosted-content attachment, fallback to chunked text.

Every successful outbound message ID is recorded in the dedup ring via markSent. In delegated mode the agent shares the user's Graph identity (delegated tokens act as the user), so messages we post come back via polling with the same from.user.id as messages the user types directly. The dedup ring is the ONLY way to tell our own posts apart from real inbound traffic before reaching the admission gate.

func (*Plugin) Start

func (p *Plugin) Start(ctx context.Context, handler channels.EventHandler) error

func (*Plugin) Stop

func (p *Plugin) Stop() error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL