diff --git a/KEYWORDS b/KEYWORDS
index d1fcf9c2..3a58af59 100644
--- a/KEYWORDS
+++ b/KEYWORDS
@@ -86,6 +86,7 @@ Twist
Twitter
Vonage
Webex
+WhatsApp
Windows
Voipms
XBMC
diff --git a/README.md b/README.md
index 594a98d7..e3c61686 100644
--- a/README.md
+++ b/README.md
@@ -122,6 +122,7 @@ The table below identifies the services this tool supports and some example serv
| [Twist](https://github.com/caronc/apprise/wiki/Notify_twist) | twist:// | (TCP) 443 | twist://pasword:login
twist://password:login/#channel
twist://password:login/#team:channel
twist://password:login/#team:channel1/channel2/#team3:channel
| [XBMC](https://github.com/caronc/apprise/wiki/Notify_xbmc) | xbmc:// or xbmcs:// | (TCP) 8080 or 443 | xbmc://hostname
xbmc://user@hostname
xbmc://user:password@hostname:port
| [Webex Teams (Cisco)](https://github.com/caronc/apprise/wiki/Notify_wxteams) | wxteams:// | (TCP) 443 | wxteams://Token
+| [WhatsApp](https://github.com/caronc/apprise/wiki/Notify_whatsapp) | whatsapp:// | (TCP) 443 | whatsapp://AccessToken@FromPhoneID/ToPhoneNo
whatsapp://Template:AccessToken@FromPhoneID/ToPhoneNo
| [Zulip Chat](https://github.com/caronc/apprise/wiki/Notify_zulip) | zulip:// | (TCP) 443 | zulip://botname@Organization/Token
zulip://botname@Organization/Token/Stream
zulip://botname@Organization/Token/Email
## SMS Notifications
diff --git a/apprise/plugins/NotifyWhatsApp.py b/apprise/plugins/NotifyWhatsApp.py
new file mode 100644
index 00000000..065f2d7b
--- /dev/null
+++ b/apprise/plugins/NotifyWhatsApp.py
@@ -0,0 +1,563 @@
+# -*- coding: utf-8 -*-
+# BSD 3-Clause License
+#
+# Apprise - Push Notification Library.
+# Copyright (c) 2023, Chris Caron
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# API Source:
+# https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages
+#
+# 1. Register a developer account with Meta:
+# https://developers.facebook.com/docs/whatsapp/cloud-api/get-started
+# 2. Enable 2 Factor Authentication (2FA) with your account (if not done
+# already)
+# 3. Create a App using WhatsApp Product. There are 2 to create an app from
+# Do NOT chose the WhatsApp Webhook one (choose the other)
+#
+# When you click on the API Setup section of your new app you need to record
+# both the access token and the From Phone Number ID. Note that this not the
+# from phone number itself, but it's ID. It's displayed below and contains
+# way more numbers then your typical phone number
+
+import re
+import requests
+from json import loads, dumps
+from .NotifyBase import NotifyBase
+from ..common import NotifyType
+from ..utils import is_phone_no
+from ..utils import parse_phone_no
+from ..utils import validate_regex
+from ..AppriseLocale import gettext_lazy as _
+
+
+class NotifyWhatsApp(NotifyBase):
+ """
+ A wrapper for WhatsApp Notifications
+ """
+
+ # The default descriptive name associated with the Notification
+ service_name = 'WhatsApp'
+
+ # The services URL
+ service_url = \
+ 'https://developers.facebook.com/docs/whatsapp/cloud-api/get-started'
+
+ # All notification requests are secure
+ secure_protocol = 'whatsapp'
+
+ # Allow 300 requests per minute.
+ # 60/300 = 0.2
+ request_rate_per_sec = 0.20
+
+ # Facebook Graph version
+ fb_graph_version = 'v17.0'
+
+ # A URL that takes you to the setup/help of the specific protocol
+ setup_url = 'https://github.com/caronc/apprise/wiki/Notify_whatsapp'
+
+ # WhatsApp Message Notification URL
+ notify_url = 'https://graph.facebook.com/{fb_ver}/{phone_id}/messages'
+
+ # The maximum length of the body
+ body_maxlen = 1024
+
+ # A title can not be used for SMS Messages. Setting this to zero will
+ # cause any title (if defined) to get placed into the message body.
+ title_maxlen = 0
+
+ # Define object templates
+ templates = (
+ '{schema}://{token}@{from_phone_id}/{targets}',
+ '{schema}://{template}:{token}@{from_phone_id}/{targets}',
+ )
+
+ # Define our template tokens
+ template_tokens = dict(NotifyBase.template_tokens, **{
+ 'token': {
+ 'name': _('Access Token'),
+ 'type': 'string',
+ 'private': True,
+ 'required': True,
+ 'regex': (r'^[a-z0-9]+$', 'i'),
+ },
+ 'template': {
+ 'name': _('Template Name'),
+ 'type': 'string',
+ 'required': False,
+ 'regex': (r'^[^\s]+$', 'i'),
+ },
+ 'from_phone_id': {
+ 'name': _('From Phone ID'),
+ 'type': 'string',
+ 'private': True,
+ 'required': True,
+ 'regex': (r'^[0-9]+$', 'i'),
+ },
+ 'target_phone': {
+ 'name': _('Target Phone No'),
+ 'type': 'string',
+ 'prefix': '+',
+ 'regex': (r'^[0-9\s)(+-]+$', 'i'),
+ 'map_to': 'targets',
+ },
+ 'targets': {
+ 'name': _('Targets'),
+ 'type': 'list:string',
+ },
+ 'language': {
+ 'name': _('Language'),
+ 'type': 'string',
+ 'default': 'en_US',
+ 'regex': (r'^[^0-9\s]+$', 'i'),
+ },
+ })
+
+ # Define our template arguments
+ template_args = dict(NotifyBase.template_args, **{
+ 'to': {
+ 'alias_of': 'targets',
+ },
+ 'from': {
+ 'alias_of': 'from_phone_id',
+ },
+ 'token': {
+ 'alias_of': 'token',
+ },
+ 'template': {
+ 'alias_of': 'template',
+ },
+ 'lang': {
+ 'alias_of': 'language',
+ },
+ })
+
+ # Our supported mappings and component keys
+ component_key_re = re.compile(
+ r'(?P((?P[1-9][0-9]*)|(?P