Skip to content

Commit

Permalink
Added Slack role
Browse files Browse the repository at this point in the history
  • Loading branch information
kingoftheconnors committed Jul 27, 2019
1 parent bd99dd0 commit 49766c5
Show file tree
Hide file tree
Showing 11 changed files with 436 additions and 0 deletions.
81 changes: 81 additions & 0 deletions docs/configuring-playbook-bridge-appservice-slack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Setting up Appservice Slack (optional)

The playbook can install and configure [matrix-appservice-slack](https://github.com/matrix-org/matrix-appservice-slack) for you.

See the project's [documentation](https://github.com/matrix-org/matrix-appservice-slack/blob/master/README.md) to learn what it does and why it might be useful to you.

Setup Instructions:

loosely based on [this](https://github.com/matrix-org/matrix-appservice-slack#Setup)

1. Create a new Matrix room to act as the administration control room. Note its internal room ID. This can
be done in Riot by making a message, opening the options for that message and choosing "view source". The
room ID will be displayed near the top.
2. Enable the bridge with the following configuration in your `vars.yml` file:

```yaml
matrix_appservice_slack_enabled: true
matrix_appservice_slack_control_room_id: "Your matrix admin room id"
```
3. If you've already installed Matrix services using the playbook before, you'll need to re-run it (`--tags=setup-all,start`). If not, proceed with [configuring other playbook services](configuring-playbook.md) and then with [Installing](installing.md). Get back to this guide once ready.
4. Invite the bridge bot user into the admin room:

```
/invite @slackbot:MY.DOMAIN
```

Note that the bot's domain is your server's domain **without the `matrix.` prefix.**

5. Create a new Slack App [here](https://api.slack.com/apps).

Name the app & select the team/workspace this app will belong to.

Click on bot users and add a new bot user. We will use this account to bridge the the rooms.

6. Click on Event Subscriptions and enable them and use the request url `https://matrix.DOMAIN/appservice-slack`. Then add the following events and save:

Bot User Events:

- team_domain_change
- message.channels
- message.groups (if you want to bridge private channels)
- team.info

7. Click on OAuth & Permissions and add the following scopes:

- chat:write:bot
- users:read

If you want to bridge files, also add the following:

- files:write:user

Note: any media uploaded to matrix is currently accessible by anyone who knows the url. In order to make Slack files visible to matrix users, this bridge will make Slack files visible to anyone with the url (including files in private channels). This is different then the current behavior in Slack, which only allows authenticated access to media posted in private channels. See MSC701 for details.

8. Click on Install App and Install App to Workspace. Note the access tokens shown. You will need the Bot User OAuth Access Token and if you want to bridge files, the OAuth Access Token whenever you link a room.

9. For each channel you would like to bridge, perform the following steps:

* Create a Matrix room in the usual manner for your client. Take a note of its Matrix room ID - it will look something like !aBcDeF:example.com.

* Invite the bot user to both the Slack and Matrix channels you would like to bridge using `/invite @slackbot` for slack and `/invite @slackbot:MY.DOMAIN` for matrix.

* Determine the "channel ID" that Slack uses to identify the channel, which can be found in the url https://XXX.slack.com/messages/<channel id>/.

* Issue a link command in the administration control room with these collected values as arguments:

with file bridging:
```
link --channel_id CHANNELID --room !the-matrix:room.id --slack_bot_token xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx --slack_user_token xoxp-xxxxxxxx-xxxxxxxxx-xxxxxxxx-xxxxxxxx
```
without file bridging:
```
link --channel_id CHANNELID --room !the-matrix:room.id --slack_bot_token xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx
```
These arguments can be shortened to single-letter forms:
```
link -I CHANNELID -R !the-matrix:room.id -t xoxb-xxxxxxxxxx-xxxxxxxxxxxxxxxxxxxx
```

Other configuration options are available via the `matrix_appservice_slack_configuration_extension_yaml` variable.
2 changes: 2 additions & 0 deletions docs/configuring-playbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,5 @@ When you're done with all the configuration you'd like to do, continue with [Ins
- [Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md) (optional)

- [Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md) (optional)

- [Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (optional)
28 changes: 28 additions & 0 deletions group_vars/matrix_servers
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,34 @@ matrix_appservice_discord_homeserver_token: "{{ matrix_synapse_macaroon_secret_k
######################################################################


######################################################################
#
# matrix-appservice-slack
#
######################################################################

# We don't enable bridges by default.
matrix_appservice_slack_enabled: false

matrix_appservice_slack_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'slack-appservice-token') | to_uuid }}"

matrix_appservice_slack_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'slack-homeserver-token') | to_uuid }}"

matrix_appservice_slack_id_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'slack-id-token') | to_uuid }}"

matrix_appservice_slack_systemd_required_services_list: |
{{
['docker.service']
+
(['matrix-synapse.service'] if matrix_synapse_enabled else [])
}}

######################################################################
#
# /matrix-bridge-appservice-slack
#
######################################################################

######################################################################
#
# matrix-bridge-appservice-irc
Expand Down
104 changes: 104 additions & 0 deletions roles/matrix-bridge-appservice-slack/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# matrix-appservice-slack is a Matrix <-> Slack bridge
# See: https://github.com/matrix-org/matrix-appservice-slack

matrix_appservice_slack_enabled: true

matrix_appservice_slack_docker_image: "cadair/matrix-appservice-slack:latest"

matrix_appservice_slack_base_path: "{{ matrix_base_data_path }}/appservice-slack"
matrix_appservice_slack_config_path: "{{ matrix_appservice_slack_base_path }}/config"
matrix_appservice_slack_data_path: "{{ matrix_appservice_slack_base_path }}/data"

matrix_appservice_slack_public_endpoint: /appservice-slack
matrix_appservice_slack_inbound_uri_prefix: "{{ matrix_homeserver_url }}{{ matrix_appservice_slack_public_endpoint }}"

# Once you make a control room in Matrix, you can get its ID by typing any message and checking its source
matrix_appservice_slack_control_room_id: ''
matrix_appservice_slack_bot_name: 'slackbot'
matrix_appservice_slack_user_prefix: 'slack_'

# Controls the SLACK_PORT and MATRIX_PORT of the installation
matrix_appservice_slack_matrix_port: 9004
matrix_appservice_slack_slack_port: 9003

# Takes an "<ip>:<port>" or "<port>" value (e.g. "127.0.0.1:9999"), or empty string to not expose.
matrix_appservice_slack_container_http_host_bind_port: ''

matrix_appservice_slack_homeserver_media_url: "matrix.{{ matrix_domain }}"
matrix_appservice_slack_homeserver_url: "http://matrix-synapse:8008"
matrix_appservice_slack_homeserver_domain: "{{ matrix_domain }}"
matrix_appservice_slack_appservice_url: 'http://matrix-appservice-slack'

# A list of extra arguments to pass to the container
matrix_appservice_slack_container_extra_arguments: []

# List of systemd services that matrix-appservice-slack.service depends on.
matrix_appservice_slack_systemd_required_services_list: ['docker.service']

# List of systemd services that matrix-appservice-slack.service wants
matrix_appservice_slack_systemd_wanted_services_list: []

matrix_appservice_slack_appservice_token: ''
matrix_appservice_slack_homeserver_token: ''
matrix_appservice_slack_id_token: ''

matrix_appservice_slack_configuration_yaml: |
slack_hook_port: {{ matrix_appservice_slack_slack_port }}
inbound_uri_prefix: "{{ matrix_appservice_slack_inbound_uri_prefix }}"
bot_username: "{{ matrix_appservice_slack_bot_name }}"
username_prefix: {{ matrix_appservice_slack_user_prefix }}
homeserver:
media_url: "{{ matrix_appservice_slack_homeserver_media_url }}"
url: "{{ matrix_appservice_slack_homeserver_url }}"
server_name: "{{ matrix_domain }}"
dbdir: "/data"
matrix_admin_room: "{{ matrix_appservice_slack_control_room_id }}"
matrix_appservice_slack_configuration_extension_yaml: |
#slack_hook_port: 9898
#inbound_uri_prefix: "https://my.server.here:9898/"
#bot_username: "slackbot"
#username_prefix: "slack_"
# Optional
#slack_master_token: "abc-123-def"
# Optional
#matrix_admin_room: "!aBcDeF:matrix.org"
#homeserver:
# url: http://localhost:8008
# server_name: my.server
# Optional
#tls:
# key_file: /path/to/tls.key
# crt_file: /path/to/tls.crt
#logging:
# console: "info"
# files:
# - "./debug.log": "info"
#- "./error.log": "error"
matrix_appservice_slack_configuration_extension: "{{ matrix_appservice_slack_configuration_extension_yaml|from_yaml if matrix_appservice_slack_configuration_extension_yaml|from_yaml else {} }}"

matrix_appservice_slack_configuration: "{{ matrix_appservice_slack_configuration_yaml|from_yaml|combine(matrix_appservice_slack_configuration_extension, recursive=True) }}"

matrix_appservice_slack_registration_yaml: |
id: "{{ matrix_appservice_slack_id_token }}"
as_token: "{{ matrix_appservice_slack_appservice_token }}"
hs_token: "{{ matrix_appservice_slack_homeserver_token }}"
namespaces:
users:
- exclusive: true
regex: '@{{ matrix_appservice_slack_user_prefix }}.*'
aliases:
- exclusive: false
regex: '#{{ matrix_appservice_slack_user_prefix }}.*'
rooms: []
url: "{{matrix_appservice_slack_appservice_url}}:{{ matrix_appservice_slack_matrix_port }}"
sender_localpart: slackbot
rate_limited: true
protocols: null
matrix_appservice_slack_registration: "{{ matrix_appservice_slack_registration_yaml|from_yaml }}"
79 changes: 79 additions & 0 deletions roles/matrix-bridge-appservice-slack/tasks/init.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist.
# We don't want to fail in such cases.
- name: Fail if matrix-synapse role already executed
fail:
msg: >-
The matrix-bridge-appservice-slack role needs to execute before the matrix-synapse role.
when: "matrix_synapse_role_executed|default(False)"

- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-appservice-slack'] }}"
when: matrix_appservice_slack_enabled|bool

# If the matrix-synapse role is not used, these variables may not exist.
- set_fact:
matrix_synapse_container_extra_arguments: >
{{ matrix_synapse_container_extra_arguments|default([]) }}
+
{{ ["--mount type=bind,src={{ matrix_appservice_slack_config_path }}/slack-registration.yaml,dst=/matrix-appservice-slack-registration.yaml,ro"] }}
matrix_synapse_app_service_config_files: >
{{ matrix_synapse_app_service_config_files|default([]) }}
+
{{ ["/matrix-appservice-slack-registration.yaml"] }}
when: matrix_appservice_slack_enabled|bool

# If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist.
# We don't want to fail in such cases.
- name: Fail if matrix-synapse role already executed
fail:
msg: >-
The matrix-bridge-appservice-slack role needs to execute before the matrix-synapse role.
when: "matrix_synapse_role_executed|default(False)"

- block:
- name: Fail if matrix-nginx-proxy role already executed
fail:
msg: >-
Trying to append Slack Appservice's reverse-proxying configuration to matrix-nginx-proxy,
but it's pointless since the matrix-nginx-proxy role had already executed.
To fix this, please change the order of roles in your plabook,
so that the matrix-nginx-proxy role would run after the matrix-bridge-appservice-slack role.
when: matrix_nginx_proxy_role_executed|default(False)|bool

- name: Generate Matrix Appservice Slack proxying configuration for matrix-nginx-proxy
set_fact:
matrix_appservice_slack_matrix_nginx_proxy_configuration: |
location {{ matrix_appservice_slack_public_endpoint }} {
{% if matrix_nginx_proxy_enabled|default(False) %}
{# Use the embedded DNS resolver in Docker containers to discover the service #}
resolver 127.0.0.11 valid=5s;
set $backend "{{ matrix_appservice_slack_appservice_url }}:{{ matrix_appservice_slack_slack_port }}";
proxy_pass $backend;
{% else %}
{# Generic configuration for use outside of our container setup #}
proxy_pass http://127.0.0.1:{{ matrix_appservice_slack_slack_port }};
{% endif %}
}
- name: Register Slack Appservice proxying configuration with matrix-nginx-proxy
set_fact:
matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks: |
{{
matrix_nginx_proxy_proxy_matrix_additional_server_configuration_blocks|default([])
+
[matrix_appservice_slack_matrix_nginx_proxy_configuration]
}}
tags:
- always
when: matrix_appservice_slack_enabled|bool

- name: Warn about reverse-proxying if matrix-nginx-proxy not used
debug:
msg: >-
NOTE: You've enabled the Matrix Slack bridge but are not using the matrix-nginx-proxy
reverse proxy.
Please make sure that you're proxying the `{{ something }}`
URL endpoint to the matrix-appservice-slack container.
You can expose the container's port using the `matrix_appservice_slack_container_http_host_bind_port` variable.
when: "matrix_appservice_slack_enabled|bool and matrix_nginx_proxy_enabled is not defined"
21 changes: 21 additions & 0 deletions roles/matrix-bridge-appservice-slack/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
- import_tasks: "{{ role_path }}/tasks/init.yml"
tags:
- always

- import_tasks: "{{ role_path }}/tasks/validate_config.yml"
when: "run_setup|bool and matrix_appservice_slack_enabled|bool"
tags:
- setup-all
- setup-appservice-slack

- import_tasks: "{{ role_path }}/tasks/setup_install.yml"
when: "run_setup|bool and matrix_appservice_slack_enabled|bool"
tags:
- setup-all
- setup-appservice-slack

- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
when: "run_setup|bool and not matrix_appservice_slack_enabled|bool"
tags:
- setup-all
- setup-appservice-slack
46 changes: 46 additions & 0 deletions roles/matrix-bridge-appservice-slack/tasks/setup_install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---

- name: Ensure Appservice Slack image is pulled
docker_image:
name: "{{ matrix_appservice_slack_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"

- name: Ensure AppService Slack paths exist
file:
path: "{{ item }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_username }}"
with_items:
- "{{ matrix_appservice_slack_base_path }}"
- "{{ matrix_appservice_slack_config_path }}"
- "{{ matrix_appservice_slack_data_path }}"

- name: Ensure Matrix Appservice Slack config installed
copy:
content: "{{ matrix_appservice_slack_configuration|to_nice_yaml }}"
dest: "{{ matrix_appservice_slack_config_path }}/config.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_username }}"

- name: Ensure appservice-slack registration.yaml installed
copy:
content: "{{ matrix_appservice_slack_registration|to_nice_yaml }}"
dest: "{{ matrix_appservice_slack_config_path }}/slack-registration.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_username }}"

- name: Ensure matrix-appservice-slack.service installed
template:
src: "{{ role_path }}/templates/systemd/matrix-appservice-slack.service.j2"
dest: "/etc/systemd/system/matrix-appservice-slack.service"
mode: 0644
register: matrix_appservice_slack_systemd_service_result

- name: Ensure systemd reloaded after matrix-appservice-slack.service installation
service:
daemon_reload: yes
when: "matrix_appservice_slack_systemd_service_result.changed"
Loading

0 comments on commit 49766c5

Please sign in to comment.