diff --git a/.github/workflows/package-build.yml b/.github/workflows/package-build.yml index e8492fb..85e734c 100644 --- a/.github/workflows/package-build.yml +++ b/.github/workflows/package-build.yml @@ -7,7 +7,7 @@ on: push: branches: [dev, workflows] pull_request: - branches: [dev, master] + branches: [master] jobs: build: diff --git a/.github/workflows/python-linter.yml b/.github/workflows/python-linter.yml index e464292..b0e4ae8 100644 --- a/.github/workflows/python-linter.yml +++ b/.github/workflows/python-linter.yml @@ -7,7 +7,7 @@ on: push: branches: [dev, workflows] pull_request: - branches: [dev, master] + branches: [master] jobs: build: diff --git a/README.md b/README.md index 216599b..1d029ce 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Notipyer -##### Notification Triggers for Python -Send async email notifications via Python. Get updates/crashlogs from your scripts with ease. +#### Notification Triggers for Python +Send async email and slack notifications via Python. Get updates/crashlogs from your scripts with ease. ## Installation ```bash @@ -16,7 +16,8 @@ Notipyer currently supports Gmail accounts as senders. To allow the library to u 2. Create an app password. [Ref](https://support.google.com/mail/answer/185833) 3. While creating an app password, select app as "Other (Custom name)" and enter a name of your choice. 4. Use the password obtained from app password for the configuration step below. - +5. More information can be obtained on the wiki page [here](https://github.com/chirag-jn/notipyer/wiki/Notifications-via-Email) + ### Configuration ```python from notipyer.email_notify import set_email_config @@ -38,5 +39,30 @@ bcc_recipients = ['bcc-email-1@domain.com', 'bcc-email-2@domain.com'] # Can be N send_email(subject, body, to_recipients, cc_recipients, bcc_recipients) ``` +## Slack Notifications +Notipyer currently supports running a single workplace install only. + +For setting up token keys for using slack notifications, follow the wiki page [here](https://github.com/chirag-jn/notipyer/wiki/Notifications-via-Slack) + +### Configuration +```python +from notipyer.slack_notify import set_slack_token_config + +# Follow the wiki for getting the bot token +BOT_TOKEN = 'xoxb-12345678990123-1234567890123-abcdefghijklmnopqrstuvwx' +set_slack_token_config(BOT_TOKEN) +``` +### Sending Message +```python +from notipyer.slack_notify import send_message + +# the bot should be added to the channel +channel = 'my-channel-name' +message = 'my-message' + +set_slack_token_config(SLACK_TOKEN) +send_message(channel, message) +``` + ## Contact [Chirag Jain](https://github.com/chirag-jn) \ No newline at end of file diff --git a/examples/slack_example.py b/examples/slack_example.py new file mode 100644 index 0000000..09821ff --- /dev/null +++ b/examples/slack_example.py @@ -0,0 +1,9 @@ +from notipyer.slack_notify import set_slack_token_config, send_message + +SLACK_TOKEN = 'xoxb-12345678990123-1234567890123-abcdefghijklmnopqrstuvwx' + +channel = 'my-channel-name' +message = 'my-message' + +set_slack_token_config(SLACK_TOKEN) +send_message(channel, message) diff --git a/notipyer/__init__.py b/notipyer/__init__.py index 66a87bb..4cb7e0f 100644 --- a/notipyer/__init__.py +++ b/notipyer/__init__.py @@ -1 +1,16 @@ -__version__ = '0.1.5' +from .credential_handler import credentials + +__version__ = '0.2.0' +__name__ = 'Notipyer' +__short_desc__ = 'Notification Triggers for Python' +__url__ = 'https://github.com/chirag-jn/notipyer' + + +creds = None + + +def _get_creds(): + global creds + if creds is None: + creds = credentials() + return creds diff --git a/notipyer/credential_handler.py b/notipyer/credential_handler.py index b704560..1a8cb75 100644 --- a/notipyer/credential_handler.py +++ b/notipyer/credential_handler.py @@ -1,6 +1,7 @@ class credentials: EMAIL_ID = '' EMAIL_PASS = '' + SLACK_TOKEN = '' def __init__(self): pass @@ -9,3 +10,7 @@ def __init__(self): def _set_email_credentials(cred_obj, email, password): cred_obj.EMAIL_ID = email cred_obj.EMAIL_PASS = password + + +def _set_slack_token_credentials(cred_obj, token): + cred_obj.SLACK_TOKEN = token diff --git a/notipyer/email_notify.py b/notipyer/email_notify.py index a5d0f0c..c6f73cc 100644 --- a/notipyer/email_notify.py +++ b/notipyer/email_notify.py @@ -1,11 +1,12 @@ -from .credential_handler import credentials, _set_email_credentials -from .errors import GmailLoginException, RecipientNotPresentException -from .async_decorator import Async +from .credential_handler import _set_email_credentials +from .utils.errors import GmailLoginException, RecipientNotPresentException +from .utils.async_decorator import Async +from notipyer import _get_creds import smtplib SMTP_GMAIL_URL = 'smtp.gmail.com' -mail_cred = credentials() +mail_cred = _get_creds() def _check_valid_string(string): diff --git a/notipyer/errors.py b/notipyer/errors.py deleted file mode 100644 index a8d1eb0..0000000 --- a/notipyer/errors.py +++ /dev/null @@ -1,10 +0,0 @@ -class RecipientNotPresentException(Exception): - def __init__(self): - message = 'No recipients found.' - super().__init__(message) - - -class GmailLoginException(Exception): - def __init__(self): - message = 'Either less secure app access is turned off or the Email-Password combination is incorrect.' - super().__init__(message) diff --git a/notipyer/slack_notify.py b/notipyer/slack_notify.py new file mode 100644 index 0000000..ac813e8 --- /dev/null +++ b/notipyer/slack_notify.py @@ -0,0 +1,32 @@ +from .credential_handler import _set_slack_token_credentials +from .utils.async_decorator import Async +from .utils.errors import SlackApiException +from slack import WebClient +from slack.errors import SlackApiError +from notipyer import _get_creds + +slack_creds = _get_creds() +slack_client = None + + +def set_slack_token_config(slack_token): + global slack_creds + _set_slack_token_credentials(slack_creds, slack_token) + + +def _get_slack_client(): + global slack_creds, slack_client + if slack_client is None: + slack_client = WebClient(token=slack_creds.SLACK_TOKEN) + return slack_client + + +@Async +def send_message(channel, text): + try: + _get_slack_client().chat_postMessage( + channel=channel, + text=text + ) + except SlackApiError as e: + raise SlackApiException(e) diff --git a/notipyer/async_decorator.py b/notipyer/utils/async_decorator.py similarity index 100% rename from notipyer/async_decorator.py rename to notipyer/utils/async_decorator.py diff --git a/notipyer/utils/errors.py b/notipyer/utils/errors.py new file mode 100644 index 0000000..0c6deb4 --- /dev/null +++ b/notipyer/utils/errors.py @@ -0,0 +1,21 @@ +from notipyer import __url__ as url + + +class RecipientNotPresentException(Exception): + def __init__(self): + message = 'No recipients found.' + super().__init__(message) + + +class GmailLoginException(Exception): + def __init__(self): + message = "The App password doesn't work." \ + f" Please refer README at {url}" + super().__init__(message) + + +class SlackApiException(Exception): + def __init__(self, e): + message = "The Slack trigger for the bot failed" \ + f" with the error: {e.response}" + super().__init__(message) diff --git a/requirements-test.txt b/requirements-test.txt index 9111e67..486ad89 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,14 +1,40 @@ +aiohttp==3.7.4.post0 +async-timeout==3.0.1 atomicwrites==1.4.0 attrs==21.2.0 +bleach==3.3.0 +certifi==2020.12.5 +chardet==4.0.0 colorama==0.4.4 +docutils==0.17.1 flake8==3.9.2 +idna==2.10 +importlib-metadata==4.3.1 iniconfig==1.1.1 +keyring==23.0.1 mccabe==0.6.1 +multidict==5.1.0 packaging==20.9 +pkginfo==1.7.0 pluggy==0.13.1 py==1.10.0 pycodestyle==2.7.0 pyflakes==2.3.1 +Pygments==2.9.0 pyparsing==2.4.7 pytest==6.2.4 +pywin32-ctypes==0.2.0 +readme-renderer==29.0 +requests==2.25.1 +requests-toolbelt==0.9.1 +rfc3986==1.5.0 +six==1.16.0 +slackclient==2.9.3 toml==0.10.2 +tqdm==4.61.0 +twine==3.4.1 +typing-extensions==3.10.0.0 +urllib3==1.26.5 +webencodings==0.5.1 +yarl==1.6.3 +zipp==3.4.1 diff --git a/requirements.txt b/requirements.txt index e69de29..31b9ae8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -0,0 +1,31 @@ +aiohttp==3.7.4.post0 +async-timeout==3.0.1 +attrs==21.2.0 +bleach==3.3.1 +certifi==2021.5.30 +chardet==4.0.0 +charset-normalizer==2.0.3 +colorama==0.4.4 +docutils==0.17.1 +idna==3.2 +importlib-metadata==4.6.1 +keyring==23.0.1 +multidict==5.1.0 +packaging==21.0 +pkginfo==1.7.1 +Pygments==2.9.0 +pyparsing==2.4.7 +pywin32-ctypes==0.2.0 +readme-renderer==29.0 +requests==2.26.0 +requests-toolbelt==0.9.1 +rfc3986==1.5.0 +six==1.16.0 +slackclient==2.9.3 +tqdm==4.61.2 +twine==3.4.2 +typing-extensions==3.10.0.0 +urllib3==1.26.6 +webencodings==0.5.1 +yarl==1.6.3 +zipp==3.5.0 diff --git a/setup.py b/setup.py index 9e3d63b..0f97c03 100644 --- a/setup.py +++ b/setup.py @@ -1,18 +1,22 @@ from setuptools import setup, find_packages from notipyer import __version__ as version +from notipyer import __url__ as url +from notipyer import __name__ as name +from notipyer import __short_desc__ as short_desc + with open("README.md", "r") as fh: long_description = fh.read() setup( - name='notipyer', + name=name, version=version, - description='Notification Triggers for Python', + description=short_desc, long_description=long_description, long_description_content_type="text/markdown", author='Chirag Jain', - url='https://github.com/chirag-jn/notipyer', + url=url, packages=find_packages(), include_package_data=True, classifiers=[ diff --git a/tests/credentials.py.sample b/tests/credentials.py.sample index ed30b74..9537a2f 100644 --- a/tests/credentials.py.sample +++ b/tests/credentials.py.sample @@ -1,3 +1,4 @@ username = "myemail@gmail.com" password = "myapppassword" target_email = "myemail@gmail.com" +slack_token = 'xoxb-12345678990123-1234567890123-abcdefghijklmnopqrstuvwx' \ No newline at end of file diff --git a/tests/test_slack_send.py b/tests/test_slack_send.py new file mode 100644 index 0000000..ec23729 --- /dev/null +++ b/tests/test_slack_send.py @@ -0,0 +1,6 @@ +from credentials import * + +from notipyer.slack_notify import set_slack_token_config, send_message + +set_slack_token_config(slack_token) +send_message("random", "my message")