init: Initial commit
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,8 @@
|
||||
.idea/
|
||||
.venv/
|
||||
__pycache__/
|
||||
devTools/
|
||||
*.log
|
||||
.env
|
||||
CLAUDE.md
|
||||
database.db
|
||||
10
.idea/.gitignore
generated
vendored
10
.idea/.gitignore
generated
vendored
@@ -1,10 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
.idea/misc.xml
generated
7
.idea/misc.xml
generated
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.14" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.14" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/taro-bot-teams.iml" filepath="$PROJECT_DIR$/.idea/taro-bot-teams.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/taro-bot-teams.iml
generated
8
.idea/taro-bot-teams.iml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.14" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
43
bot.py
43
bot.py
@@ -8,6 +8,7 @@ from config import DefaultConfig
|
||||
from commands.webhook import WebhookCommand
|
||||
from commands.test import TestCommand
|
||||
from modules.database import DatabaseManager
|
||||
from modules.command import Command
|
||||
|
||||
import re
|
||||
|
||||
@@ -20,11 +21,11 @@ class WebhookBot(ActivityHandler):
|
||||
self.webhook_manager = WebhookCommand(database)
|
||||
self.database = database
|
||||
|
||||
def is_command(self, text: str) -> tuple[bool, str | None]:
|
||||
def is_command(self, text: str) -> tuple[bool, str]:
|
||||
"""Check if the text is a command."""
|
||||
if text.startswith(self.command_prefix) and len(text) > len(self.command_prefix):
|
||||
return True, text[len(self.command_prefix):].split(" ")[0]
|
||||
return False, None
|
||||
return False, ""
|
||||
|
||||
def has_sub_command(self, text: str) -> tuple[bool, str | None]:
|
||||
"""Check if the text has a sub command."""
|
||||
@@ -117,10 +118,8 @@ class WebhookBot(ActivityHandler):
|
||||
|
||||
# Check if this is a channel conversation
|
||||
is_channel = self.is_channel_conversation(turn_context)
|
||||
print(f"[Bot] Is channel conversation: {is_channel}")
|
||||
|
||||
if not is_channel:
|
||||
print(f"[Bot] Not a channel conversation, ignoring message")
|
||||
return
|
||||
|
||||
# Get text from activity - can be None for channel posts with only attachments
|
||||
@@ -131,39 +130,13 @@ class WebhookBot(ActivityHandler):
|
||||
|
||||
# Strip whitespace and check if it's a command
|
||||
text = text.strip()
|
||||
print(f"[Bot] Processed text (after removing mentions): '{text}'")
|
||||
message = text.split(" ")[1:] if len(text.split(" ")) > 1 else None
|
||||
message = " ".join(message) if message is not None else None
|
||||
is_command, command = self.is_command(text)
|
||||
print(f"[Bot] Is command: {is_command}, Command: {command}")
|
||||
|
||||
if is_command:
|
||||
match command:
|
||||
case "test":
|
||||
# Get the text behind the command /test <message>
|
||||
# Remove the command from the text
|
||||
message = text.replace(f"/test ", "").strip()
|
||||
if message == "":
|
||||
await turn_context.send_activity(f"Please provide a message for the test command.")
|
||||
return
|
||||
await TestCommand(self.database).handle_test(turn_context, message)
|
||||
return
|
||||
case "webhooks":
|
||||
is_sub_command, sub_command = self.has_sub_command(text)
|
||||
if is_sub_command:
|
||||
match sub_command:
|
||||
case "list":
|
||||
await self.webhook_manager.handle_list_webhooks(turn_context)
|
||||
return
|
||||
case _:
|
||||
await turn_context.send_activity(f"Sub command {sub_command} not found.")
|
||||
return
|
||||
else:
|
||||
# Default to list if no sub-command specified
|
||||
await self.webhook_manager.handle_list_webhooks(turn_context)
|
||||
return
|
||||
case _:
|
||||
await turn_context.send_activity(f"Command {command} not found.")
|
||||
return
|
||||
cmd = Command(turn_context, self.database)
|
||||
await cmd.handle_command(command, message)
|
||||
else:
|
||||
print(f"[Bot] Not a command, echoing message")
|
||||
await turn_context.send_activity(f"Message: {text}")
|
||||
return
|
||||
return
|
||||
44
commands/help.py
Normal file
44
commands/help.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from botbuilder.core import TurnContext, MessageFactory, CardFactory
|
||||
from botbuilder.schema import Attachment
|
||||
|
||||
from modules.database import DatabaseManager
|
||||
from modules.template import TemplateEngine
|
||||
|
||||
class HelpCommand:
|
||||
def __init__(self, turn_context: TurnContext, database: DatabaseManager) -> None:
|
||||
self.turn_context = turn_context
|
||||
self.database = database
|
||||
|
||||
async def handle_help(self) -> None:
|
||||
template = TemplateEngine("help-command-card")
|
||||
card = template.json_dict({
|
||||
"card_title": "Help",
|
||||
"card_icon": "🚨",
|
||||
"card_description": "You can use the following commands to interact with the bot:",
|
||||
})
|
||||
commands = [
|
||||
{
|
||||
"title": "**/help**",
|
||||
"value": "Show this help message"
|
||||
},
|
||||
{
|
||||
"title": "**/test** <message>",
|
||||
"value": "Test the bot"
|
||||
},
|
||||
{
|
||||
"title": "**/webhooks** create",
|
||||
"value": "Create a new webhook"
|
||||
},
|
||||
{
|
||||
"title": "**/webhooks** delete",
|
||||
"value": "Delete a webhook"
|
||||
},
|
||||
{
|
||||
"title": "**/webhooks** list",
|
||||
"value": "List all webhooks"
|
||||
}
|
||||
]
|
||||
card["body"][2]["facts"] = commands
|
||||
card_attachment = CardFactory.adaptive_card(card)
|
||||
await self.turn_context.send_activity(MessageFactory.attachment(card_attachment))
|
||||
return
|
||||
@@ -10,32 +10,28 @@ class TestCommand:
|
||||
def __init__(self, database: DatabaseManager):
|
||||
self.database = database
|
||||
|
||||
async def handle_test(self, turn_context: TurnContext, message: str) -> None:
|
||||
async def handle_test(self, turn_context: TurnContext, command: str, message: str | None = None) -> None:
|
||||
if message is None:
|
||||
message = "No message provided"
|
||||
try:
|
||||
activity = turn_context.activity
|
||||
# conversation_reference = TurnContext.get_conversation_reference(turn_context.activity)
|
||||
|
||||
# Check if the channel is a Microsoft Teams channel (msteams) or emulator (for testing)
|
||||
channel_id_str = activity.channel_id
|
||||
|
||||
channel_data = activity.channel_data
|
||||
|
||||
# channel_data is a dictionary, access it as such
|
||||
teams_id = channel_data.get('teamsTeamId') if channel_data and isinstance(channel_data, dict) else None
|
||||
microsoft_teams_id_str = channel_data.get('teamsTeamId') if channel_data and isinstance(channel_data, dict) else None
|
||||
microsoft_channel_id_str = channel_data.get('teamsChannelId') if channel_data and isinstance(channel_data, dict) else None
|
||||
|
||||
if channel_id_str == "emulator":
|
||||
teams_id = "00000000-0000-0000-0000-000000000000"
|
||||
microsoft_teams_id_str = "00000000-0000-0000-0000-000000000000"
|
||||
microsoft_channel_id_str = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
# Load template and prepare data
|
||||
template = TemplateEngine("card")
|
||||
|
||||
# Create and send the Adaptive Card
|
||||
card_attachment = CardFactory.adaptive_card(template.generate({"card_type": "Test", "card_title": "Test", "card_content": message}))
|
||||
card_attachment = CardFactory.adaptive_card(template.generate({"card_type": "Test", "card_icon": "🔎", "card_title": "Test", "card_content": f"_{message}_", "card_channel_id": microsoft_teams_id_str, "card_teams_id": microsoft_channel_id_str, "card_debug": json.dumps(channel_data, indent=4)}))
|
||||
|
||||
# Send the attachment as a reply to the post in the channel
|
||||
result = await turn_context.send_activity(MessageFactory.attachment(card_attachment))
|
||||
await turn_context.send_activity(MessageFactory.attachment(card_attachment))
|
||||
return
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -16,29 +16,23 @@ class WebhookCommand:
|
||||
async def handle_list_webhooks(self, turn_context: TurnContext) -> None:
|
||||
try:
|
||||
activity = turn_context.activity
|
||||
# conversation_reference = TurnContext.get_conversation_reference(turn_context.activity)
|
||||
|
||||
# Check if the channel is a Microsoft Teams channel (msteams) or emulator (for testing)
|
||||
channel_id_str = activity.channel_id
|
||||
|
||||
channel_data = activity.channel_data
|
||||
|
||||
# channel_data is a dictionary, access it as such
|
||||
teams_id = channel_data.get('teamsTeamId') if channel_data and isinstance(channel_data, dict) else None
|
||||
microsoft_teams_id_str = channel_data.get('teamsTeamId') if channel_data and isinstance(channel_data, dict) else None
|
||||
microsoft_channel_id_str = channel_data.get('teamsChannelId') if channel_data and isinstance(channel_data, dict) else None
|
||||
|
||||
if channel_id_str == "emulator":
|
||||
teams_id = "00000000-0000-0000-0000-000000000000"
|
||||
microsoft_teams_id_str = "00000000-0000-0000-0000-000000000000"
|
||||
microsoft_channel_id_str = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
# Get the actual channel UUID from the database
|
||||
channel_uuid = None
|
||||
webhook_count = 0
|
||||
|
||||
if microsoft_channel_id_str:
|
||||
try:
|
||||
from uuid import UUID
|
||||
# Try to get channel by Microsoft Teams channel ID
|
||||
microsoft_channel_id = UUID(microsoft_channel_id_str) if isinstance(microsoft_channel_id_str, str) else microsoft_channel_id_str
|
||||
channel_obj = self.database.get_channel_by_microsoft_channel_id(str(microsoft_channel_id))
|
||||
if channel_obj:
|
||||
@@ -47,14 +41,10 @@ class WebhookCommand:
|
||||
except (ValueError, TypeError) as e:
|
||||
webhook_count = 0
|
||||
|
||||
# Load template and prepare data
|
||||
template = TemplateEngine("webhook-overview-card" if webhook_count > 0 else "webhook-overview-no-webhooks-card")
|
||||
|
||||
# Create and send the Adaptive Card
|
||||
card_attachment = self.create_webhooks_card(template, {"webhook_count": webhook_count})
|
||||
|
||||
# Send the attachment as a reply to the post in the channel
|
||||
result = await turn_context.send_activity(MessageFactory.attachment(card_attachment))
|
||||
await turn_context.send_activity(MessageFactory.attachment(card_attachment))
|
||||
return
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
BIN
database.db
BIN
database.db
Binary file not shown.
@@ -1,76 +0,0 @@
|
||||
debug Telemetry: agents-playground-cli/cliStart {"cleanProperties":{"isExec":"false","argv":"<REDACTED: user-file-path>,-e,http://localhost:3978/api/messages,-c,emulator"}}
|
||||
|
||||
log Listening on 56150
|
||||
log Microsoft 365 Agents Playground is being launched for you to debug the app: http://localhost:56150
|
||||
debug started web socket client
|
||||
debug started web socket client
|
||||
log Waiting for connection of endpoint: http://localhost:3978/api/messages
|
||||
log waiting for 1 resources: http://localhost:3978/api/messages
|
||||
log wait-on(76805) complete
|
||||
log Events recording disabled.
|
||||
debug Telemetry: agents-playground-server/eventsRecording {"cleanProperties":{"enabled":"false"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/getConfig {"cleanProperties":{"internalConfig":"{\"locale\":\"en-US\",\"localTimezone\":\"Europe/Berlin\",\"channelId\":\"emulator\",\"debugConfig\":{\"eventsRecordingEnabled\":false}}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"40b98e9d-79b0-4d5f-b810-32da23f6b42e","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"team-id","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"message","conversationId":"team-id;messageid=1767856906530","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug stopping web socket client
|
||||
debug stopping web socket client
|
||||
debug started web socket client
|
||||
debug started web socket client
|
||||
log Waiting for connection of endpoint: http://localhost:3978/api/messages
|
||||
log waiting for 1 resources: http://localhost:3978/api/messages
|
||||
log wait-on(76805) complete
|
||||
log Events recording disabled.
|
||||
debug Telemetry: agents-playground-server/eventsRecording {"cleanProperties":{"enabled":"false"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/getConfig {"cleanProperties":{"internalConfig":"{\"locale\":\"en-US\",\"localTimezone\":\"Europe/Berlin\",\"channelId\":\"emulator\",\"debugConfig\":{\"eventsRecordingEnabled\":false}}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"40b98e9d-79b0-4d5f-b810-32da23f6b42e","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"team-id","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"message","conversationId":"team-id;messageid=1767857222140","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug stopping web socket client
|
||||
debug stopping web socket client
|
||||
debug started web socket client
|
||||
debug started web socket client
|
||||
log Waiting for connection of endpoint: http://localhost:3978/api/messages
|
||||
log waiting for 1 resources: http://localhost:3978/api/messages
|
||||
log wait-on(76805) complete
|
||||
log Events recording disabled.
|
||||
debug Telemetry: agents-playground-server/eventsRecording {"cleanProperties":{"enabled":"false"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/getConfig {"cleanProperties":{"internalConfig":"{\"locale\":\"en-US\",\"localTimezone\":\"Europe/Berlin\",\"channelId\":\"emulator\",\"debugConfig\":{\"eventsRecordingEnabled\":false}}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"40b98e9d-79b0-4d5f-b810-32da23f6b42e","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"team-id","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"message","conversationId":"team-id;messageid=1767857462550","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug stopping web socket client
|
||||
debug stopping web socket client
|
||||
debug started web socket client
|
||||
debug started web socket client
|
||||
log Waiting for connection of endpoint: http://localhost:3978/api/messages
|
||||
log waiting for 1 resources: http://localhost:3978/api/messages
|
||||
log wait-on(76805) complete
|
||||
log Events recording disabled.
|
||||
debug Telemetry: agents-playground-server/eventsRecording {"cleanProperties":{"enabled":"false"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/getConfig {"cleanProperties":{"internalConfig":"{\"locale\":\"en-US\",\"localTimezone\":\"Europe/Berlin\",\"channelId\":\"emulator\",\"debugConfig\":{\"eventsRecordingEnabled\":false}}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"40b98e9d-79b0-4d5f-b810-32da23f6b42e","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"conversationUpdate","conversationId":"team-id","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug Telemetry: agents-playground-server/sendActivity {"cleanProperties":{"activityType":"message","conversationId":"team-id;messageid=1767857505932","headers":"{\"x-ms-agents-playground\":\"true\"}"}}
|
||||
|
||||
debug stopping web socket client
|
||||
debug stopping web socket client
|
||||
20
modules/command.py
Normal file
20
modules/command.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from botbuilder.core import TurnContext
|
||||
|
||||
from commands.test import TestCommand
|
||||
from commands.webhook import WebhookCommand
|
||||
from commands.help import HelpCommand
|
||||
from modules.database import DatabaseManager
|
||||
|
||||
class Command:
|
||||
def __init__(self, turn_context: TurnContext, database: DatabaseManager) -> None:
|
||||
self.turn_context = turn_context
|
||||
self.database = database
|
||||
|
||||
async def handle_command(self, command: str, message: str | None = None) -> None:
|
||||
match command:
|
||||
case "test":
|
||||
await TestCommand(self.database).handle_test(self.turn_context, command, message)
|
||||
case "webhooks":
|
||||
await WebhookCommand(self.database).handle_list_webhooks(self.turn_context)
|
||||
case _:
|
||||
await HelpCommand(self.turn_context, self.database).handle_help()
|
||||
@@ -59,23 +59,18 @@ class DatabaseManager:
|
||||
def get_webhooks(self) -> list[Webhook]:
|
||||
return self.__session.query(Webhook).all()
|
||||
|
||||
def count_webhooks(self) -> int:
|
||||
return len(self.get_webhooks())
|
||||
|
||||
def get_webhook_by_id(self, id: str) -> Webhook:
|
||||
webhook = self.__session.query(Webhook).filter(Webhook.id == id).first()
|
||||
if webhook is None:
|
||||
raise ValueError(f"Webhook with id {id} not found")
|
||||
return webhook
|
||||
|
||||
def get_services(self) -> list[Service]:
|
||||
return self.__session.query(Service).all()
|
||||
|
||||
def get_service_by_id(self, id: str) -> Service:
|
||||
service = self.__session.query(Service).filter(Service.id == id).first()
|
||||
if service is None:
|
||||
raise ValueError(f"Service with id {id} not found")
|
||||
return service
|
||||
def count_webhooks_by_channel_id(self, channel_id: str | UUID) -> int | None:
|
||||
try:
|
||||
channel_uuid = UUID(channel_id) if isinstance(channel_id, str) else channel_id
|
||||
return len(self.__session.query(Webhook).filter(Webhook.channel_id == channel_uuid).all())
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
|
||||
def get_channels(self) -> list[Channel]:
|
||||
return self.__session.query(Channel).all()
|
||||
@@ -86,22 +81,17 @@ class DatabaseManager:
|
||||
raise ValueError(f"Channel with id {id} not found")
|
||||
return channel
|
||||
|
||||
def get_channel_by_microsoft_channel_id(self, microsoft_channel_id: str) -> Channel | None:
|
||||
"""Get channel by Microsoft Teams channel ID. Returns None if not found."""
|
||||
try:
|
||||
# Convert string to UUID if needed
|
||||
channel_uuid = UUID(microsoft_channel_id) if isinstance(microsoft_channel_id, str) else microsoft_channel_id
|
||||
channel = self.__session.query(Channel).filter(Channel.microsoft_channel_id == channel_uuid).first()
|
||||
return channel
|
||||
except (ValueError, TypeError):
|
||||
return None
|
||||
def get_channel_by_microsoft_channel_id(self, microsoft_channel_id: str) -> Channel:
|
||||
channel = self.__session.query(Channel).filter(Channel.microsoft_channel_id == microsoft_channel_id).first()
|
||||
if channel is None:
|
||||
raise ValueError(f"Channel with microsoft channel id {microsoft_channel_id} not found")
|
||||
return channel
|
||||
|
||||
def count_webhooks_by_channel_id(self, channel_id: str | UUID) -> int:
|
||||
"""Count webhooks by channel ID. Accepts UUID string or UUID object."""
|
||||
try:
|
||||
# Convert string to UUID if needed
|
||||
channel_uuid = UUID(channel_id) if isinstance(channel_id, str) else channel_id
|
||||
return len(self.__session.query(Webhook).filter(Webhook.channel_id == channel_uuid).all())
|
||||
except (ValueError, TypeError):
|
||||
# If channel_id is not a valid UUID, return 0
|
||||
return 0
|
||||
def get_services(self) -> list[Service]:
|
||||
return self.__session.query(Service).all()
|
||||
|
||||
def get_service_by_id(self, id: str) -> Service:
|
||||
service = self.__session.query(Service).filter(Service.id == id).first()
|
||||
if service is None:
|
||||
raise ValueError(f"Service with id {id} not found")
|
||||
return service
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from botbuilder.schema import Attachment
|
||||
class TemplateEngine:
|
||||
def __init__(self, template_name: str, template_path: str = "templates/") -> None:
|
||||
self.__name = template_name
|
||||
@@ -24,6 +25,21 @@ class TemplateEngine:
|
||||
else:
|
||||
return obj
|
||||
|
||||
def generate(self, data: dict) -> dict[str, Any]:
|
||||
def __generate_card(self, data: dict) -> dict[str, Any]:
|
||||
template = self.__load_template()
|
||||
return self.__replace_placeholders(template, data)
|
||||
|
||||
def generate(self, data: dict) -> dict[str, Any]:
|
||||
return self.__generate_card(data)
|
||||
|
||||
def attachment(self, data: dict) -> Attachment:
|
||||
return Attachment(
|
||||
content_type="application/vnd.microsoft.card.adaptive",
|
||||
content=self.generate(data)
|
||||
)
|
||||
|
||||
def json_dict(self, data: dict) -> dict:
|
||||
return self.generate(data)
|
||||
|
||||
def json(self, data: dict) -> str:
|
||||
return json.dumps(self.generate(data))
|
||||
@@ -14,12 +14,31 @@
|
||||
"wrap": true,
|
||||
"style": "heading",
|
||||
"size": "ExtraLarge",
|
||||
"text": "{card_title}"
|
||||
"text": "{card_icon} {card_title}"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{card_content}",
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "FactSet",
|
||||
"facts": [
|
||||
{
|
||||
"title": "Channel",
|
||||
"value": "{card_channel_id}"
|
||||
},
|
||||
{
|
||||
"title": "Teams",
|
||||
"value": "{card_teams_id}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{card_debug}",
|
||||
"wrap": true,
|
||||
"fontType": "Monospace"
|
||||
}
|
||||
]
|
||||
}
|
||||
23
templates/help-command-card.json
Normal file
23
templates/help-command-card.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"type": "AdaptiveCard",
|
||||
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
||||
"version": "1.5",
|
||||
"body": [
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{card_icon} {card_title}",
|
||||
"wrap": true,
|
||||
"style": "heading",
|
||||
"size": "ExtraLarge"
|
||||
},
|
||||
{
|
||||
"type": "TextBlock",
|
||||
"text": "{card_description}",
|
||||
"wrap": true
|
||||
},
|
||||
{
|
||||
"type": "FactSet",
|
||||
"facts": []
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user