Automatically increment Matrix v3 transaction IDs (#1128)

This commit is contained in:
Niccolò Maggioni 2024-05-22 03:35:58 +02:00 committed by GitHub
parent 286a4374c0
commit d3c13fd619
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 68 additions and 2 deletions

View File

@ -293,6 +293,9 @@ class NotifyMatrix(NotifyBase):
# This gets initialized after a login/registration
self.access_token = None
# This gets incremented for each request made against the v3 API
self.transaction_id = 0
# Place an image inline with the message body
self.include_image = include_image
@ -612,8 +615,10 @@ class NotifyMatrix(NotifyBase):
# Build our path
if self.version == MatrixVersion.V3:
path = '/rooms/{}/send/m.room.message/0'.format(
NotifyMatrix.quote(room_id))
path = '/rooms/{}/send/m.room.message/{}'.format(
NotifyMatrix.quote(room_id),
self.transaction_id,
)
else:
path = '/rooms/{}/send/m.room.message'.format(
@ -685,6 +690,12 @@ class NotifyMatrix(NotifyBase):
method = 'PUT' if self.version == MatrixVersion.V3 else 'POST'
postokay, response = self._fetch(
path, payload=payload, method=method)
# Increment the transaction ID to avoid future messages being
# recognized as retransmissions and ignored
if self.version == MatrixVersion.V3:
self.transaction_id += 1
if not postokay:
# Notify our user
self.logger.warning(

View File

@ -1137,3 +1137,58 @@ def test_plugin_matrix_attachments_api_v2(mock_post, mock_get):
# Force __del__() call
del obj
@mock.patch('requests.put')
@mock.patch('requests.get')
@mock.patch('requests.post')
def test_plugin_matrix_transaction_ids_api_v3(mock_post, mock_get, mock_put):
"""
NotifyMatrix() Transaction ID Checks (v3)
"""
# Prepare a good response
response = mock.Mock()
response.status_code = requests.codes.ok
response.content = MATRIX_GOOD_RESPONSE.encode('utf-8')
# Prepare a bad response
bad_response = mock.Mock()
bad_response.status_code = requests.codes.internal_server_error
# Prepare Mock return object
mock_post.return_value = response
mock_get.return_value = response
mock_put.return_value = response
notifications_to_send = [10, 1]
mock_post_offset = mock_put_counter = 0
for logins, notifications in enumerate(notifications_to_send, start=1):
# Instantiate our object
obj = Apprise.instantiate('matrix://user:pass@localhost/#general?v=3')
for txnId in range(notifications):
assert obj.notify(
body='body', title='title', notify_type=NotifyType.INFO
) is True
# Test our call count
assert mock_put.call_count == mock_put_counter + 1
# Login & join must happen only once per session
assert mock_post.call_count == mock_post_offset + (2 * logins)
assert mock_post.call_args_list[0][0][0] == \
'http://localhost/_matrix/client/v3/login'
assert mock_post.call_args_list[1][0][0] == \
'http://localhost/_matrix/client/v3/join/' + \
'%23general%3Alocalhost'
assert mock_put.call_args_list[txnId][0][0] == \
'http://localhost/_matrix/client/v3/rooms/' + \
f'%21abc123%3Alocalhost/send/m.room.message/{txnId}'
mock_put_counter = mock_put.call_count
# Force a object removal (thus a logout call)
del obj
mock_post_offset += 1