Skip to content

Commit b2113e7

Browse files
github-actions[bot]github-actions
andauthored
Support mark as read by token API (#880)
line/line-openapi#115 ## Support for "Mark as Read" by Token API We have released a new **Mark as Read API** that allows developers to mark a user’s messages as read. Previously, this functionality was available only to partners, but it is now publicly available. When your server receives a user message via Webhook, the `MessageEvent` will include a new field: `markAsReadToken`. By calling the Mark as Read API with this token, all messages in the chat room **up to and including** that message will be marked as read. > **Note:** This feature assumes that your service uses the chat feature through Official Account Manager. > If chat is not enabled, messages from users are automatically marked as read, making this API unnecessary. For more details, please refer to the release note: https://developers.line.biz/en/news/2025/11/05/mark-as-read/ Co-authored-by: github-actions <[email protected]>
1 parent ecea075 commit b2113e7

14 files changed

+485
-18
lines changed

line-openapi

linebot/v3/messaging/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
from linebot.v3.messaging.models.location_message import LocationMessage
154154
from linebot.v3.messaging.models.lottery_acquisition_condition_request import LotteryAcquisitionConditionRequest
155155
from linebot.v3.messaging.models.lottery_acquisition_condition_response import LotteryAcquisitionConditionResponse
156+
from linebot.v3.messaging.models.mark_messages_as_read_by_token_request import MarkMessagesAsReadByTokenRequest
156157
from linebot.v3.messaging.models.mark_messages_as_read_request import MarkMessagesAsReadRequest
157158
from linebot.v3.messaging.models.members_ids_response import MembersIdsResponse
158159
from linebot.v3.messaging.models.membership import Membership

linebot/v3/messaging/api/async_messaging_api.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
from linebot.v3.messaging.models.group_summary_response import GroupSummaryResponse
4141
from linebot.v3.messaging.models.group_user_profile_response import GroupUserProfileResponse
4242
from linebot.v3.messaging.models.issue_link_token_response import IssueLinkTokenResponse
43+
from linebot.v3.messaging.models.mark_messages_as_read_by_token_request import MarkMessagesAsReadByTokenRequest
4344
from linebot.v3.messaging.models.mark_messages_as_read_request import MarkMessagesAsReadRequest
4445
from linebot.v3.messaging.models.members_ids_response import MembersIdsResponse
4546
from linebot.v3.messaging.models.membership_list_response import MembershipListResponse
@@ -7222,6 +7223,162 @@ def mark_messages_as_read_with_http_info(self, mark_messages_as_read_request : M
72227223
collection_formats=_collection_formats,
72237224
_request_auth=_params.get('_request_auth'))
72247225

7226+
@overload
7227+
async def mark_messages_as_read_by_token(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, **kwargs) -> None: # noqa: E501
7228+
...
7229+
7230+
@overload
7231+
def mark_messages_as_read_by_token(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, async_req: Optional[bool]=True, **kwargs) -> None: # noqa: E501
7232+
...
7233+
7234+
@validate_arguments
7235+
def mark_messages_as_read_by_token(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, async_req: Optional[bool]=None, **kwargs) -> Union[None, Awaitable[None]]: # noqa: E501
7236+
"""mark_messages_as_read_by_token # noqa: E501
7237+
7238+
Mark messages from users as read by token # noqa: E501
7239+
This method makes a synchronous HTTP request by default. To make an
7240+
asynchronous HTTP request, please pass async_req=True
7241+
7242+
>>> thread = api.mark_messages_as_read_by_token(mark_messages_as_read_by_token_request, async_req=True)
7243+
>>> result = thread.get()
7244+
7245+
:param mark_messages_as_read_by_token_request: (required)
7246+
:type mark_messages_as_read_by_token_request: MarkMessagesAsReadByTokenRequest
7247+
:param async_req: Whether to execute the request asynchronously.
7248+
:type async_req: bool, optional
7249+
:param _request_timeout: timeout setting for this request. If one
7250+
number provided, it will be total request
7251+
timeout. It can also be a pair (tuple) of
7252+
(connection, read) timeouts.
7253+
:return: Returns the result object.
7254+
If the method is called asynchronously,
7255+
returns the request thread.
7256+
:rtype: None
7257+
"""
7258+
kwargs['_return_http_data_only'] = True
7259+
if '_preload_content' in kwargs:
7260+
raise ValueError("Error! Please call the mark_messages_as_read_by_token_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
7261+
if async_req is not None:
7262+
kwargs['async_req'] = async_req
7263+
return self.mark_messages_as_read_by_token_with_http_info(mark_messages_as_read_by_token_request, **kwargs) # noqa: E501
7264+
7265+
@validate_arguments
7266+
def mark_messages_as_read_by_token_with_http_info(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, **kwargs) -> ApiResponse: # noqa: E501
7267+
"""mark_messages_as_read_by_token # noqa: E501
7268+
7269+
Mark messages from users as read by token # noqa: E501
7270+
This method makes a synchronous HTTP request by default. To make an
7271+
asynchronous HTTP request, please pass async_req=True
7272+
7273+
>>> thread = api.mark_messages_as_read_by_token_with_http_info(mark_messages_as_read_by_token_request, async_req=True)
7274+
>>> result = thread.get()
7275+
7276+
:param mark_messages_as_read_by_token_request: (required)
7277+
:type mark_messages_as_read_by_token_request: MarkMessagesAsReadByTokenRequest
7278+
:param async_req: Whether to execute the request asynchronously.
7279+
:type async_req: bool, optional
7280+
:param _preload_content: if False, the ApiResponse.data will
7281+
be set to none and raw_data will store the
7282+
HTTP response body without reading/decoding.
7283+
Default is True.
7284+
:type _preload_content: bool, optional
7285+
:param _return_http_data_only: response data instead of ApiResponse
7286+
object with status code, headers, etc
7287+
:type _return_http_data_only: bool, optional
7288+
:param _request_timeout: timeout setting for this request. If one
7289+
number provided, it will be total request
7290+
timeout. It can also be a pair (tuple) of
7291+
(connection, read) timeouts.
7292+
:param _request_auth: set to override the auth_settings for an a single
7293+
request; this effectively ignores the authentication
7294+
in the spec for a single request.
7295+
:type _request_auth: dict, optional
7296+
:type _content_type: string, optional: force content-type for the request
7297+
:return: Returns the result object.
7298+
If the method is called asynchronously,
7299+
returns the request thread.
7300+
:rtype: None
7301+
"""
7302+
7303+
_host = self.line_base_path
7304+
_params = locals()
7305+
7306+
_all_params = [
7307+
'mark_messages_as_read_by_token_request'
7308+
]
7309+
_all_params.extend(
7310+
[
7311+
'async_req',
7312+
'_return_http_data_only',
7313+
'_preload_content',
7314+
'_request_timeout',
7315+
'_request_auth',
7316+
'_content_type',
7317+
'_headers'
7318+
]
7319+
)
7320+
7321+
# validate the arguments
7322+
for _key, _val in _params['kwargs'].items():
7323+
if _key not in _all_params:
7324+
raise ApiTypeError(
7325+
"Got an unexpected keyword argument '%s'"
7326+
" to method mark_messages_as_read_by_token" % _key
7327+
)
7328+
_params[_key] = _val
7329+
del _params['kwargs']
7330+
7331+
_collection_formats = {}
7332+
7333+
# process the path parameters
7334+
_path_params = {}
7335+
7336+
# process the query parameters
7337+
_query_params = []
7338+
# process the header parameters
7339+
_header_params = dict(_params.get('_headers', {}))
7340+
# process the form parameters
7341+
_form_params = []
7342+
_files = {}
7343+
# process the body parameter
7344+
_body_params = None
7345+
if _params['mark_messages_as_read_by_token_request'] is not None:
7346+
_body_params = _params['mark_messages_as_read_by_token_request']
7347+
7348+
# set the HTTP header `Accept`
7349+
_header_params['Accept'] = self.api_client.select_header_accept(
7350+
['application/json']) # noqa: E501
7351+
7352+
# set the HTTP header `Content-Type`
7353+
_content_types_list = _params.get('_content_type',
7354+
self.api_client.select_header_content_type(
7355+
['application/json']))
7356+
if _content_types_list:
7357+
_header_params['Content-Type'] = _content_types_list
7358+
7359+
# authentication setting
7360+
_auth_settings = ['Bearer'] # noqa: E501
7361+
7362+
_response_types_map = {}
7363+
7364+
return self.api_client.call_api(
7365+
'/v2/bot/chat/markAsRead', 'POST',
7366+
_path_params,
7367+
_query_params,
7368+
_header_params,
7369+
body=_body_params,
7370+
post_params=_form_params,
7371+
files=_files,
7372+
response_types_map=_response_types_map,
7373+
auth_settings=_auth_settings,
7374+
async_req=_params.get('async_req'),
7375+
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
7376+
_preload_content=_params.get('_preload_content', True),
7377+
_request_timeout=_params.get('_request_timeout'),
7378+
_host=_host,
7379+
collection_formats=_collection_formats,
7380+
_request_auth=_params.get('_request_auth'))
7381+
72257382
@overload
72267383
async def multicast(self, multicast_request : MulticastRequest, x_line_retry_key : Annotated[Optional[StrictStr], Field(description="Retry key. Specifies the UUID in hexadecimal format (e.g., `123e4567-e89b-12d3-a456-426614174000`) generated by any method. The retry key isn't generated by LINE. Each developer must generate their own retry key. ")] = None, **kwargs) -> object: # noqa: E501
72277384
...

linebot/v3/messaging/api/messaging_api.py

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from linebot.v3.messaging.models.group_summary_response import GroupSummaryResponse
3939
from linebot.v3.messaging.models.group_user_profile_response import GroupUserProfileResponse
4040
from linebot.v3.messaging.models.issue_link_token_response import IssueLinkTokenResponse
41+
from linebot.v3.messaging.models.mark_messages_as_read_by_token_request import MarkMessagesAsReadByTokenRequest
4142
from linebot.v3.messaging.models.mark_messages_as_read_request import MarkMessagesAsReadRequest
4243
from linebot.v3.messaging.models.members_ids_response import MembersIdsResponse
4344
from linebot.v3.messaging.models.membership_list_response import MembershipListResponse
@@ -6750,6 +6751,152 @@ def mark_messages_as_read_with_http_info(self, mark_messages_as_read_request : M
67506751
collection_formats=_collection_formats,
67516752
_request_auth=_params.get('_request_auth'))
67526753

6754+
@validate_arguments
6755+
def mark_messages_as_read_by_token(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, **kwargs) -> None: # noqa: E501
6756+
"""mark_messages_as_read_by_token # noqa: E501
6757+
6758+
Mark messages from users as read by token # noqa: E501
6759+
This method makes a synchronous HTTP request by default. To make an
6760+
asynchronous HTTP request, please pass async_req=True
6761+
6762+
>>> thread = api.mark_messages_as_read_by_token(mark_messages_as_read_by_token_request, async_req=True)
6763+
>>> result = thread.get()
6764+
6765+
:param mark_messages_as_read_by_token_request: (required)
6766+
:type mark_messages_as_read_by_token_request: MarkMessagesAsReadByTokenRequest
6767+
:param async_req: Whether to execute the request asynchronously.
6768+
:type async_req: bool, optional
6769+
:param _request_timeout: timeout setting for this request. If one
6770+
number provided, it will be total request
6771+
timeout. It can also be a pair (tuple) of
6772+
(connection, read) timeouts.
6773+
:return: Returns the result object.
6774+
If the method is called asynchronously,
6775+
returns the request thread.
6776+
:rtype: None
6777+
"""
6778+
kwargs['_return_http_data_only'] = True
6779+
if '_preload_content' in kwargs:
6780+
raise ValueError("Error! Please call the mark_messages_as_read_by_token_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data")
6781+
return self.mark_messages_as_read_by_token_with_http_info(mark_messages_as_read_by_token_request, **kwargs) # noqa: E501
6782+
6783+
@validate_arguments
6784+
def mark_messages_as_read_by_token_with_http_info(self, mark_messages_as_read_by_token_request : MarkMessagesAsReadByTokenRequest, **kwargs) -> ApiResponse: # noqa: E501
6785+
"""mark_messages_as_read_by_token # noqa: E501
6786+
6787+
Mark messages from users as read by token # noqa: E501
6788+
This method makes a synchronous HTTP request by default. To make an
6789+
asynchronous HTTP request, please pass async_req=True
6790+
6791+
>>> thread = api.mark_messages_as_read_by_token_with_http_info(mark_messages_as_read_by_token_request, async_req=True)
6792+
>>> result = thread.get()
6793+
6794+
:param mark_messages_as_read_by_token_request: (required)
6795+
:type mark_messages_as_read_by_token_request: MarkMessagesAsReadByTokenRequest
6796+
:param async_req: Whether to execute the request asynchronously.
6797+
:type async_req: bool, optional
6798+
:param _preload_content: if False, the ApiResponse.data will
6799+
be set to none and raw_data will store the
6800+
HTTP response body without reading/decoding.
6801+
Default is True.
6802+
:type _preload_content: bool, optional
6803+
:param _return_http_data_only: response data instead of ApiResponse
6804+
object with status code, headers, etc
6805+
:type _return_http_data_only: bool, optional
6806+
:param _request_timeout: timeout setting for this request. If one
6807+
number provided, it will be total request
6808+
timeout. It can also be a pair (tuple) of
6809+
(connection, read) timeouts.
6810+
:param _request_auth: set to override the auth_settings for an a single
6811+
request; this effectively ignores the authentication
6812+
in the spec for a single request.
6813+
:type _request_auth: dict, optional
6814+
:type _content_type: string, optional: force content-type for the request
6815+
:return: Returns the result object.
6816+
If the method is called asynchronously,
6817+
returns the request thread.
6818+
:rtype: None
6819+
"""
6820+
6821+
_host = self.line_base_path
6822+
_params = locals()
6823+
6824+
_all_params = [
6825+
'mark_messages_as_read_by_token_request'
6826+
]
6827+
_all_params.extend(
6828+
[
6829+
'async_req',
6830+
'_return_http_data_only',
6831+
'_preload_content',
6832+
'_request_timeout',
6833+
'_request_auth',
6834+
'_content_type',
6835+
'_headers'
6836+
]
6837+
)
6838+
6839+
# validate the arguments
6840+
for _key, _val in _params['kwargs'].items():
6841+
if _key not in _all_params:
6842+
raise ApiTypeError(
6843+
"Got an unexpected keyword argument '%s'"
6844+
" to method mark_messages_as_read_by_token" % _key
6845+
)
6846+
_params[_key] = _val
6847+
del _params['kwargs']
6848+
6849+
_collection_formats = {}
6850+
6851+
# process the path parameters
6852+
_path_params = {}
6853+
6854+
# process the query parameters
6855+
_query_params = []
6856+
# process the header parameters
6857+
_header_params = dict(_params.get('_headers', {}))
6858+
# process the form parameters
6859+
_form_params = []
6860+
_files = {}
6861+
# process the body parameter
6862+
_body_params = None
6863+
if _params['mark_messages_as_read_by_token_request'] is not None:
6864+
_body_params = _params['mark_messages_as_read_by_token_request']
6865+
6866+
# set the HTTP header `Accept`
6867+
_header_params['Accept'] = self.api_client.select_header_accept(
6868+
['application/json']) # noqa: E501
6869+
6870+
# set the HTTP header `Content-Type`
6871+
_content_types_list = _params.get('_content_type',
6872+
self.api_client.select_header_content_type(
6873+
['application/json']))
6874+
if _content_types_list:
6875+
_header_params['Content-Type'] = _content_types_list
6876+
6877+
# authentication setting
6878+
_auth_settings = ['Bearer'] # noqa: E501
6879+
6880+
_response_types_map = {}
6881+
6882+
return self.api_client.call_api(
6883+
'/v2/bot/chat/markAsRead', 'POST',
6884+
_path_params,
6885+
_query_params,
6886+
_header_params,
6887+
body=_body_params,
6888+
post_params=_form_params,
6889+
files=_files,
6890+
response_types_map=_response_types_map,
6891+
auth_settings=_auth_settings,
6892+
async_req=_params.get('async_req'),
6893+
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
6894+
_preload_content=_params.get('_preload_content', True),
6895+
_request_timeout=_params.get('_request_timeout'),
6896+
_host=_host,
6897+
collection_formats=_collection_formats,
6898+
_request_auth=_params.get('_request_auth'))
6899+
67536900
@validate_arguments
67546901
def multicast(self, multicast_request : MulticastRequest, x_line_retry_key : Annotated[Optional[StrictStr], Field(description="Retry key. Specifies the UUID in hexadecimal format (e.g., `123e4567-e89b-12d3-a456-426614174000`) generated by any method. The retry key isn't generated by LINE. Each developer must generate their own retry key. ")] = None, **kwargs) -> object: # noqa: E501
67556902
"""multicast # noqa: E501

0 commit comments

Comments
 (0)