1
- from typing import Set , List , TYPE_CHECKING
1
+ from typing import Set , List , Optional , TYPE_CHECKING
2
2
from uuid import UUID
3
3
import asyncio
4
4
import json
21
21
spaces = re .compile (" +" )
22
22
space = " "
23
23
24
-
25
24
class LinearWebhook :
26
25
bot : 'LinearBot'
27
26
secret : str
@@ -30,6 +29,8 @@ class LinearWebhook:
30
29
handled_webhooks : Set [UUID ]
31
30
ignore_uuids : Set [UUID ]
32
31
messages : TemplateManager
32
+ release_label_ids : Set [UUID ]
33
+
33
34
# templates: TemplateManager
34
35
35
36
def __init__ (self , bot : 'LinearBot' ) -> None :
@@ -39,6 +40,7 @@ def __init__(self, bot: 'LinearBot') -> None:
39
40
self .joined_rooms = set ()
40
41
self .handled_webhooks = set ()
41
42
self .ignore_uuids = set ()
43
+ self .release_label_ids = set ()
42
44
43
45
self .messages = TemplateManager (self .bot .loader , "templates/messages" )
44
46
# self.templates = TemplateManager(self.bot.loader, "templates/mixins")
@@ -51,7 +53,8 @@ async def stop(self) -> None:
51
53
if self .task_list :
52
54
await asyncio .wait (self .task_list , timeout = 1 )
53
55
54
- async def handle_webhook (self , room_id : RoomID , evt : LinearEvent ) -> None :
56
+ async def handle_webhook (self , room_id : Optional [RoomID ], release_room_id : Optional [RoomID ],
57
+ evt : LinearEvent ) -> None :
55
58
if evt .data .id in self .ignore_uuids :
56
59
self .log .debug (f"Dropping webhook for { evt .type } { evt .data .id } "
57
60
" that was marked to be ignored" )
@@ -98,12 +101,22 @@ def abort() -> None:
98
101
content .external_url = evt .url
99
102
query = {"ts" : int (evt .created_at .timestamp () * 1000 )}
100
103
101
- await self .bot .client .send_message (room_id , content , query_params = query )
104
+ if room_id is not None :
105
+ await self .bot .client .send_message (room_id , content , query_params = query )
106
+
107
+ # Only post in the release room if the issue has one of the release labels
108
+ if release_room_id is not None :
109
+ issue_id = getattr (evt .data , 'issue_id' , None )
110
+ if issue_id is not None :
111
+ label_ids = await self .bot .linear_bot .get_issue_labels (issue_id )
112
+ if set (label_ids ) & self .release_label_ids :
113
+ await self .bot .client .send_message (release_room_id , content , query_params = query )
102
114
103
- async def _try_handle_webhook (self , delivery_id : UUID , room_id : RoomID , evt : LinearEvent
115
+ async def _try_handle_webhook (self , delivery_id : UUID , room_id : Optional [RoomID ], release_room_id : Optional [RoomID ],
116
+ evt : LinearEvent
104
117
) -> None :
105
118
try :
106
- await self .handle_webhook (room_id , evt )
119
+ await self .handle_webhook (room_id , release_room_id , evt )
107
120
except Exception :
108
121
self .log .exception (f"Error handling webhook { delivery_id } " )
109
122
finally :
@@ -123,12 +136,23 @@ async def webhook(self, request: Request) -> Response:
123
136
try :
124
137
room_id = RoomID (request .url .query ["room_id" ])
125
138
except KeyError :
126
- return Response (status = 400 , text = "400: Bad Request\n "
127
- "Missing `room_id` query parameter\n " )
128
- if room_id not in self .joined_rooms :
129
- return Response (text = "403: Forbidden\n The bot is not in the room. "
139
+ room_id = None
140
+
141
+ if room_id is not None and room_id not in self .joined_rooms :
142
+ return Response (text = f"403: Forbidden\n The bot is not in the room { room_id } . "
143
+ f"Please invite { self .bot .client .mxid } to the room.\n " ,
144
+ status = 403 )
145
+
146
+ try :
147
+ release_room_id = RoomID (request .url .query ["release_room_id" ])
148
+ except KeyError :
149
+ release_room_id = None
150
+
151
+ if release_room_id is not None and release_room_id not in self .joined_rooms :
152
+ return Response (text = f"403: Forbidden\n The bot is not in the room { release_room_id } . "
130
153
f"Please invite { self .bot .client .mxid } to the room.\n " ,
131
154
status = 403 )
155
+
132
156
try :
133
157
delivery_id = UUID (request .headers ["Linear-Delivery" ])
134
158
except (KeyError , ValueError ):
@@ -161,7 +185,7 @@ async def webhook(self, request: Request) -> Response:
161
185
self .log .debug ("Recognized data in %s: %s" , delivery_id , evt )
162
186
except AttributeError :
163
187
self .log .trace ("Received event %s: %s" , delivery_id , evt )
164
- task = asyncio .create_task (self ._try_handle_webhook (delivery_id , room_id , evt ))
188
+ task = asyncio .create_task (self ._try_handle_webhook (delivery_id , room_id , release_room_id , evt ))
165
189
self .task_list .append (task )
166
190
return Response (status = 202 , text = "202: Accepted\n Webhook processing started.\n " )
167
191
0 commit comments