Module: Legion::Extensions::MicrosoftTeams::Runners::Loop

Includes:
Helpers::Lex, Helpers::Client, JSON::Helper
Included in:
Client
Defined in:
lib/legion/extensions/microsoft_teams/runners/loop.rb

Instance Method Summary collapse

Methods included from Helpers::Client

#bot_connection, #graph_connection, #oauth_connection, #user_path

Instance Method Details

#create_loop_file(filename:, folder_path: nil, user_id: 'me') ⇒ Object

Creates a new .loop file in the user’s OneDrive via the Graph API. The Fluid Framework collaborative session is initialized by Teams on first open. Returns the drive item metadata including webUrl, which can be passed to post_loop_to_chat or post_loop_to_channel.

Parameters:

  • filename (String)

    Name of the file (e.g. “incident-status” or “incident-status.loop”)

  • folder_path (String) (defaults to: nil)

    OneDrive folder path relative to root (default: root)

  • user_id (String) (defaults to: 'me')

    Graph user ID or ‘me’ (default: ‘me’)



22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/legion/extensions/microsoft_teams/runners/loop.rb', line 22

def create_loop_file(filename:, folder_path: nil, user_id: 'me', **)
  filename = "#{filename}.loop" unless filename.end_with?('.loop')

  path = if folder_path.nil? || folder_path.empty?
           "users/#{user_id}/drive/root:/#{filename}:/content"
         else
           "users/#{user_id}/drive/root:/#{folder_path}/#{filename}:/content"
         end

  response = graph_connection(**).put(path, '', 'Content-Type' => 'application/octet-stream')
  { result: response.body }
end

#loop_attachment(component_url:, source_type: 'Compose') ⇒ Object

Builds the fluidEmbedCard attachment array required to embed a Loop component in a Teams message. Pass the resulting array as attachments: to send_chat_message / send_channel_message, or use the convenience methods post_loop_to_chat and post_loop_to_channel.

Parameters:

  • component_url (String)

    SharePoint/OneDrive URL of the .loop file (the webUrl from create_loop_file)

  • source_type (String) (defaults to: 'Compose')

    ‘Compose’ (default) or ‘Loop’



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/legion/extensions/microsoft_teams/runners/loop.rb', line 43

def loop_attachment(component_url:, source_type: 'Compose', **)
  attachment_id = SecureRandom.hex(16)
  {
    result: [
      {
        id:          attachment_id,
        contentType: 'application/vnd.microsoft.card.fluidEmbedCard',
        contentUrl:  nil,
        content:     json_generate({ componentUrl: component_url, sourceType: source_type }),
        teamsAppId:  'FluidEmbedCard'
      },
      {
        id:          'placeholderCard',
        contentType: 'application/vnd.microsoft.card.codesnippet',
        content:     '{}',
        teamsAppId:  'FLUID_PLACEHOLDER_CARD'
      }
    ]
  }
end

#post_loop_to_channel(team_id:, channel_id:, component_url:, body_text: '', subject: nil) ⇒ Object

Posts a message into a Teams channel thread with a Loop component embedded inline.

Parameters:

  • team_id (String)

    Teams team ID

  • channel_id (String)

    Teams channel ID

  • component_url (String)

    SharePoint/OneDrive URL of the .loop file

  • body_text (String) (defaults to: '')

    Optional plain-text preamble shown above the component

  • subject (String) (defaults to: nil)

    Optional thread subject line



84
85
86
87
88
89
90
91
# File 'lib/legion/extensions/microsoft_teams/runners/loop.rb', line 84

def post_loop_to_channel(team_id:, channel_id:, component_url:, body_text: '', subject: nil, **)
  attachments = loop_attachment(component_url: component_url, **)[:result]
  content     = body_text.empty? ? '<p></p>' : "<p>#{body_text}</p>"
  payload     = { body: { contentType: 'html', content: content }, attachments: attachments }
  payload[:subject] = subject if subject
  response = graph_connection(**).post("teams/#{team_id}/channels/#{channel_id}/messages", payload)
  { result: response.body }
end

#post_loop_to_chat(chat_id:, component_url:, body_text: '') ⇒ Object

Posts a message into a Teams chat thread with a Loop component embedded inline.

Parameters:

  • chat_id (String)

    Teams chat thread ID (e.g. 19:…@thread.v2)

  • component_url (String)

    SharePoint/OneDrive URL of the .loop file

  • body_text (String) (defaults to: '')

    Optional plain-text preamble shown above the component



69
70
71
72
73
74
75
# File 'lib/legion/extensions/microsoft_teams/runners/loop.rb', line 69

def post_loop_to_chat(chat_id:, component_url:, body_text: '', **)
  attachments = loop_attachment(component_url: component_url, **)[:result]
  content     = body_text.empty? ? '<p></p>' : "<p>#{body_text}</p>"
  payload     = { body: { contentType: 'html', content: content }, attachments: attachments }
  response    = graph_connection(**).post("chats/#{chat_id}/messages", payload)
  { result: response.body }
end