Repository: zulip/zulip

Issue:
Jotform integration
It might be valuable to implement an integration with [Jotform](https://www.jotform.com/), as we have received feedback from users who would be willing to switch to Zulip if we had that feature available.

It seems like a standard outgoing webhook, with https://www.jotform.com/help/245-how-to-setup-a-webhook-with-jotform providing some introductory information on setting this up.


Discussion:
Hello @zulip/server-integrations members, this issue was labeled with the "area: integrations" label, so you may want to check it out!

<!-- areaLabelAddition -->
Tagged it as a good first issue; this seems like a great project for someone new to working on Zulip.  https://zulip.com/api/incoming-webhooks-overview documents how to write one.
@timabbott Can I please work on this issue parallely with my PR #16524 under review ?
Sure!  

Resolving patch:
diff --git a/zerver/lib/integrations.py b/zerver/lib/integrations.py
--- a/zerver/lib/integrations.py
+++ b/zerver/lib/integrations.py
@@ -397,6 +397,7 @@ def __init__(self, name: str, *args: Any, **kwargs: Any) -> None:
     WebhookIntegration("insping", ["monitoring"], display_name="Insping"),
     WebhookIntegration("intercom", ["customer-support"], display_name="Intercom"),
     WebhookIntegration("jira", ["project-management"], display_name="JIRA"),
+    WebhookIntegration("jotform", ["misc"], display_name="Jotform"),
     WebhookIntegration("librato", ["monitoring"]),
     WebhookIntegration("mention", ["marketing"], display_name="Mention"),
     WebhookIntegration("netlify", ["continuous-integration", "deployment"], display_name="Netlify"),
@@ -689,6 +690,7 @@ def __init__(self, name: str, *args: Any, **kwargs: Any) -> None:
     "insping": [ScreenshotConfig("website_state_available.json")],
     "intercom": [ScreenshotConfig("conversation_admin_replied.json")],
     "jira": [ScreenshotConfig("created_v1.json")],
+    "jotform": [ScreenshotConfig("response.json")],
     "librato": [ScreenshotConfig("three_conditions_alert.json", payload_as_query_param=True)],
     "mention": [ScreenshotConfig("webfeeds.json")],
     "netlify": [ScreenshotConfig("deploy_building.json")],
diff --git a/zerver/webhooks/jotform/__init__.py b/zerver/webhooks/jotform/__init__.py
new file mode 100644
diff --git a/zerver/webhooks/jotform/view.py b/zerver/webhooks/jotform/view.py
new file mode 100644
--- /dev/null
+++ b/zerver/webhooks/jotform/view.py
@@ -0,0 +1,31 @@
+# Webhooks for external integrations.
+from typing import Any, Dict
+
+from django.http import HttpRequest, HttpResponse
+
+from zerver.decorator import webhook_view
+from zerver.lib.request import REQ, has_request_variables
+from zerver.lib.response import json_success
+from zerver.lib.webhooks.common import check_send_webhook_message
+from zerver.models import UserProfile
+
+
+@webhook_view("Jotform")
+@has_request_variables
+def api_jotform_webhook(
+    request: HttpRequest,
+    user_profile: UserProfile,
+    payload: Dict[str, Any] = REQ(argument_type="body"),
+) -> HttpResponse:
+    topic = payload["formTitle"]
+    submission_id = payload["submissionID"]
+    fields_dict = list(payload["pretty"].split(", "))
+
+    form_response = f"A new submission (ID {submission_id}) was received:\n"
+    for field in fields_dict:
+        form_response += f"* {field}\n"
+
+    message = form_response.strip()
+
+    check_send_webhook_message(request, user_profile, topic, message)
+    return json_success()


Test patch:
diff --git a/zerver/webhooks/jotform/tests.py b/zerver/webhooks/jotform/tests.py
new file mode 100644
--- /dev/null
+++ b/zerver/webhooks/jotform/tests.py
@@ -0,0 +1,23 @@
+from zerver.lib.test_classes import WebhookTestCase
+
+
+class JotFormHookTests(WebhookTestCase):
+    STREAM_NAME = "test"
+    URL_TEMPLATE = "/api/v1/external/jotform?stream={stream}&api_key={api_key}"
+    FIXTURE_DIR_NAME = "jotform"
+
+    def test_response(self) -> None:
+        expected_title = "Form"
+        expected_message = """
+A new submission (ID 4791133489169827307) was received:
+* Name:Gaurav Pandey
+* Address:Lampgarden-street wolfsquare Bengaluru Karnataka 165578
+* Signature:uploads/gauravguitarrocks/202944822449057/4791133489169827307/4791133489169827307_signature_4.png
+""".strip()
+
+        self.check_webhook(
+            "response",
+            expected_title,
+            expected_message,
+            content_type="application/x-www-form-urlencoded",
+        )