diff --git a/frappe/core/doctype/role/role.py b/frappe/core/doctype/role/role.py
index e458b401e4..1920189f78 100644
--- a/frappe/core/doctype/role/role.py
+++ b/frappe/core/doctype/role/role.py
@@ -37,7 +37,7 @@ class Role(Document):
def get_info_based_on_role(role, field='email'):
''' Get information of all users that have been assigned this role '''
users = frappe.get_list("Has Role", filters={"role": role, "parenttype": "User"},
- fields=["parent"])
+ fields=["parent as user_name"])
return get_user_info(users, field)
@@ -45,7 +45,7 @@ def get_user_info(users, field='email'):
''' Fetch details about users for the specified field '''
info_list = []
for user in users:
- user_info, enabled = frappe.db.get_value("User", user.parent, [field, "enabled"])
+ user_info, enabled = frappe.db.get_value("User", user.get("user_name"), [field, "enabled"])
if enabled and user_info not in ["admin@example.com", "guest@example.com"]:
info_list.append(user_info)
return info_list
diff --git a/frappe/email/doctype/notification/notification.js b/frappe/email/doctype/notification/notification.js
index 2cc027acd6..27fcd0e453 100644
--- a/frappe/email/doctype/notification/notification.js
+++ b/frappe/email/doctype/notification/notification.js
@@ -97,14 +97,7 @@ frappe.notification = {
},
setup_example_message: function(frm) {
let template = '';
- if (frm.doc.channel === 'WhatsApp') {
- template = `
Warning:
Only Use Pre-Approved WhatsApp for Business Template
-Message Example
-
-
-Your appointment is coming up on {{ doc.date }} at {{ doc.time }}
-`;
- } else if (frm.doc.channel === 'Email') {
+ if (frm.doc.channel === 'Email') {
template = `Message Example
<h3>Order Overdue</h3>
@@ -124,7 +117,7 @@ Last comment: {{ comments[-1].comment }} by {{ comments[-1].by }}
</ul>
`;
- } else {
+ } else if (in_list(['Slack', 'System Notification', 'SMS'], frm.doc.channel)) {
template = `Message Example
*Order Overdue*
@@ -142,7 +135,9 @@ Last comment: {{ comments[-1].comment }} by {{ comments[-1].by }}
• Amount: {{ doc.grand_total }}
`;
}
- frm.set_df_property('message_examples', 'options', template);
+ if (template) {
+ frm.set_df_property('message_examples', 'options', template);
+ }
}
};
diff --git a/frappe/email/doctype/notification/notification.json b/frappe/email/doctype/notification/notification.json
index 2a8ee1aeb1..73a84e1d3e 100644
--- a/frappe/email/doctype/notification/notification.json
+++ b/frappe/email/doctype/notification/notification.json
@@ -10,7 +10,6 @@
"enabled",
"column_break_2",
"channel",
- "twilio_number",
"slack_webhook_url",
"filters",
"subject",
@@ -61,7 +60,7 @@
"fieldname": "channel",
"fieldtype": "Select",
"label": "Channel",
- "options": "Email\nSlack\nSystem Notification\nWhatsApp\nSMS",
+ "options": "Email\nSlack\nSystem Notification\nSMS",
"reqd": 1,
"set_only_once": 1
},
@@ -80,14 +79,14 @@
"label": "Filters"
},
{
- "depends_on": "eval: !in_list(['SMS', 'WhatsApp'], doc.channel)",
+ "depends_on": "eval: in_list(['Email', 'Slack', 'System Notification'], doc.channel)",
"description": "To add dynamic subject, use jinja tags like\n\n",
"fieldname": "subject",
"fieldtype": "Data",
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Subject",
- "mandatory_depends_on": "eval:!in_list(['SMS', 'WhatsApp'], doc.channel)"
+ "mandatory_depends_on": "eval: in_list(['Email', 'Slack', 'System Notification'], doc.channel)"
},
{
"fieldname": "document_type",
@@ -208,7 +207,7 @@
"label": "Value To Be Set"
},
{
- "depends_on": "eval:in_list(['Email', 'SMS', 'WhatsApp'], doc.channel)",
+ "depends_on": "eval:in_list(['Email', 'SMS'], doc.channel)",
"fieldname": "column_break_5",
"fieldtype": "Section Break",
"label": "Recipients"
@@ -263,15 +262,6 @@
"label": "Print Format",
"options": "Print Format"
},
- {
- "depends_on": "eval: doc.channel==='WhatsApp'",
- "description": "To use WhatsApp for Business, initialize Twilio Settings.",
- "fieldname": "twilio_number",
- "fieldtype": "Link",
- "label": "Twilio Number",
- "mandatory_depends_on": "eval: doc.channel==='WhatsApp'",
- "options": "Twilio Number Group"
- },
{
"default": "0",
"depends_on": "eval: doc.channel !== 'System Notification'",
@@ -291,7 +281,7 @@
"icon": "fa fa-envelope",
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2020-09-03 10:33:23.084590",
+ "modified": "2020-10-28 11:04:54.955567",
"modified_by": "Administrator",
"module": "Email",
"name": "Notification",
diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py
index 62be313b82..75281d427e 100644
--- a/frappe/email/doctype/notification/notification.py
+++ b/frappe/email/doctype/notification/notification.py
@@ -14,7 +14,6 @@ from frappe.utils.safe_exec import get_safe_globals
from frappe.modules.utils import export_module_json, get_doc_module
from six import string_types
from frappe.integrations.doctype.slack_webhook_url.slack_webhook_url import send_slack_message
-from frappe.integrations.doctype.twilio_settings.twilio_settings import send_whatsapp_message
from frappe.core.doctype.sms_settings.sms_settings import send_sms
from frappe.desk.doctype.notification_log.notification_log import enqueue_create_notification
@@ -29,7 +28,7 @@ class Notification(Document):
self.name = self.subject
def validate(self):
- if self.channel not in ('WhatsApp', 'SMS'):
+ if self.channel in ("Email", "Slack", "System Notification"):
validate_template(self.subject)
validate_template(self.message)
@@ -43,7 +42,6 @@ class Notification(Document):
self.validate_forbidden_types()
self.validate_condition()
self.validate_standard()
- self.validate_twilio_settings()
frappe.cache().hdel('notifications', self.document_type)
def on_update(self):
@@ -70,11 +68,6 @@ def get_context(context):
if self.is_standard and not frappe.conf.developer_mode:
frappe.throw(_('Cannot edit Standard Notification. To edit, please disable this and duplicate it'))
- def validate_twilio_settings(self):
- if self.enabled and self.channel == "WhatsApp" \
- and not frappe.db.get_single_value("Twilio Settings", "enabled"):
- frappe.throw(_("Please enable Twilio settings to send WhatsApp messages"))
-
def validate_condition(self):
temp_doc = frappe.new_doc(self.document_type)
if self.condition:
@@ -137,9 +130,6 @@ def get_context(context):
if self.channel == 'Slack':
self.send_a_slack_msg(doc, context)
- if self.channel == 'WhatsApp':
- self.send_whatsapp_msg(doc, context)
-
if self.channel == 'SMS':
self.send_sms(doc, context)
@@ -230,13 +220,6 @@ def get_context(context):
reference_doctype=doc.doctype,
reference_name=doc.name)
- def send_whatsapp_msg(self, doc, context):
- send_whatsapp_message(
- sender=self.twilio_number,
- receiver_list=self.get_receiver_list(doc, context),
- message=frappe.render_template(self.message, context),
- )
-
def send_sms(self, doc, context):
send_sms(
receiver_list=self.get_receiver_list(doc, context),
@@ -302,7 +285,7 @@ def get_context(context):
# For sending messages to the owner's mobile phone number
if recipient.receiver_by_document_field == 'owner':
- receiver_list.append(get_user_info(doc.get('owner'), 'mobile_no'))
+ receiver_list += get_user_info([dict(user_name=doc.get('owner'))], 'mobile_no')
# For sending messages to the number specified in the receiver field
elif recipient.receiver_by_document_field:
receiver_list.append(doc.get(recipient.receiver_by_document_field))
diff --git a/frappe/integrations/desk_page/integrations/integrations.json b/frappe/integrations/desk_page/integrations/integrations.json
index cbf7c9c085..1acf4e6c4a 100644
--- a/frappe/integrations/desk_page/integrations/integrations.json
+++ b/frappe/integrations/desk_page/integrations/integrations.json
@@ -23,7 +23,7 @@
{
"hidden": 0,
"label": "Settings",
- "links": "[\n {\n \"description\": \"Webhooks calling API requests into web apps\",\n \"label\": \"Webhook\",\n \"name\": \"Webhook\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Slack Webhooks for internal integration\",\n \"label\": \"Slack Webhook URL\",\n \"name\": \"Slack Webhook URL\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Twilio Settings for WhatsApp integration\",\n \"label\": \"Twilio Settings\",\n \"name\": \"Twilio Settings\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"SMS Settings for sending sms\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n }\n]"
+ "links": "[\n {\n \"description\": \"Webhooks calling API requests into web apps\",\n \"label\": \"Webhook\",\n \"name\": \"Webhook\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"Slack Webhooks for internal integration\",\n \"label\": \"Slack Webhook URL\",\n \"name\": \"Slack Webhook URL\",\n \"type\": \"doctype\"\n },\n {\n \"description\": \"SMS Settings for sending sms\",\n \"label\": \"SMS Settings\",\n \"name\": \"SMS Settings\",\n \"type\": \"doctype\"\n }\n]"
}
],
"category": "Administration",
@@ -38,7 +38,7 @@
"idx": 0,
"is_standard": 1,
"label": "Integrations",
- "modified": "2020-08-20 23:04:04.528572",
+ "modified": "2020-10-28 10:25:54.792363",
"modified_by": "Administrator",
"module": "Integrations",
"name": "Integrations",
diff --git a/frappe/integrations/doctype/twilio_number_group/__init__.py b/frappe/integrations/doctype/twilio_number_group/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/frappe/integrations/doctype/twilio_number_group/twilio_number_group.json b/frappe/integrations/doctype/twilio_number_group/twilio_number_group.json
deleted file mode 100644
index 9d51e4b452..0000000000
--- a/frappe/integrations/doctype/twilio_number_group/twilio_number_group.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "actions": [],
- "autoname": "field:phone_number",
- "creation": "2020-02-24 13:58:58.036914",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
- "phone_number"
- ],
- "fields": [
- {
- "fieldname": "phone_number",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Phone Number",
- "options": "Phone",
- "show_days": 1,
- "show_seconds": 1,
- "unique": 1
- }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2020-08-20 22:48:57.166791",
- "modified_by": "Administrator",
- "module": "Integrations",
- "name": "Twilio Number Group",
- "owner": "Administrator",
- "permissions": [],
- "quick_entry": 1,
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/twilio_number_group/twilio_number_group.py b/frappe/integrations/doctype/twilio_number_group/twilio_number_group.py
deleted file mode 100644
index 04cb9ae146..0000000000
--- a/frappe/integrations/doctype/twilio_number_group/twilio_number_group.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-# import frappe
-from frappe.model.document import Document
-
-class TwilioNumberGroup(Document):
- pass
diff --git a/frappe/integrations/doctype/twilio_settings/__init__.py b/frappe/integrations/doctype/twilio_settings/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/frappe/integrations/doctype/twilio_settings/test_twilio_settings.py b/frappe/integrations/doctype/twilio_settings/test_twilio_settings.py
deleted file mode 100644
index bcb1368d68..0000000000
--- a/frappe/integrations/doctype/twilio_settings/test_twilio_settings.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies and Contributors
-# See license.txt
-from __future__ import unicode_literals
-
-# import frappe
-import unittest
-
-class TestTwilioSettings(unittest.TestCase):
- pass
diff --git a/frappe/integrations/doctype/twilio_settings/twilio_settings.js b/frappe/integrations/doctype/twilio_settings/twilio_settings.js
deleted file mode 100644
index 59ebcf2e7d..0000000000
--- a/frappe/integrations/doctype/twilio_settings/twilio_settings.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2020, Frappe Technologies and contributors
-// For license information, please see license.txt
-
-frappe.ui.form.on('Twilio Settings', {
- refresh: function(frm) {
- frm.dashboard.set_headline(__("For more information, {0}.", [`${__('Click here')}`]));
- }
-});
diff --git a/frappe/integrations/doctype/twilio_settings/twilio_settings.json b/frappe/integrations/doctype/twilio_settings/twilio_settings.json
deleted file mode 100644
index 9eb2c0c512..0000000000
--- a/frappe/integrations/doctype/twilio_settings/twilio_settings.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "actions": [],
- "creation": "2020-01-28 15:21:44.457163",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
- "enabled",
- "account_sid",
- "auth_token",
- "column_break_2",
- "twilio_number"
- ],
- "fields": [
- {
- "fieldname": "account_sid",
- "fieldtype": "Data",
- "label": "Account SID",
- "mandatory_depends_on": "eval: doc.enabled"
- },
- {
- "fieldname": "auth_token",
- "fieldtype": "Password",
- "label": "Auth Token",
- "mandatory_depends_on": "eval: doc.enabled"
- },
- {
- "fieldname": "column_break_2",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "twilio_number",
- "fieldtype": "Table",
- "label": "Twilio Number",
- "options": "Twilio Number Group"
- },
- {
- "default": "0",
- "fieldname": "enabled",
- "fieldtype": "Check",
- "label": "Enabled"
- }
- ],
- "index_web_pages_for_search": 1,
- "issingle": 1,
- "links": [],
- "modified": "2020-09-03 10:17:21.318743",
- "modified_by": "Administrator",
- "module": "Integrations",
- "name": "Twilio Settings",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "print": 1,
- "read": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- }
- ],
- "sort_field": "modified",
- "sort_order": "DESC",
- "track_changes": 1
-}
\ No newline at end of file
diff --git a/frappe/integrations/doctype/twilio_settings/twilio_settings.py b/frappe/integrations/doctype/twilio_settings/twilio_settings.py
deleted file mode 100644
index b8f991e829..0000000000
--- a/frappe/integrations/doctype/twilio_settings/twilio_settings.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (c) 2020, Frappe Technologies and contributors
-# For license information, please see license.txt
-
-from __future__ import unicode_literals
-import frappe
-from frappe.model.document import Document
-from frappe import _
-from frappe.utils.password import get_decrypted_password
-from twilio.rest import Client
-from six import string_types
-from json import loads
-
-class TwilioSettings(Document):
- def on_update(self):
- if self.enabled:
- self.validate_twilio_credentials()
-
- def validate_twilio_credentials(self):
- try:
- auth_token = get_decrypted_password("Twilio Settings", "Twilio Settings", 'auth_token')
- client = Client(self.account_sid, auth_token)
- client.api.accounts(self.account_sid).fetch()
- except Exception:
- frappe.throw(_("Invalid Account SID or Auth Token."))
-
-def send_whatsapp_message(sender, receiver_list, message):
- twilio_settings = frappe.get_doc("Twilio Settings")
- if not twilio_settings.enabled:
- frappe.throw(_("Please enable twilio settings before sending WhatsApp messages"))
-
- if isinstance(receiver_list, string_types):
- receiver_list = loads(receiver_list)
- if not isinstance(receiver_list, list):
- receiver_list = [receiver_list]
-
- auth_token = get_decrypted_password("Twilio Settings", "Twilio Settings", 'auth_token')
- client = Client(twilio_settings.account_sid, auth_token)
- args = {
- "from_": 'whatsapp:+{}'.format(sender),
- "body": message
- }
-
- failed_delivery = []
-
- for rec in receiver_list:
- args.update({"to": 'whatsapp:{}'.format(rec)})
- resp = _send_whatsapp(args, client)
- if not resp or resp.error_message:
- failed_delivery.append(rec)
-
- if failed_delivery:
- frappe.log_error(_("The message wasn't correctly delivered to: {}".format(", ".join(failed_delivery))), _('Delivery Failed'))
-
-
-def _send_whatsapp(message_dict, client):
- response = frappe._dict()
- try:
- response = client.messages.create(**message_dict)
- except Exception as e:
- frappe.log_error(e, title = _('Twilio WhatsApp Message Error'))
-
- return response
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 30f0220af7..de9e675a67 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -72,7 +72,5 @@ zxcvbn-python==4.4.24
pycryptodome==3.9.8
paytmchecksum==1.7.0
wrapt==1.10.11
-twilio==6.44.2
razorpay==1.2.0
-
rsa>=4.1 # not directly required, pinned by Snyk to avoid a vulnerability
\ No newline at end of file