Skip to content

Commit

Permalink
Merge pull request #1476 from OfficeDev/v-jegadeesh/authconfig
Browse files Browse the repository at this point in the history
msgext-search-auth-config python code fix and image update
  • Loading branch information
Harikrishnan-MSFT authored Jan 6, 2025
2 parents 2ebe7b1 + b7f3b5a commit 9bb6100
Show file tree
Hide file tree
Showing 14 changed files with 128 additions and 18 deletions.
Binary file modified samples/msgext-search-auth-config/python/Images/1-add_app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/msgext-search-auth-config/python/Images/3.search.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/msgext-search-auth-config/python/Images/6.search.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified samples/msgext-search-auth-config/python/Images/7.search.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions samples/msgext-search-auth-config/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,11 @@ Once the Messaging Extension is installed, click the icon for **Config Auth Sear
![search ](Images/3.search.PNG)
![search ](Images/4.search.PNG)
![search ](Images/5.search.PNG)
![search ](Images/6.search.PNG)
![search ](Images/7.search.PNG)
![search ](Images/8.zero_install.PNG)
## Deploy the bot to Azure
Expand Down
2 changes: 1 addition & 1 deletion samples/msgext-search-auth-config/python/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
TurnContext,
BotFrameworkAdapter,
MemoryStorage,
UserState,
UserState
)
from botbuilder.core.integration import aiohttp_error_middleware

Expand Down
20 changes: 16 additions & 4 deletions samples/msgext-search-auth-config/python/appManifest/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"manifestVersion": "1.19",
"version": "1.0.0",
"id": "${{TEAMS_APP_ID}}",
"packageName": "com.microsoft.teams.sample",
"developer": {
"name": "Microsoft",
"websiteUrl": "https://dev.botframework.com",
Expand All @@ -15,8 +14,8 @@
"outline": "icon-outline.png"
},
"name": {
"short": "Config Auth Search",
"full": "Config Auth Search"
"short": "Messaging Extension Auth",
"full": "ME Auth for Search, Action and link unfurling"
},
"description": {
"short": "Python Messaging Extension with authentication and configuration page.",
Expand All @@ -37,7 +36,8 @@
"fetchTask": false,
"context": [
"commandBox",
"compose"
"compose",
"message"
],
"parameters": [
{
Expand Down Expand Up @@ -67,6 +67,18 @@
}
]
}
],
"messageHandlers": [
{
"type": "link",
"value": {
"domains": [
"*.botframework.com",
"${{BOT_DOMAIN}}"
],
"supportsAnonymizedPayloads": true
}
}
]
}
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
# Licensed under the MIT License.

import urllib.parse
import xmlrpc.client
from botbuilder.core import CardFactory, MessageFactory, TurnContext, UserState
from botbuilder.schema import (
ThumbnailCard,
CardImage,
HeroCard,
CardAction,
ActionTypes,
InvokeResponse
)
from bs4 import BeautifulSoup
from botbuilder.schema.teams import (
MessagingExtensionAction,
MessagingExtensionAttachment,
Expand All @@ -21,6 +23,8 @@
TaskModuleContinueResponse,
TaskModuleTaskInfo,
)
import requests
from http import HTTPStatus
from botbuilder.core.teams import TeamsActivityHandler
from simple_graph_client import SimpleGraphClient

Expand Down Expand Up @@ -77,6 +81,67 @@ async def on_teams_messaging_extension_configuration_query_settings_url(
)
)

async def on_invoke_activity(self, turn_context: TurnContext):
if turn_context.activity.name == "composeExtension/anonymousQueryLink":
# Handle the anonymous query link
response = await self.handle_teams_app_based_anonymous_link_query(
turn_context, turn_context.activity.value
)
return InvokeResponse(status=HTTPStatus.OK, body=self.convert_to_dict(response))
else:
return await super().on_invoke_activity(turn_context)

async def handle_teams_app_based_anonymous_link_query(self, turn_context: TurnContext, value):
# Create the Adaptive Card JSON directly
adaptive_card = {
"type": "AdaptiveCard",
"version": "1.5",
"body": [
{
"type": "TextBlock",
"text": "Zero Installation Link Unfurling Card",
"size": "ExtraLarge",
},
{
"type": "TextBlock",
"text": "Install the app or sign in to view full content of the card.",
"size": "Medium",
},
],
}
# Create a MessagingExtensionAttachment for the card
attachment = MessagingExtensionAttachment(
content_type="application/vnd.microsoft.card.adaptive",
content=adaptive_card,
)
# Create a MessagingExtensionResult
result = MessagingExtensionResult(
attachment_layout="list",
type="auth",
attachments=[attachment],
)
# Return the MessagingExtensionResponse
return MessagingExtensionResponse(compose_extension=result)

def convert_to_dict(self, response: MessagingExtensionResponse) -> dict:
"""Manually convert MessagingExtensionResponse and MessagingExtensionResult to a JSON-serializable dictionary."""
compose_extension = response.compose_extension
if compose_extension is None: return {}
# Manually serialize the MessagingExtensionResult
result_dict = {
"attachmentLayout": compose_extension.attachment_layout,
"type": compose_extension.type,
"attachments": [
{
"contentType": attachment.content_type,
"content": attachment.content,
}
for attachment in compose_extension.attachments
],
}
# Return the dictionary in the expected format
return {"composeExtension": result_dict}

async def on_teams_messaging_extension_configuration_setting(
self, turn_context: TurnContext, settings
):
Expand Down Expand Up @@ -118,14 +183,14 @@ async def on_teams_messaging_extension_query(
content_type=CardFactory.content_types.hero_card,
content=HeroCard(title=obj["name"]),
preview=CardFactory.hero_card(hero_card),
)
)
attachments.append(attachment)
return MessagingExtensionResponse(
compose_extension=MessagingExtensionResult(
type="result", attachment_layout="list", attachments=attachments
)
)

async def _get_auth_or_search_result(
self,
turn_context: TurnContext,
Expand Down Expand Up @@ -246,10 +311,10 @@ async def on_teams_messaging_extension_fetch_task(
card=card, height=200, title="Adaptive Card Example", width=400
)
continue_response = TaskModuleContinueResponse(
type="continue", value=task_info
value=task_info
)
return MessagingExtensionActionResponse(task=continue_response)

return None

async def on_teams_messaging_extension_select_item(
Expand All @@ -275,6 +340,40 @@ async def on_teams_messaging_extension_select_item(
)

def _get_search_results(self, query: str):
client = xmlrpc.client.ServerProxy("https://pypi.org/pypi")
search_results = client.search({"name": query})
return search_results[:10] if len(search_results) > 10 else search_results
"""
Fetch the top 10 search results from PyPI using HTML scraping.
:param query: The package name or search query
:return: List of search results
"""
search_url = f"https://pypi.org/search/?q={query}&page=1"
search_results = []

try:
# Send GET request to the PyPI search page
response = requests.get(search_url, headers={"User-Agent": "TeamsBot/1.0"})
response.raise_for_status() # Raise an exception for HTTP errors

# Parse the HTML response to extract package information
soup = BeautifulSoup(response.text, "html.parser")
for package in soup.find_all("a", class_="package-snippet", limit=10): # Limit to 10 results
name_tag = package.find("span", class_="package-snippet__name")
version_tag = package.find("span", class_="package-snippet__version")
summary_tag = package.find("p", class_="package-snippet__description")

# Safely extract text from tags, ensuring no NoneType error
name = name_tag.text if name_tag else "Unknown"
version = version_tag.text if version_tag else "N/A"
summary = summary_tag.text if summary_tag else "No description provided."

search_results.append({
"name": name,
"version": version,
"summary": summary
})
except requests.exceptions.RequestException as e:
print(f"Error fetching search results: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")

return search_results
2 changes: 1 addition & 1 deletion samples/msgext-search-auth-config/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
botbuilder-integration-aiohttp>=4.14.0
botbuilder-integration-aiohttp>=4.16.2
requests_oauthlib>=1.3.0

0 comments on commit 9bb6100

Please sign in to comment.