mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +00:00 
			
		
		
		
	Update integration-guide according to integrations redesign.
With numerous typo and grammar fixed by tabbott.
This commit is contained in:
		@@ -25,7 +25,7 @@ paths will be familiar to Django developers.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
* `zerver/views/*.py` Most [Django views](https://docs.djangoproject.com/en/1.8/topics/http/views/).
 | 
					* `zerver/views/*.py` Most [Django views](https://docs.djangoproject.com/en/1.8/topics/http/views/).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `zerver/views/webhooks/` Webhook views for [Zulip integrations](integration-guide.html).
 | 
					* `zerver/webhooks/` Webhook views and tests for [Zulip webhook integrations](integration-guide.html).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `zerver/tornado/views.py` Tornado views.
 | 
					* `zerver/tornado/views.py` Tornado views.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,10 +32,10 @@ products, ordered here by which types we prefer to write:
 | 
				
			|||||||
1. **[Webhook integrations](#webhook-integrations)** (examples:
 | 
					1. **[Webhook integrations](#webhook-integrations)** (examples:
 | 
				
			||||||
   Freshdesk, GitHub), where the third-party service supports posting
 | 
					   Freshdesk, GitHub), where the third-party service supports posting
 | 
				
			||||||
   content to a particular URI on our site with data about the event.
 | 
					   content to a particular URI on our site with data about the event.
 | 
				
			||||||
   For these, you usually just need to add a new view file in the
 | 
					   For these, you usually just need to create a new python package in
 | 
				
			||||||
   `zerver/views/webhooks/` directory (plus test/document/etc.).  An
 | 
					   the `zerver/webhooks/` directory.  You can easily find recent
 | 
				
			||||||
   example commit implementing a new webhook is:
 | 
					   commits adding new integrations to crib from via `git log
 | 
				
			||||||
   https://github.com/zulip/zulip/pull/324.
 | 
					   zerver/webhooks/`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2. **[Python script integrations](#python-script-and-plugin-integrations)**
 | 
					2. **[Python script integrations](#python-script-and-plugin-integrations)**
 | 
				
			||||||
   (examples: SVN, Git), where we can get the service to call our integration
 | 
					   (examples: SVN, Git), where we can get the service to call our integration
 | 
				
			||||||
@@ -100,26 +100,26 @@ Here's how we recommend doing it:
 | 
				
			|||||||
  can use these captured payloads to create a set of test fixtures for
 | 
					  can use these captured payloads to create a set of test fixtures for
 | 
				
			||||||
  your integration under `zerver/fixtures`.
 | 
					  your integration under `zerver/fixtures`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Then write a draft webhook handler under `zerver/views/webhooks/`;
 | 
					* Then write a draft webhook handler under `zerver/webhooks/`;
 | 
				
			||||||
  there are a lot of examples in that directory.  We recommend
 | 
					  there are a lot of examples in that directory.  We recommend
 | 
				
			||||||
  templating off a short one (like `stash.py` or `zendesk.py`), since
 | 
					  templating off a short one (like `stash` or `zendesk`), since
 | 
				
			||||||
  the longer ones usually just have more complex parsing which can
 | 
					  the longer ones usually just have more complex parsing which can
 | 
				
			||||||
  obscure what's common to all webhook integrations.  In addition to
 | 
					  obscure what's common to all webhook integrations.  In addition to
 | 
				
			||||||
  writing the integration itself, you'll need to create `Integration`
 | 
					  writing the integration itself, you'll need to create `Integration`
 | 
				
			||||||
  object and add it to `WEBHOOK_INTEGRATIONS` in
 | 
					  object and add it to `WEBHOOK_INTEGRATIONS` in
 | 
				
			||||||
  `zerver/lib/integrations.py'; search for `webhook` in that
 | 
					  `zerver/lib/integrations.py';` search for `webhook` in that
 | 
				
			||||||
  file to find the existing ones (and please add yours in the
 | 
					  file to find the existing ones (and please add yours in the
 | 
				
			||||||
  alphabetically correct place).
 | 
					  alphabetically correct place).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Then write a test for your fixture in a new file in the
 | 
					* Then write a test for your fixture in the `tests.py` file in the
 | 
				
			||||||
  `zerver/tests/webhooks/` directory, and you can iterate on the tests
 | 
					  `zerver/webhooks/mywebhook` directory.  You can now iterate on
 | 
				
			||||||
  and webhooks handler until they work, all without ever needing to
 | 
					  debugging the tests and webhooks handler until they work, all
 | 
				
			||||||
  post directly from the server you're integrating to your Zulip
 | 
					  without ever needing to post directly from the service you're
 | 
				
			||||||
  development machine.  To run just the tests from the test class you
 | 
					  integrating with to your Zulip development machine.  To run just the
 | 
				
			||||||
  wrote, you can use e.g.
 | 
					  tests from the test class you wrote, you can use e.g.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ```
 | 
					  ```
 | 
				
			||||||
  test-backend zerver.tests.webhooks.test_pagerduty.PagerDutyHookTests
 | 
					  test-backend zerver/webhooks/pagerduty/
 | 
				
			||||||
  ```
 | 
					  ```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  See [this guide](testing.html) for more details on the Zulip test
 | 
					  See [this guide](testing.html) for more details on the Zulip test
 | 
				
			||||||
@@ -155,20 +155,22 @@ for a webhook named 'MyWebHook'.
 | 
				
			|||||||
* `zerver/fixtures/mywebhook/mywebhook_messagetype.json`: Sample json payload data
 | 
					* `zerver/fixtures/mywebhook/mywebhook_messagetype.json`: Sample json payload data
 | 
				
			||||||
  used by tests. Add one fixture file per type of message supported by your
 | 
					  used by tests. Add one fixture file per type of message supported by your
 | 
				
			||||||
  integration. See [Testing and writing tests](testing.html) for details.
 | 
					  integration. See [Testing and writing tests](testing.html) for details.
 | 
				
			||||||
* `zerver/views/webhooks/mywebhook.py`: Includes the main webhook integration
 | 
					* `zerver/webhooks/mywebhook/__init__.py`: Empty file that is obligatory
 | 
				
			||||||
 | 
					   part of every python package.  Remember to `git add` it.
 | 
				
			||||||
 | 
					* `zerver/webhooks/mywebhook/view.py`: Includes the main webhook integration
 | 
				
			||||||
  function including any needed helper functions.
 | 
					  function including any needed helper functions.
 | 
				
			||||||
* `zerver/tests/webhooks/mywebhook.py`: Add tests for your
 | 
					* `zerver/webhooks/mywebhook/tests.py`: Add tests for your
 | 
				
			||||||
  webbook. See [Testing and writing tests](testing.html) for details.
 | 
					  webbook. See [Testing and writing tests](testing.html) for details.
 | 
				
			||||||
 | 
					* `zerver/webhooks/mywebhook/doc.html`: Add end-user documentation. See
 | 
				
			||||||
 | 
					  [Documenting your integration](#documenting-your-integration) for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Files that need to be updated
 | 
					### Files that need to be updated
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* `templates/zerver/integrations.html`: Edit to add end-user documentation. See
 | 
					 | 
				
			||||||
  [Documenting your integration](#documenting-your-integration) for details.
 | 
					 | 
				
			||||||
* `zerver/lib/integrations.py`: Add your integration to
 | 
					* `zerver/lib/integrations.py`: Add your integration to
 | 
				
			||||||
`WEBHOOK_INTEGRATIONS` to register it.  This will automatically
 | 
					`WEBHOOK_INTEGRATIONS` to register it.  This will automatically
 | 
				
			||||||
register a url for the webhook of the form `api/v1/external/mywebhook`
 | 
					register a url for the webhook of the form `api/v1/external/mywebhook`
 | 
				
			||||||
and associate with the function called `api_mywebhook_webhook` in
 | 
					and associate with the function called `api_mywebhook_webhook` in
 | 
				
			||||||
`zerver/views/webhooks/mywebhook.py`.
 | 
					`zerver/webhooks/mywebhook/view.py`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Python script and plugin integrations
 | 
					## Python script and plugin integrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -203,17 +205,17 @@ ZulipMobile/0.5.4 (Android; 4.2; maguro)
 | 
				
			|||||||
## Documenting your integration
 | 
					## Documenting your integration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Every Zulip integration must be documented in
 | 
					Every Zulip integration must be documented in
 | 
				
			||||||
`templates/zerver/integrations.html`.  Usually, this involves a few
 | 
					`zerver/webhooks/mywebhook/doc.html`.  Usually, this involves a few
 | 
				
			||||||
steps:
 | 
					steps:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Add an `integration-instructions` class block in the
 | 
					* Add text explaining all of the steps required to setup the
 | 
				
			||||||
  alphabetically correct place, explaining all the steps required to
 | 
					  integration, including what URLs to use, etc.  If there are any
 | 
				
			||||||
  setup the integration, including what URLs to use, etc.  If there
 | 
					  screens in the product involved, take a few screenshots with the
 | 
				
			||||||
  are any screens in the product involved, take a few screenshots with
 | 
					  input fields filled out with sample values in order to make the
 | 
				
			||||||
  the input fields filled out with sample values in order to make the
 | 
					  instructions really easy to follow.  For the screenshots, use a bot
 | 
				
			||||||
  instructions really easy to follow.  For the screenshots, use
 | 
					  with a name like "GitHub Bot", an email address for the bot like
 | 
				
			||||||
  something like `github-bot@example.com` for the email addresses and
 | 
					  `github-bot@zulip.example.com`, and an obviously fake API key like
 | 
				
			||||||
  an obviously fake API key like `abcdef123456790`.
 | 
					  `abcdef123456790`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Make sure you've added your integration to
 | 
					* Make sure you've added your integration to
 | 
				
			||||||
  `zerver/lib/integrations.py`; this results in your integration
 | 
					  `zerver/lib/integrations.py`; this results in your integration
 | 
				
			||||||
@@ -286,16 +288,22 @@ only one fixture, `zerver/fixtures/helloworld/helloworld_hello.json`:
 | 
				
			|||||||
When writing your own webhook integration, you'll want to write a test function
 | 
					When writing your own webhook integration, you'll want to write a test function
 | 
				
			||||||
for each distinct message condition your webhook supports. You'll also need a
 | 
					for each distinct message condition your webhook supports. You'll also need a
 | 
				
			||||||
corresponding fixture for each of these tests. See [Step 3: Create
 | 
					corresponding fixture for each of these tests. See [Step 3: Create
 | 
				
			||||||
tests](#step-3-create-tests) or [Testing](testing.html) for further details.
 | 
					tests](#step-4-create-tests) or [Testing](testing.html) for further details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Step 1: Create main webhook code
 | 
					### Step 1: Initialize your webhook python package
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the `zerver/webhooks/` directory, create new subdirectory that will
 | 
				
			||||||
 | 
					contain all of corresponding code.  In our example it will be
 | 
				
			||||||
 | 
					`helloworld`. The new directory will be a python package, so you have
 | 
				
			||||||
 | 
					to create an empty `__init__.py` file in that directory via e.g. `touch
 | 
				
			||||||
 | 
					zerver/webhooks/helloworld/__init__.py`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Step 2: Create main webhook code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The majority of the code for your webhook integration will be in a single
 | 
					The majority of the code for your webhook integration will be in a single
 | 
				
			||||||
python file in `zerver/views/webhooks/`. The name of this file should be the
 | 
					python file, `zerver/webhooks/mywebhook/view.py`.
 | 
				
			||||||
name of your webhook, all lower-case, with file extension `.py`:
 | 
					 | 
				
			||||||
`mywebhook.py`.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The Hello World integration is in `zerver/views/webhooks/helloworld.py`:
 | 
					The Hello World integration is in `zerver/webhooks/helloworld/view.py`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
from __future__ import absolute_import
 | 
					from __future__ import absolute_import
 | 
				
			||||||
@@ -377,7 +385,7 @@ validate the message and then send it.
 | 
				
			|||||||
Finally, we return a 200 http status with a JSON format success message via
 | 
					Finally, we return a 200 http status with a JSON format success message via
 | 
				
			||||||
`json_success()`.
 | 
					`json_success()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Step 2: Create an api endpoint for the webhook
 | 
					### Step 3: Create an api endpoint for the webhook
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In order for a webhook to be externally available, it must be mapped to a url.
 | 
					In order for a webhook to be externally available, it must be mapped to a url.
 | 
				
			||||||
This is done in `zerver/lib/integrations.py`.
 | 
					This is done in `zerver/lib/integrations.py`.
 | 
				
			||||||
@@ -395,7 +403,7 @@ And you'll find the entry for Hello World:
 | 
				
			|||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This tells the Zulip api to call the `api_helloworld_webhook` function in
 | 
					This tells the Zulip api to call the `api_helloworld_webhook` function in
 | 
				
			||||||
`zerver/views/webhooks/helloworld.py` when it receives a request at
 | 
					`zerver/webhooks/helloworld/view.py` when it receives a request at
 | 
				
			||||||
`/api/v1/external/helloworld`.
 | 
					`/api/v1/external/helloworld`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This line also tells Zulip to generate an entry for Hello World on the Zulip
 | 
					This line also tells Zulip to generate an entry for Hello World on the Zulip
 | 
				
			||||||
@@ -441,10 +449,10 @@ Using either method will create a message in Zulip:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||

 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Step 3: Create tests
 | 
					### Step 4: Create tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Every webhook integration should have a corresponding test file in
 | 
					Every webhook integration should have a corresponding test file:
 | 
				
			||||||
`zerver/tests/webhooks/`.
 | 
					`zerver/webhooks/mywebhook/tests.py`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You should name the class `<WebhookName>HookTests` and have it inherit from
 | 
					You should name the class `<WebhookName>HookTests` and have it inherit from
 | 
				
			||||||
the base class `WebhookTestCase`. For our HelloWorld webhook, we name the test
 | 
					the base class `WebhookTestCase`. For our HelloWorld webhook, we name the test
 | 
				
			||||||
@@ -510,7 +518,7 @@ the Zulip development environment with this command:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
(zulip-venv)vagrant@vagrant-ubuntu-trusty-64:/srv/zulip$
 | 
					(zulip-venv)vagrant@vagrant-ubuntu-trusty-64:/srv/zulip$
 | 
				
			||||||
./tools/test-backend zerver.tests.webhooks.test_hello_world.HelloWorldHookTests
 | 
					./tools/test-backend zerver/webhooks/helloworld
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(Note: You must run the tests from the top level of your development directory.
 | 
					(Note: You must run the tests from the top level of your development directory.
 | 
				
			||||||
@@ -520,15 +528,15 @@ using Vagrant, use the directory where you have your development environment.)
 | 
				
			|||||||
You will see some script output and if all the tests have passed, you will see:
 | 
					You will see some script output and if all the tests have passed, you will see:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
Running zerver.tests.webhooks.test_hello_world.HelloWorldHookTests.test_goodbye_message
 | 
					Running zerver.webhooks.helloworld.tests.HelloWorldHookTests.test_goodbye_message
 | 
				
			||||||
Running zerver.tests.webhooks.test_hello_world.HelloWorldHookTests.test_hello_message
 | 
					Running zerver.webhooks.helloworld.tests.HelloWorldHookTests.test_hello_message
 | 
				
			||||||
DONE!
 | 
					DONE!
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Step 4: Create documentation
 | 
					### Step 5: Create documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Next, we add end-user documentation for our webhook integration to
 | 
					Next, we add end-user documentation for our webhook integration to
 | 
				
			||||||
`templates/zerver/integrations.html`. This is what generates the page
 | 
					`zever/webhooks/mywebhook/doc.html`. This is what generates the page
 | 
				
			||||||
displayed for your webhook from the Integrations page (in the gear menu.)
 | 
					displayed for your webhook from the Integrations page (in the gear menu.)
 | 
				
			||||||
You can see an example at [https://zulipchat.com/integrations](https://zulipchat.com/integrations).
 | 
					You can see an example at [https://zulipchat.com/integrations](https://zulipchat.com/integrations).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -541,40 +549,40 @@ installation and usage instructions.
 | 
				
			|||||||
Because there is an entry for the Hello World webhook in WEBHOOK_INTEGRATIONS
 | 
					Because there is an entry for the Hello World webhook in WEBHOOK_INTEGRATIONS
 | 
				
			||||||
in `zerver/lib/integrations.py`, this div will be generated automatically.
 | 
					in `zerver/lib/integrations.py`, this div will be generated automatically.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The second part is a `div` with the webhook's usage instructions:
 | 
					The second part is a content of a `div` with the webhook's usage instructions.
 | 
				
			||||||
 | 
					Because there is an entry for the Hello World webhook in WEBHOOK_INTEGRATIONS
 | 
				
			||||||
 | 
					in `zerver/lib/integrations.py`, this div will also be generated automatically.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
<div id="helloworld" class="integration-instructions">
 | 
					<p>Learn how Zulip integrations work with this simple Hello World example!</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>Learn how Zulip integrations work with this simple Hello World example!</p>
 | 
					<p>The Hello World webhook will use the <code>test<code> stream, which is
 | 
				
			||||||
 | 
					created by default in the Zulip development environment. If you are running
 | 
				
			||||||
 | 
					Zulip in production, you should make sure this stream exists.</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>The Hello World webhook will use the <code>test<code> stream, which is
 | 
					<p>Next, on your <a href="/#settings" target="_blank">Zulip
 | 
				
			||||||
    created by default in the Zulip development environment. If you are running
 | 
					settings page</a>, create a Hello World bot.  Construct the URL for
 | 
				
			||||||
    Zulip in production, you should make sure this stream exists.</p>
 | 
					the Hello World bot using the API key and stream name:
 | 
				
			||||||
 | 
					  <code>{{ external_api_uri }}/v1/external/helloworld?api_key=abcdefgh&stream=test</code>
 | 
				
			||||||
 | 
					</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <p>Next, on your <a href="/#settings" target="_blank">Zulip
 | 
					<p>To trigger a notication using this webhook, use `send_webhook_fixture_message` from the Zulip command line:</p>
 | 
				
			||||||
    settings page</a>, create a Hello World bot.  Construct the URL for
 | 
					<div class="codehilite">
 | 
				
			||||||
    the Hello World bot using the API key and stream name:
 | 
					  <pre>(zulip-venv)vagrant@vagrant-ubuntu-trusty-64:/srv/zulip$
 | 
				
			||||||
      <code>{{ external_api_uri }}/v1/external/helloworld?api_key=abcdefgh&stream=test</code>
 | 
					 | 
				
			||||||
    </p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>To trigger a notication using this webhook, use `send_webhook_fixture_message` from the Zulip command line:</p>
 | 
					 | 
				
			||||||
    <div class="codehilite">
 | 
					 | 
				
			||||||
      <pre>(zulip-venv)vagrant@vagrant-ubuntu-trusty-64:/srv/zulip$
 | 
					 | 
				
			||||||
./manage.py send_webhook_fixture_message \
 | 
					./manage.py send_webhook_fixture_message \
 | 
				
			||||||
> --fixture=zerver/fixtures/helloworld/helloworld_hello.json \
 | 
					> --fixture=zerver/fixtures/helloworld/helloworld_hello.json \
 | 
				
			||||||
> '--url=http://localhost:9991/api/v1/external/helloworld?api_key=<api_key>'</pre>
 | 
					> '--url=http://localhost:9991/api/v1/external/helloworld?api_key=<api_key>'</pre>
 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p>Or, use curl:</p>
 | 
					 | 
				
			||||||
    <div class="codehilite">
 | 
					 | 
				
			||||||
      <pre>curl -X POST -H "Content-Type: application/json" -d '{ "featured_title":"Marilyn Monroe", "featured_url":"https://en.wikipedia.org/wiki/Marilyn_Monroe" }' http://localhost:9991/api/v1/external/helloworld\?api_key\=<api_key></pre>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <p><b>Congratulations! You're done!</b><br /> Your messages may look like:</p>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <img class="screenshot" src="/static/images/integrations/helloworld/001.png" />
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p>Or, use curl:</p>
 | 
				
			||||||
 | 
					<div class="codehilite">
 | 
				
			||||||
 | 
					  <pre>curl -X POST -H "Content-Type: application/json" -d '{ "featured_title":"Marilyn Monroe", "featured_url":"https://en.wikipedia.org/wiki/Marilyn_Monroe" }' http://localhost:9991/api/v1/external/helloworld\?api_key\=<api_key></pre>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><b>Congratulations! You're done!</b><br /> Your messages may look like:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<img class="screenshot" src="/static/images/integrations/helloworld/001.png" />
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
These documentation blocks should fall alphabetically. For the
 | 
					These documentation blocks should fall alphabetically. For the
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user