-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmatrix_room.py
171 lines (143 loc) · 4.74 KB
/
matrix_room.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#!/usr/bin/python
# coding: utf-8
# (c) 2018, Jan Christian Grünhage <[email protected]>
# (c) 2020-2021, Famedly GmbH
# GNU Affero General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/agpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {
"metadata_version": "1.1",
"status": ["preview"],
"supported_by": "community",
}
DOCUMENTATION = """
---
author: "Jan Christian Grünhage (@jcgruenhage)"
module: matrix_room
short_description: Join/Create matrix room
description:
- This module takes a room alias and makes sure that the user identified by the access token is in such a room.
If that room does not exist, it is created, if it does exist but the user is not in it, it tries to join.
If the alias is taken and the user can't join the room, the module will fail.
Remote aliases are not supported for creating, but work for joining.
options:
hs_url:
description:
- URL of the homeserver, where the CS-API is reachable
required: true
type: str
user_id:
description:
- The user id of the user
required: false
type: str
password:
description:
- The password to log in with
required: false
type: str
token:
description:
- Authentication token for the API call
required: false
type: str
alias:
description:
- Alias of the room to join/create
required: true
type: str
requirements:
- matrix-nio (Python library)
"""
EXAMPLES = """
- name: Create notification room
matrix_room:
alias: "#ansible-notifications:matrix.org"
hs_url: "https://matrix.org"
token: "{{ matrix_auth_token }}"
"""
RETURN = """
room_id:
description: ID of the room
type: str
returned: success
sample: "!asdfbuiarbk213e479asf:server.tld"
"""
import asyncio
import re
import traceback
from ansible.module_utils.basic import missing_required_lib
LIB_IMP_ERR = None
try:
from ansible_collections.famedly.matrix.plugins.module_utils.matrix import (
AnsibleNioModule,
)
from nio import (
RoomCreateResponse,
RoomCreateError,
JoinedRoomsResponse,
JoinedRoomsError,
JoinResponse,
JoinError,
RoomResolveAliasResponse,
RoomResolveAliasError,
)
HAS_LIB = True
except ImportError:
LIB_IMP_ERR = traceback.format_exc()
HAS_LIB = False
async def run_module():
module_args = dict(alias=dict(type="str", required=True))
result = dict(changed=False, message="")
module = AnsibleNioModule(module_args)
if not HAS_LIB:
await module.fail_json(msg=missing_required_lib("matrix-nio"))
await module.matrix_login()
client = module.client
if module.check_mode:
result["changed"] = True
result["room_id"] = "!fakeRoomId:localhost"
await module.exit_json(**result)
# Try to look up room_id
room_id_resp = await client.room_resolve_alias(module.params["alias"])
failed = False
result = {}
if isinstance(room_id_resp, RoomResolveAliasResponse):
# Check if already in room
rooms_resp = await client.joined_rooms()
if isinstance(rooms_resp, JoinedRoomsError):
failed = True
result = {"msg": "Couldn't get joined rooms."}
elif room_id_resp.room_id in rooms_resp.rooms:
result = {"room_id": room_id_resp.room_id, "changed": False}
else:
# Try to join room
join_resp = await client.join(module.params["alias"])
# If successful, return, changed=true
if isinstance(join_resp, JoinResponse):
result = {"room_id": join_resp.room_id, "changed": True}
else:
failed = True
result = {"msg": f"Room exists, but couldn't join: {join_resp}"}
else:
# Get local part of alias
local_part_regex = re.search("#([^:]*):(.*)", module.params["alias"])
local_part = local_part_regex.groups()[0]
# Try to create room with alias
create_room_resp = await client.room_create(alias=local_part)
# If successful, exit with changed=true and room_id
if isinstance(create_room_resp, RoomCreateResponse):
result = {"room_id": create_room_resp.room_id, "changed": True}
else:
failed = True
result = {
"msg": f"Room does not exist but couldn't be created either: {create_room_resp}"
}
if failed:
await module.fail_json(**result)
else:
await module.exit_json(**result)
def main():
asyncio.run(run_module())
if __name__ == "__main__":
main()