feat(chalice): msteams add
feat(chalice): msteams update feat(chalice): msteams share session feat(chalice): msteams share error
This commit is contained in:
parent
e176f9bd44
commit
30eca5e8fb
7 changed files with 129 additions and 75 deletions
|
|
@ -30,7 +30,7 @@ class BaseCollaboration(ABC):
|
|||
|
||||
@classmethod
|
||||
@abstractmethod
|
||||
def __share(cls, tenant_id, integration_id, fallback, pretext, title, title_link, text):
|
||||
def __share(cls, tenant_id, integration_id, attachments):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import requests
|
||||
from decouple import config
|
||||
from datetime import datetime
|
||||
|
||||
import schemas
|
||||
from chalicelib.core import webhook
|
||||
|
|
@ -16,6 +15,7 @@ class MSTeams(BaseCollaboration):
|
|||
webhook_type="msteams",
|
||||
name=data.name)
|
||||
return None
|
||||
|
||||
# https://messagecardplayground.azurewebsites.net
|
||||
@classmethod
|
||||
def say_hello(cls, url):
|
||||
|
|
@ -58,6 +58,7 @@ class MSTeams(BaseCollaboration):
|
|||
|
||||
@classmethod
|
||||
def send_batch(cls, tenant_id, webhook_id, attachments):
|
||||
# TODO: change this
|
||||
integration = cls.__get(tenant_id=tenant_id, integration_id=webhook_id)
|
||||
if integration is None:
|
||||
return {"errors": ["slack integration not found"]}
|
||||
|
|
@ -72,50 +73,87 @@ class MSTeams(BaseCollaboration):
|
|||
print(r.text)
|
||||
|
||||
@classmethod
|
||||
def __share(cls, tenant_id, integration_id, fallback, pretext, title, title_link, text):
|
||||
def __share(cls, tenant_id, integration_id, attachement):
|
||||
integration = cls.__get(tenant_id=tenant_id, integration_id=integration_id)
|
||||
if integration is None:
|
||||
return {"errors": ["slack integration not found"]}
|
||||
return {"errors": ["Microsoft Teams integration not found"]}
|
||||
r = requests.post(
|
||||
url=integration["endpoint"],
|
||||
json={
|
||||
"attachments": [
|
||||
{
|
||||
"fallback": fallback,
|
||||
"pretext": pretext,
|
||||
"title": title,
|
||||
"title_link": title_link,
|
||||
"text": text,
|
||||
"ts": datetime.now().timestamp()
|
||||
}
|
||||
]
|
||||
})
|
||||
json={"type": "message",
|
||||
"attachments": [
|
||||
{"contentType": "application/vnd.microsoft.card.adaptive",
|
||||
"contentUrl": None,
|
||||
"content": {
|
||||
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
|
||||
"type": "AdaptiveCard",
|
||||
"version": "1.2",
|
||||
"body": [attachement]}}
|
||||
]
|
||||
})
|
||||
|
||||
return r.text
|
||||
|
||||
@classmethod
|
||||
def share_session(cls, tenant_id, project_id, session_id, user, comment, integration_id=None):
|
||||
args = {"fallback": f"{user} has shared the below session!",
|
||||
"pretext": f"{user} has shared the below session!",
|
||||
"title": f"{config('SITE_URL')}/{project_id}/session/{session_id}",
|
||||
"title_link": f"{config('SITE_URL')}/{project_id}/session/{session_id}",
|
||||
"text": comment}
|
||||
return {"data": cls.__share(tenant_id, integration_id, **args)}
|
||||
title = f"[{user}](mailto:{user}) has shared the below session!"
|
||||
link = f"{config('SITE_URL')}/{project_id}/session/{session_id}"
|
||||
link = f"[{link}]({link})"
|
||||
args = {"type": "ColumnSet",
|
||||
"columns": [{
|
||||
"width": "stretch",
|
||||
"items": [
|
||||
{"type": "TextBlock",
|
||||
"text": title},
|
||||
{"type": "TextBlock",
|
||||
"spacing": "small",
|
||||
"text": link}
|
||||
]
|
||||
}]}
|
||||
if comment and len(comment) > 0:
|
||||
args["columns"][0]["items"].append({
|
||||
"type": "TextBlock",
|
||||
"spacing": "small",
|
||||
"text": comment
|
||||
})
|
||||
data = cls.__share(tenant_id, integration_id, attachement=args)
|
||||
if "errors" in data:
|
||||
return data
|
||||
return {"data": data}
|
||||
|
||||
@classmethod
|
||||
def share_error(cls, tenant_id, project_id, error_id, user, comment, integration_id=None):
|
||||
args = {"fallback": f"{user} has shared the below error!",
|
||||
"pretext": f"{user} has shared the below error!",
|
||||
"title": f"{config('SITE_URL')}/{project_id}/errors/{error_id}",
|
||||
"title_link": f"{config('SITE_URL')}/{project_id}/errors/{error_id}",
|
||||
"text": comment}
|
||||
return {"data": cls.__share(tenant_id, integration_id, **args)}
|
||||
title = f"[{user}](mailto:{user}) has shared the below error!"
|
||||
link = f"{config('SITE_URL')}/{project_id}/errors/{error_id}"
|
||||
link = f"[{link}]({link})"
|
||||
args = {"type": "ColumnSet",
|
||||
"columns": [{
|
||||
"width": "stretch",
|
||||
"items": [
|
||||
{"type": "TextBlock",
|
||||
"text": title},
|
||||
{"type": "TextBlock",
|
||||
"spacing": "small",
|
||||
"text": link}
|
||||
]
|
||||
}]}
|
||||
if comment and len(comment) > 0:
|
||||
args["columns"][0]["items"].append({
|
||||
"type": "TextBlock",
|
||||
"spacing": "small",
|
||||
"text": comment
|
||||
})
|
||||
data = cls.__share(tenant_id, integration_id, attachement=args)
|
||||
if "errors" in data:
|
||||
return data
|
||||
return {"data": data}
|
||||
|
||||
@classmethod
|
||||
def __get(cls, tenant_id, integration_id=None):
|
||||
if integration_id is not None:
|
||||
return webhook.get(tenant_id=tenant_id, webhook_id=integration_id)
|
||||
return webhook.get_webhook(tenant_id=tenant_id, webhook_id=integration_id,
|
||||
webhook_type=schemas.WebhookType.msteams)
|
||||
|
||||
integrations = webhook.get_by_type(tenant_id=tenant_id, webhook_type="slack")
|
||||
integrations = webhook.get_by_type(tenant_id=tenant_id, webhook_type=schemas.WebhookType.msteams)
|
||||
if integrations is None or len(integrations) == 0:
|
||||
return None
|
||||
return integrations[0]
|
||||
|
|
|
|||
|
|
@ -75,24 +75,12 @@ class Slack(BaseCollaboration):
|
|||
print(r.text)
|
||||
|
||||
@classmethod
|
||||
def __share(cls, tenant_id, integration_id, fallback, pretext, title, title_link, text):
|
||||
def __share(cls, tenant_id, integration_id, attachement):
|
||||
integration = cls.__get(tenant_id=tenant_id, integration_id=integration_id)
|
||||
if integration is None:
|
||||
return {"errors": ["slack integration not found"]}
|
||||
r = requests.post(
|
||||
url=integration["endpoint"],
|
||||
json={
|
||||
"attachments": [
|
||||
{
|
||||
"fallback": fallback,
|
||||
"pretext": pretext,
|
||||
"title": title,
|
||||
"title_link": title_link,
|
||||
"text": text,
|
||||
"ts": datetime.now().timestamp()
|
||||
}
|
||||
]
|
||||
})
|
||||
attachement["ts"] = datetime.now().timestamp()
|
||||
r = requests.post(url=integration["endpoint"], json={"attachments": [attachement]})
|
||||
return r.text
|
||||
|
||||
@classmethod
|
||||
|
|
@ -102,7 +90,10 @@ class Slack(BaseCollaboration):
|
|||
"title": f"{config('SITE_URL')}/{project_id}/session/{session_id}",
|
||||
"title_link": f"{config('SITE_URL')}/{project_id}/session/{session_id}",
|
||||
"text": comment}
|
||||
return {"data": cls.__share(tenant_id, integration_id, **args)}
|
||||
data = cls.__share(tenant_id, integration_id, attachement=args)
|
||||
if "errors" in data:
|
||||
return data
|
||||
return {"data": data}
|
||||
|
||||
@classmethod
|
||||
def share_error(cls, tenant_id, project_id, error_id, user, comment, integration_id=None):
|
||||
|
|
@ -111,14 +102,18 @@ class Slack(BaseCollaboration):
|
|||
"title": f"{config('SITE_URL')}/{project_id}/errors/{error_id}",
|
||||
"title_link": f"{config('SITE_URL')}/{project_id}/errors/{error_id}",
|
||||
"text": comment}
|
||||
return {"data": cls.__share(tenant_id, integration_id, **args)}
|
||||
data = cls.__share(tenant_id, integration_id, attachement=args)
|
||||
if "errors" in data:
|
||||
return data
|
||||
return {"data": data}
|
||||
|
||||
@classmethod
|
||||
def __get(cls, tenant_id, integration_id=None):
|
||||
if integration_id is not None:
|
||||
return webhook.get(tenant_id=tenant_id, webhook_id=integration_id)
|
||||
return webhook.get_webhook(tenant_id=tenant_id, webhook_id=integration_id,
|
||||
webhook_type=schemas.WebhookType.slack)
|
||||
|
||||
integrations = webhook.get_by_type(tenant_id=tenant_id, webhook_type="slack")
|
||||
integrations = webhook.get_by_type(tenant_id=tenant_id, webhook_type=schemas.WebhookType.slack)
|
||||
if integrations is None or len(integrations) == 0:
|
||||
return None
|
||||
return integrations[0]
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ def get_by_id(webhook_id):
|
|||
return w
|
||||
|
||||
|
||||
def get(tenant_id, webhook_id):
|
||||
def get_webhook(tenant_id, webhook_id, webhook_type='webhook'):
|
||||
with pg_client.PostgresClient() as cur:
|
||||
cur.execute(
|
||||
cur.mogrify("""SELECT w.*
|
||||
FROM public.webhooks AS w
|
||||
WHERE w.webhook_id =%(webhook_id)s
|
||||
AND deleted_at ISNULL AND type='webhook';""",
|
||||
{"webhook_id": webhook_id})
|
||||
AND deleted_at ISNULL AND type=%(webhook_type)s;""",
|
||||
{"webhook_id": webhook_id, "webhook_type": webhook_type})
|
||||
)
|
||||
w = helper.dict_to_camel_case(cur.fetchone())
|
||||
if w:
|
||||
|
|
@ -70,7 +70,7 @@ def update(tenant_id, webhook_id, changes, replace_none=False):
|
|||
UPDATE public.webhooks
|
||||
SET {','.join(sub_query)}
|
||||
WHERE webhook_id =%(id)s AND deleted_at ISNULL
|
||||
RETURNING webhook_id AS integration_id, webhook_id AS id,*;""",
|
||||
RETURNING *;""",
|
||||
{"id": webhook_id, **changes})
|
||||
)
|
||||
w = helper.dict_to_camel_case(cur.fetchone())
|
||||
|
|
@ -87,7 +87,7 @@ def add(tenant_id, endpoint, auth_header=None, webhook_type='webhook', name="",
|
|||
query = cur.mogrify("""\
|
||||
INSERT INTO public.webhooks(endpoint,auth_header,type,name)
|
||||
VALUES (%(endpoint)s, %(auth_header)s, %(type)s,%(name)s)
|
||||
RETURNING webhook_id AS integration_id, webhook_id AS id,*;""",
|
||||
RETURNING *;""",
|
||||
{"endpoint": endpoint, "auth_header": auth_header,
|
||||
"type": webhook_type, "name": name})
|
||||
cur.execute(
|
||||
|
|
|
|||
|
|
@ -97,21 +97,27 @@ def get_integrations_status(projectId: int, context: schemas.CurrentContext = De
|
|||
return {"data": data}
|
||||
|
||||
|
||||
@app.post('/{projectId}/integrations/{integration}/notify/{integrationId}/{source}/{sourceId}', tags=["integrations"])
|
||||
def integration_notify(projectId: int, integration: str, integrationId: int, source: str, sourceId: str,
|
||||
@app.post('/{projectId}/integrations/{integration}/notify/{webhookId}/{source}/{sourceId}', tags=["integrations"])
|
||||
def integration_notify(projectId: int, integration: str, webhookId: int, source: str, sourceId: str,
|
||||
data: schemas.IntegrationNotificationSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
comment = None
|
||||
if data.comment:
|
||||
comment = data.comment
|
||||
if integration == "slack":
|
||||
args = {"tenant_id": context.tenant_id,
|
||||
"user": context.email, "comment": comment, "project_id": projectId,
|
||||
"integration_id": integrationId}
|
||||
|
||||
args = {"tenant_id": context.tenant_id,
|
||||
"user": context.email, "comment": comment, "project_id": projectId,
|
||||
"integration_id": webhookId}
|
||||
if integration == schemas.WebhookType.slack:
|
||||
if source == "sessions":
|
||||
return Slack.share_session(session_id=sourceId, **args)
|
||||
elif source == "errors":
|
||||
return Slack.share_error(error_id=sourceId, **args)
|
||||
elif integration == schemas.WebhookType.msteams:
|
||||
if source == "sessions":
|
||||
return MSTeams.share_session(session_id=sourceId, **args)
|
||||
elif source == "errors":
|
||||
return Slack.share_error(error_id=sourceId, **args)
|
||||
return {"data": None}
|
||||
|
||||
|
||||
|
|
@ -856,17 +862,18 @@ def get_boarding_state_integrations(context: schemas.CurrentContext = Depends(OR
|
|||
|
||||
@app.get('/integrations/slack/channels', tags=["integrations"])
|
||||
def get_slack_channels(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": webhook.get_by_type(tenant_id=context.tenant_id, webhook_type='slack')}
|
||||
return {"data": webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.slack)}
|
||||
|
||||
|
||||
@app.get('/integrations/slack/{integrationId}', tags=["integrations"])
|
||||
def get_slack_webhook(integrationId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": webhook.get(tenant_id=context.tenant_id, webhook_id=integrationId)}
|
||||
@app.get('/integrations/slack/{webhookId}', tags=["integrations"])
|
||||
def get_slack_webhook(webhookId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": webhook.get_webhook(tenant_id=context.tenant_id, webhook_id=webhookId,
|
||||
webhook_type=schemas.WebhookType.slack)}
|
||||
|
||||
|
||||
@app.delete('/integrations/slack/{integrationId}', tags=["integrations"])
|
||||
def delete_slack_integration(integrationId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return webhook.delete(context.tenant_id, integrationId)
|
||||
@app.delete('/integrations/slack/{webhookId}', tags=["integrations"])
|
||||
def delete_slack_integration(webhookId: int, context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return webhook.delete(context.tenant_id, webhookId)
|
||||
|
||||
|
||||
@app.put('/webhooks', tags=["webhooks"])
|
||||
|
|
@ -950,29 +957,36 @@ def get_limits(context: schemas.CurrentContext = Depends(OR_context)):
|
|||
}
|
||||
|
||||
|
||||
@app.get('/integrations/msteams/channels', tags=["integrations"])
|
||||
def get_msteams_channels(context: schemas.CurrentContext = Depends(OR_context)):
|
||||
return {"data": webhook.get_by_type(tenant_id=context.tenant_id, webhook_type=schemas.WebhookType.msteams)}
|
||||
|
||||
|
||||
@app.post('/integrations/msteams', tags=['integrations'])
|
||||
def add_msteams_integration(data: schemas.AddCollaborationSchema,
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
n = MSTeams.add(tenant_id=context.tenant_id, data=data)
|
||||
if n is None:
|
||||
return {
|
||||
"errors": ["We couldn't send you a test message on your Microsoft Teams channel. Please verify your webhook url."]
|
||||
"errors": [
|
||||
"We couldn't send you a test message on your Microsoft Teams channel. Please verify your webhook url."]
|
||||
}
|
||||
return {"data": n}
|
||||
|
||||
|
||||
@app.post('/integrations/msteams/{integrationId}', tags=['integrations'])
|
||||
def edit_msteams_integration(integrationId: int, data: schemas.EditCollaborationSchema = Body(...),
|
||||
@app.post('/integrations/msteams/{webhookId}', tags=['integrations'])
|
||||
def edit_msteams_integration(webhookId: int, data: schemas.EditCollaborationSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
if len(data.url) > 0:
|
||||
old = webhook.get(tenant_id=context.tenant_id, webhook_id=integrationId)
|
||||
old = webhook.get_webhook(tenant_id=context.tenant_id, webhook_id=webhookId,
|
||||
webhook_type=schemas.WebhookType.msteams)
|
||||
if old["endpoint"] != data.url:
|
||||
if not Slack.say_hello(data.url):
|
||||
if not MSTeams.say_hello(data.url):
|
||||
return {
|
||||
"errors": [
|
||||
"We couldn't send you a test message on your Slack channel. Please verify your webhook url."]
|
||||
"We couldn't send you a test message on your Microsoft Teams channel. Please verify your webhook url."]
|
||||
}
|
||||
return {"data": webhook.update(tenant_id=context.tenant_id, webhook_id=integrationId,
|
||||
return {"data": webhook.update(tenant_id=context.tenant_id, webhook_id=webhookId,
|
||||
changes={"name": data.name, "endpoint": data.url})}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ def add_slack_integration(data: schemas.AddCollaborationSchema, context: schemas
|
|||
def edit_slack_integration(integrationId: int, data: schemas.EditCollaborationSchema = Body(...),
|
||||
context: schemas.CurrentContext = Depends(OR_context)):
|
||||
if len(data.url) > 0:
|
||||
old = webhook.get(tenant_id=context.tenant_id, webhook_id=integrationId)
|
||||
old = webhook.get_webhook(tenant_id=context.tenant_id, webhook_id=integrationId)
|
||||
if old["endpoint"] != data.url:
|
||||
if not Slack.say_hello(data.url):
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1120,3 +1120,10 @@ class SessionUpdateNoteSchema(SessionNoteSchema):
|
|||
break
|
||||
assert c > 0, "at least 1 value should be provided for update"
|
||||
return values
|
||||
|
||||
|
||||
class WebhookType(str, Enum):
|
||||
webhook = "webhook"
|
||||
slack = "slack"
|
||||
email = "email"
|
||||
msteams = "msteams"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue