We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Webhook data does not have event id
Webhook data contains issue id only. It would be nice to have event id as well.

Discussed with @mattrobenolt on IRC. Documenting it here with this issue.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/sentry/plugins/sentry_webhooks/plugin.py`
Content:
```
1 from __future__ import absolute_import
2 
3 import logging
4 import six
5 import sentry
6 
7 from django import forms
8 from django.conf import settings
9 from django.utils.translation import ugettext_lazy as _
10 
11 from sentry.exceptions import PluginError
12 from sentry.plugins.bases import notify
13 from sentry.http import is_valid_url, safe_urlopen
14 from sentry.utils.safe import safe_execute
15 
16 
17 def validate_urls(value, **kwargs):
18     output = []
19     for url in value.split('\n'):
20         url = url.strip()
21         if not url:
22             continue
23         if not url.startswith(('http://', 'https://')):
24             raise PluginError('Not a valid URL.')
25         if not is_valid_url(url):
26             raise PluginError('Not a valid URL.')
27         output.append(url)
28     return '\n'.join(output)
29 
30 
31 class WebHooksOptionsForm(notify.NotificationConfigurationForm):
32     urls = forms.CharField(
33         label=_('Callback URLs'),
34         widget=forms.Textarea(attrs={
35             'class': 'span6', 'placeholder': 'https://sentry.io/callback/url'}),
36         help_text=_('Enter callback URLs to POST new events to (one per line).'))
37 
38     def clean_url(self):
39         value = self.cleaned_data.get('url')
40         return validate_urls(value)
41 
42 
43 class WebHooksPlugin(notify.NotificationPlugin):
44     author = 'Sentry Team'
45     author_url = 'https://github.com/getsentry/sentry'
46     version = sentry.VERSION
47     description = "Integrates web hooks."
48     resource_links = [
49         ('Bug Tracker', 'https://github.com/getsentry/sentry/issues'),
50         ('Source', 'https://github.com/getsentry/sentry'),
51     ]
52 
53     slug = 'webhooks'
54     title = 'WebHooks'
55     conf_title = title
56     conf_key = 'webhooks'
57     # TODO(dcramer): remove when this is migrated to React
58     project_conf_form = WebHooksOptionsForm
59     timeout = getattr(settings, 'SENTRY_WEBHOOK_TIMEOUT', 3)
60     logger = logging.getLogger('sentry.plugins.webhooks')
61     user_agent = 'sentry-webhooks/%s' % version
62 
63     def is_configured(self, project, **kwargs):
64         return bool(self.get_option('urls', project))
65 
66     def get_config(self, project, **kwargs):
67         return [{
68             'name': 'urls',
69             'label': 'Callback URLs',
70             'type': 'textarea',
71             'help': 'Enter callback URLs to POST new events to (one per line).',
72             'placeholder': 'https://sentry.io/callback/url',
73             'validators': [validate_urls],
74             'required': False
75         }]
76 
77     def get_group_data(self, group, event):
78         data = {
79             'id': six.text_type(group.id),
80             'project': group.project.slug,
81             'project_name': group.project.name,
82             'logger': event.get_tag('logger'),
83             'level': event.get_tag('level'),
84             'culprit': group.culprit,
85             'message': event.get_legacy_message(),
86             'url': group.get_absolute_url(),
87         }
88         data['event'] = dict(event.data or {})
89         data['event']['tags'] = event.get_tags()
90         return data
91 
92     def get_webhook_urls(self, project):
93         urls = self.get_option('urls', project)
94         if not urls:
95             return ()
96         return filter(bool, urls.strip().splitlines())
97 
98     def send_webhook(self, url, payload):
99         return safe_urlopen(
100             url=url,
101             json=payload,
102             timeout=self.timeout,
103             verify_ssl=False,
104         )
105 
106     def notify_users(self, group, event, fail_silently=False):
107         payload = self.get_group_data(group, event)
108         for url in self.get_webhook_urls(group.project):
109             safe_execute(self.send_webhook, url, payload, _with_transaction=False)
110
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/sentry/plugins/sentry_webhooks/plugin.py b/src/sentry/plugins/sentry_webhooks/plugin.py
--- a/src/sentry/plugins/sentry_webhooks/plugin.py
+++ b/src/sentry/plugins/sentry_webhooks/plugin.py
@@ -87,6 +87,8 @@
         }
         data['event'] = dict(event.data or {})
         data['event']['tags'] = event.get_tags()
+        data['event']['event_id'] = event.event_id
+        data['event']['id'] = event.id
         return data
 
     def get_webhook_urls(self, project):

{"golden_diff": "diff --git a/src/sentry/plugins/sentry_webhooks/plugin.py b/src/sentry/plugins/sentry_webhooks/plugin.py\n--- a/src/sentry/plugins/sentry_webhooks/plugin.py\n+++ b/src/sentry/plugins/sentry_webhooks/plugin.py\n@@ -87,6 +87,8 @@\n         }\n         data['event'] = dict(event.data or {})\n         data['event']['tags'] = event.get_tags()\n+        data['event']['event_id'] = event.event_id\n+        data['event']['id'] = event.id\n         return data\n \n     def get_webhook_urls(self, project):\n", "issue": "Webhook data does not have event id\nWebhook data contains issue id only. It would be nice to have event id as well.\r\n\r\nDiscussed with @mattrobenolt on IRC. Documenting it here with this issue.\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport logging\nimport six\nimport sentry\n\nfrom django import forms\nfrom django.conf import settings\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom sentry.exceptions import PluginError\nfrom sentry.plugins.bases import notify\nfrom sentry.http import is_valid_url, safe_urlopen\nfrom sentry.utils.safe import safe_execute\n\n\ndef validate_urls(value, **kwargs):\n    output = []\n    for url in value.split('\\n'):\n        url = url.strip()\n        if not url:\n            continue\n        if not url.startswith(('http://', 'https://')):\n            raise PluginError('Not a valid URL.')\n        if not is_valid_url(url):\n            raise PluginError('Not a valid URL.')\n        output.append(url)\n    return '\\n'.join(output)\n\n\nclass WebHooksOptionsForm(notify.NotificationConfigurationForm):\n    urls = forms.CharField(\n        label=_('Callback URLs'),\n        widget=forms.Textarea(attrs={\n            'class': 'span6', 'placeholder': 'https://sentry.io/callback/url'}),\n        help_text=_('Enter callback URLs to POST new events to (one per line).'))\n\n    def clean_url(self):\n        value = self.cleaned_data.get('url')\n        return validate_urls(value)\n\n\nclass WebHooksPlugin(notify.NotificationPlugin):\n    author = 'Sentry Team'\n    author_url = 'https://github.com/getsentry/sentry'\n    version = sentry.VERSION\n    description = \"Integrates web hooks.\"\n    resource_links = [\n        ('Bug Tracker', 'https://github.com/getsentry/sentry/issues'),\n        ('Source', 'https://github.com/getsentry/sentry'),\n    ]\n\n    slug = 'webhooks'\n    title = 'WebHooks'\n    conf_title = title\n    conf_key = 'webhooks'\n    # TODO(dcramer): remove when this is migrated to React\n    project_conf_form = WebHooksOptionsForm\n    timeout = getattr(settings, 'SENTRY_WEBHOOK_TIMEOUT', 3)\n    logger = logging.getLogger('sentry.plugins.webhooks')\n    user_agent = 'sentry-webhooks/%s' % version\n\n    def is_configured(self, project, **kwargs):\n        return bool(self.get_option('urls', project))\n\n    def get_config(self, project, **kwargs):\n        return [{\n            'name': 'urls',\n            'label': 'Callback URLs',\n            'type': 'textarea',\n            'help': 'Enter callback URLs to POST new events to (one per line).',\n            'placeholder': 'https://sentry.io/callback/url',\n            'validators': [validate_urls],\n            'required': False\n        }]\n\n    def get_group_data(self, group, event):\n        data = {\n            'id': six.text_type(group.id),\n            'project': group.project.slug,\n            'project_name': group.project.name,\n            'logger': event.get_tag('logger'),\n            'level': event.get_tag('level'),\n            'culprit': group.culprit,\n            'message': event.get_legacy_message(),\n            'url': group.get_absolute_url(),\n        }\n        data['event'] = dict(event.data or {})\n        data['event']['tags'] = event.get_tags()\n        return data\n\n    def get_webhook_urls(self, project):\n        urls = self.get_option('urls', project)\n        if not urls:\n            return ()\n        return filter(bool, urls.strip().splitlines())\n\n    def send_webhook(self, url, payload):\n        return safe_urlopen(\n            url=url,\n            json=payload,\n            timeout=self.timeout,\n            verify_ssl=False,\n        )\n\n    def notify_users(self, group, event, fail_silently=False):\n        payload = self.get_group_data(group, event)\n        for url in self.get_webhook_urls(group.project):\n            safe_execute(self.send_webhook, url, payload, _with_transaction=False)\n", "path": "src/sentry/plugins/sentry_webhooks/plugin.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport logging\nimport six\nimport sentry\n\nfrom django import forms\nfrom django.conf import settings\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom sentry.exceptions import PluginError\nfrom sentry.plugins.bases import notify\nfrom sentry.http import is_valid_url, safe_urlopen\nfrom sentry.utils.safe import safe_execute\n\n\ndef validate_urls(value, **kwargs):\n    output = []\n    for url in value.split('\\n'):\n        url = url.strip()\n        if not url:\n            continue\n        if not url.startswith(('http://', 'https://')):\n            raise PluginError('Not a valid URL.')\n        if not is_valid_url(url):\n            raise PluginError('Not a valid URL.')\n        output.append(url)\n    return '\\n'.join(output)\n\n\nclass WebHooksOptionsForm(notify.NotificationConfigurationForm):\n    urls = forms.CharField(\n        label=_('Callback URLs'),\n        widget=forms.Textarea(attrs={\n            'class': 'span6', 'placeholder': 'https://sentry.io/callback/url'}),\n        help_text=_('Enter callback URLs to POST new events to (one per line).'))\n\n    def clean_url(self):\n        value = self.cleaned_data.get('url')\n        return validate_urls(value)\n\n\nclass WebHooksPlugin(notify.NotificationPlugin):\n    author = 'Sentry Team'\n    author_url = 'https://github.com/getsentry/sentry'\n    version = sentry.VERSION\n    description = \"Integrates web hooks.\"\n    resource_links = [\n        ('Bug Tracker', 'https://github.com/getsentry/sentry/issues'),\n        ('Source', 'https://github.com/getsentry/sentry'),\n    ]\n\n    slug = 'webhooks'\n    title = 'WebHooks'\n    conf_title = title\n    conf_key = 'webhooks'\n    # TODO(dcramer): remove when this is migrated to React\n    project_conf_form = WebHooksOptionsForm\n    timeout = getattr(settings, 'SENTRY_WEBHOOK_TIMEOUT', 3)\n    logger = logging.getLogger('sentry.plugins.webhooks')\n    user_agent = 'sentry-webhooks/%s' % version\n\n    def is_configured(self, project, **kwargs):\n        return bool(self.get_option('urls', project))\n\n    def get_config(self, project, **kwargs):\n        return [{\n            'name': 'urls',\n            'label': 'Callback URLs',\n            'type': 'textarea',\n            'help': 'Enter callback URLs to POST new events to (one per line).',\n            'placeholder': 'https://sentry.io/callback/url',\n            'validators': [validate_urls],\n            'required': False\n        }]\n\n    def get_group_data(self, group, event):\n        data = {\n            'id': six.text_type(group.id),\n            'project': group.project.slug,\n            'project_name': group.project.name,\n            'logger': event.get_tag('logger'),\n            'level': event.get_tag('level'),\n            'culprit': group.culprit,\n            'message': event.get_legacy_message(),\n            'url': group.get_absolute_url(),\n        }\n        data['event'] = dict(event.data or {})\n        data['event']['tags'] = event.get_tags()\n        data['event']['event_id'] = event.event_id\n        data['event']['id'] = event.id\n        return data\n\n    def get_webhook_urls(self, project):\n        urls = self.get_option('urls', project)\n        if not urls:\n            return ()\n        return filter(bool, urls.strip().splitlines())\n\n    def send_webhook(self, url, payload):\n        return safe_urlopen(\n            url=url,\n            json=payload,\n            timeout=self.timeout,\n            verify_ssl=False,\n        )\n\n    def notify_users(self, group, event, fail_silently=False):\n        payload = self.get_group_data(group, event)\n        for url in self.get_webhook_urls(group.project):\n            safe_execute(self.send_webhook, url, payload, _with_transaction=False)\n", "path": "src/sentry/plugins/sentry_webhooks/plugin.py"}]}