Skip to content

Commit

Permalink
Google Cloud Support Slackbot rearchitecture for Cloud Run (GoogleClo…
Browse files Browse the repository at this point in the history
…udPlatform#772)

* Update README.md

* Refactor and rearchitecture of the Google Cloud Support Slackbot code. Makes the code container friendly by integrating it with Firestore

* README fix for code blocks

* Final README fixes

* updating .dockerignore

* Updated Dockerfile and changed SupportCase.py to support_case.py

Co-authored-by: Abdel SGHIOUAR <[email protected]>
  • Loading branch information
TheLanceLord and boredabdel authored Feb 25, 2022
1 parent 649f501 commit 2a35d9b
Show file tree
Hide file tree
Showing 33 changed files with 2,838 additions and 167 deletions.
11 changes: 11 additions & 0 deletions tools/google-cloud-support-slackbot/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Dockerfile
error.log
env.list
freeze.txt
.dockerignore
archive/*
archive
google_cloud_support_slackbot_icon_big.png
google_cloud_support_slackbot_icon_small.png
google_cloud_support_slackbot_icon.svg
README.md
50 changes: 50 additions & 0 deletions tools/google-cloud-support-slackbot/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

FROM python:3.7-slim AS compile-image
LABEL author="Damian Lance"
LABEL created="2022-01-19"
LABEL last_updated="2022-01-19"

RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

COPY . ./
RUN apt-get update; \
apt-get -y install \
libffi-dev \
libssl-dev; \
pip3 install -r requirements.txt;

FROM python:3.7-slim AS build-image

# Essential environment variables
ENV ORG_ID="YOUR NUMERIC ORG ID"
ENV SLACK_TOKEN="YOUR SLACK TOKEN"
ENV SIGNING_SECRET="YOUR SLACK SIGNING SECRET"
ENV API_KEY="YOUR API KEY FOR GOOGLE CLOUD SUPPORT AND CLOUD FIRESTORE"

# Testing environment variables
ENV TEST_CHANNEL_ID="SLACK CHANNEL ID FOR TESTING"
ENV TEST_CHANNEL_NAME="SLACK CHANNEL NAME FOR TESTING"
ENV TEST_USER_ID="SLACK USER_ID FOR TESTING"
ENV TEST_USER_NAME="SLACK USER_NAME FOR TESTING"
ENV PROJECT_ID="GOOGLE CLOUD PROJECT ID FOR SUPPORT CASES"
ENV PROJECT_NUMBER="GOOGLE CLOUD PROJECT NUMBER FOR SUPPORT CASES"

COPY --from=compile-image . ./
ENV PATH="/opt/venv/bin:$PATH"

ENTRYPOINT /main.py

247 changes: 124 additions & 123 deletions tools/google-cloud-support-slackbot/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2021 Google LLC
# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env python3

# Copyright 2021 Google LLC
# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
aiohttp==3.7.4.post0
asn1crypto==0.24.0
async-timeout==3.0.1
attrs==21.2.0
cachetools==4.2.2
certifi==2021.5.30
click==7.1.2
crcmod==1.7
cryptography==2.6.1
distro-info==0.21
entrypoints==0.3
Flask==1.1.4
gevent==21.8.0
google-api-core==1.31.0
google-api-python-client==2.12.0
google-auth==1.32.1
google-auth-httplib2==0.1.0
googleapis-common-protos==1.53.0
greenlet==1.1.1
httplib2==0.19.1
idna==2.10
importlib-metadata==4.5.0
itsdangerous==1.1.0
Jinja2==2.11.3
keyring==17.1.1
keyrings.alt==3.1.1
MarkupSafe==1.1.1
multidict==5.1.0
packaging==21.0
protobuf==3.17.3
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycrypto==2.6.1
pyee==7.0.4
PyGObject==3.30.4
pyparsing==2.4.7
python-apt==1.8.4.3
python-dotenv==0.18.0
pytz==2021.1
pyxdg==0.25
requests==2.25.1
rsa==4.7.2
SecretStorage==2.3.1
six==1.16.0
slackclient==2.9.3
slackeventsapi==2.2.1
typing-extensions==3.10.0.0
unattended-upgrades==0.1
uritemplate==3.0.1
urllib3==1.26.6
Werkzeug==1.0.1
yarl==1.6.3
zipp==3.4.1
zope.event==4.5.0
zope.interface==5.4.0
64 changes: 64 additions & 0 deletions tools/google-cloud-support-slackbot/case_details.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3

# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import slack
import json
import logging
from case_not_found import case_not_found
from get_firestore_cases import get_firestore_cases

logger = logging.getLogger(__name__)


def case_details(channel_id, case, user_id):
"""
Sends the data of a single case as json to the channel where the request originated.
Parameters
----------
channel_id : str
unique string used to idenify a Slack channel. Used to send messages to the channel
case : str
unique id of the case
user_id : str
the Slack user_id of the user who submitted the request. Used to send ephemeral
messages to the user
"""
client = slack.WebClient(token=os.environ.get('SLACK_TOKEN'))
cases = get_firestore_cases()
break_flag = False

for fs_case in cases:
if case == fs_case['case_number']:
pretty_json = json.dumps(fs_case, indent=4, sort_keys=True)
client.chat_postMessage(
channel=channel_id,
text=f"Here are the details on case {case}: \n{pretty_json}")
break_flag = True
break

if break_flag is False:
case_not_found(channel_id, user_id, case)


if __name__ == "__main__":
channel_id = os.environ.get('TEST_CHANNEL_ID')
case = 'xxxxxxxx'
user_id = os.environ.get('TEST_USER_ID')
case_details(channel_id, case, user_id)
case = os.environ.get('TEST_CASE')
case_details(channel_id, case, user_id)
57 changes: 57 additions & 0 deletions tools/google-cloud-support-slackbot/case_not_found.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3

# Copyright 2022 Google LLC

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import slack
import logging
from datetime import datetime

logger = logging.getLogger(__name__)


def case_not_found(channel_id, user_id, case):
"""
Informs the user of their case could not be found.
Parameters
----------
channel_id : str
unique string used to idenify a Slack channel. Used to send messages to the channel
user_id : str
the Slack user_id of the user who submitted the request. Used to send ephemeral
messages to the user
case : str
unique id of the case
"""
client = slack.WebClient(token=os.environ.get('SLACK_TOKEN'))
try:
client.chat_postEphemeral(
channel=channel_id,
user=user_id,
text=f"Case {case} could not be found in your org. If this case was recently"
" created, please give the system 60 seconds to fetch it. Otherwise,"
" double check your case number or confirm the org being tracked"
" with your Slack admin.")
except slack.errors.SlackApiError as e:
error_message = str(e) + ' : {}'.format(datetime.now())
logger.error(error_message)


if __name__ == "__main__":
channel_id = os.environ.get('TEST_CHANNEL_ID')
user_id = os.environ.get('TEST_USER_ID')
case = "xxxxxxxx"
case_not_found(channel_id, user_id, case)
Loading

0 comments on commit 2a35d9b

Please sign in to comment.