# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""linebot.models.flex_message module."""
from abc import ABCMeta
from future.utils import with_metaclass
from .background import Background, LinearGradientBackground
from .actions import get_action
from .base import Base
from .send_messages import SendMessage
[docs]class FlexSendMessage(SendMessage):
"""FlexSendMessage.
https://developers.line.biz/en/reference/messaging-api/#flex-message
Flex Messages are messages with a customizable layout.
You can customize the layout freely by combining multiple elements.
"""
[docs] def __init__(self, alt_text=None, contents=None, **kwargs):
"""__init__ method.
:param str alt_text: Alternative text
:param contents: Flex Message container object
:type contents: :py:class:`linebot.models.flex_message.FlexContainer`
:param kwargs:
"""
super(FlexSendMessage, self).__init__(**kwargs)
self.type = 'flex'
self.alt_text = alt_text
self.contents = self.get_or_new_from_json_dict_with_types(
contents, {
'bubble': BubbleContainer,
'carousel': CarouselContainer
}
)
[docs]class FlexContainer(with_metaclass(ABCMeta, Base)):
"""FlexContainer.
https://developers.line.biz/en/reference/messaging-api/#container
A container is the top-level structure of a Flex Message.
"""
[docs] def __init__(self, **kwargs):
"""__init__ method.
:param kwargs:
"""
super(FlexContainer, self).__init__(**kwargs)
self.type = None
[docs]class BubbleContainer(FlexContainer):
"""BubbleContainer.
https://developers.line.biz/en/reference/messaging-api/#bubble
This is a container that contains one message bubble.
It can contain four blocks: header, hero, body, and footer.
"""
[docs] def __init__(self, size=None, direction=None, header=None, hero=None,
body=None, footer=None, styles=None, action=None, **kwargs):
"""__init__ method.
:param str size: The size of the bubble. `nano`, `micro`, `kilo`, `mega`, or `giga`.
:param str direction: Text directionality and the order of components
in horizontal boxes in the container
:param header: Header block
:type header: :py:class:`linebot.models.flex_message.BoxComponent`
:param hero: Hero block
:type hero: :py:class:`linebot.models.flex_message.ImageComponent`
| :py:class:`linebot.models.flex_message.BoxComponent`
| :py:class:`linebot.models.flex_message.VideoComponent`
:param body: Body block
:type body: :py:class:`linebot.models.flex_message.BoxComponent`
:param footer: Footer block
:type footer: :py:class:`linebot.models.flex_message.BoxComponent`
:param styles: Style of each block
:type styles: :py:class:`linebot.models.flex_message.BubbleStyle`
:param action: Action performed when this button is tapped
:type action: list[T <= :py:class:`linebot.models.actions.Action`]
:param kwargs:
"""
super(BubbleContainer, self).__init__(**kwargs)
self.type = 'bubble'
self.size = size
self.direction = direction
self.header = self.get_or_new_from_json_dict(header, BoxComponent)
self.hero = self.get_or_new_from_json_dict_with_types(
hero, {
'image': ImageComponent,
'box': BoxComponent,
'video': VideoComponent
}
)
self.body = self.get_or_new_from_json_dict(body, BoxComponent)
self.footer = self.get_or_new_from_json_dict(footer, BoxComponent)
self.styles = self.get_or_new_from_json_dict(styles, BubbleStyle)
self.action = get_action(action)
[docs]class BubbleStyle(with_metaclass(ABCMeta, Base)):
"""BubbleStyle.
https://developers.line.biz/en/reference/messaging-api/#bubble-style
"""
[docs] def __init__(self, header=None, hero=None, body=None, footer=None, **kwargs):
"""__init__ method.
:param header: Style of the header block
:type header: :py:class:`linebot.models.flex_message.BlockStyle`
:param hero: Style of the hero block
:type hero: :py:class:`linebot.models.flex_message.BlockStyle`
:param body: Style of the body block
:type body: :py:class:`linebot.models.flex_message.BlockStyle`
:param footer: Style of the footer block
:type footer: :py:class:`linebot.models.flex_message.BlockStyle`
:param kwargs:
"""
super(BubbleStyle, self).__init__(**kwargs)
self.header = self.get_or_new_from_json_dict(header, BlockStyle)
self.hero = self.get_or_new_from_json_dict(hero, BlockStyle)
self.body = self.get_or_new_from_json_dict(body, BlockStyle)
self.footer = self.get_or_new_from_json_dict(footer, BlockStyle)
[docs]class BlockStyle(with_metaclass(ABCMeta, Base)):
"""BlockStyle.
https://developers.line.biz/en/reference/messaging-api/#block-style
"""
[docs] def __init__(self, background_color=None, separator=None, separator_color=None, **kwargs):
"""__init__ method.
:param str background_color: Background color of the block. Use a hexadecimal color code
:param bool separator: True to place a separator above the block
True will be ignored for the first block in a container
because you cannot place a separator above the first block.
The default value is False
:param str separator_color: Color of the separator. Use a hexadecimal color code
:param kwargs:
"""
super(BlockStyle, self).__init__(**kwargs)
self.background_color = background_color
self.separator = separator
self.separator_color = separator_color
[docs]class CarouselContainer(FlexContainer):
"""CarouselContainer.
https://developers.line.biz/en/reference/messaging-api/#f-carousel
This is a container that contains multiple bubble containers, or message bubbles.
The bubbles will be shown in order by scrolling horizontally.
"""
[docs] def __init__(self, contents=None, **kwargs):
"""__init__ method.
:param contents: Array of bubble containers
:type contents: list[T <= :py:class:`linebot.models.flex_message.BubbleContainer`]
:param kwargs:
"""
super(CarouselContainer, self).__init__(**kwargs)
self.type = 'carousel'
new_contents = []
if contents:
for it in contents:
new_contents.append(self.get_or_new_from_json_dict(
it, BubbleContainer
))
self.contents = new_contents
[docs]class FlexComponent(with_metaclass(ABCMeta, Base)):
"""FlexComponent.
https://developers.line.biz/en/reference/messaging-api/#component
Components are objects that compose a Flex Message container.
"""
[docs] def __init__(self, **kwargs):
"""__init__ method.
:param kwargs:
"""
super(FlexComponent, self).__init__(**kwargs)
self.type = None
[docs]class BoxComponent(FlexComponent):
"""BoxComponent.
https://developers.line.biz/en/reference/messaging-api/#box
This is a component that defines the layout of child components.
You can also include a box in a box.
"""
[docs] def __init__(self,
layout=None,
contents=None,
background_color=None,
border_color=None,
border_width=None,
corner_radius=None,
justify_content=None,
align_items=None,
background=None,
width=None,
max_width=None,
height=None,
max_height=None,
flex=None,
spacing=None,
margin=None,
padding_all=None,
padding_top=None,
padding_bottom=None,
padding_start=None,
padding_end=None,
position=None,
offset_top=None,
offset_bottom=None,
offset_start=None,
offset_end=None,
action=None,
**kwargs):
"""__init__ method.
:param str layout: The placement style of components in this box
:param contents: Components in this box
:type contents: list[T <= :py:class:`linebot.models.flex_message.FlexComponent`]
:param str background_color: Background color of the block
:param str border_color: Color of box border
:param str border_width: Width of box border
:param str corner_radius: Radius at the time of rounding the corners of the border
:param str justify_content: How child elements are aligned along the main axis of
the parent element
:param str align_items: How child elements are aligned along the cross axis of
the parent element
:param background: Background object
:type background: T <= :py:class:`linebot.models.background.Background`
:param str width: Width of the box
:param str max_width: Maximum width of the box
:param str height: Height of the box
:param str max_height: Maximum height of the box
:param float flex: The ratio of the width or height of this box within the parent box
and the previous component in the parent box
:param str spacing: Minimum space between components in this box
:param str margin: Minimum space between this box
:param str padding_all: Free space between the borders of this box and the child element
:param str padding_top: Free space between the border at the upper end of this box
and the upper end of the child element
:param str padding_bottom: Free space between the border at the lower end of this box
and the lower end of the child element
:param str padding_start: Free space between the border at the left end of this box
and the left end of the child element
:param str padding_end: Free space between the border at the right end of this box
and the right end of the child element
:param str position: Reference position for placing this box
:param str offset_top: The top offset
:param str offset_bottom: The bottom offset
:param str offset_start: The left offset
:param str offset_end: The right offset
:param action: Action performed when this button is tapped
:type action: list[T <= :py:class:`linebot.models.actions.Action`]
:param kwargs:
"""
super(BoxComponent, self).__init__(**kwargs)
self.type = 'box'
self.layout = layout
self.background_color = background_color
self.border_color = border_color
self.border_width = border_width
self.corner_radius = corner_radius
self.justify_content = justify_content
self.align_items = align_items
self.width = width
self.max_width = max_width
self.height = height
self.max_height = max_height
self.flex = flex
self.spacing = spacing
self.margin = margin
self.padding_all = padding_all
self.padding_top = padding_top
self.padding_bottom = padding_bottom
self.padding_start = padding_start
self.padding_end = padding_end
self.position = position
self.offset_top = offset_top
self.offset_bottom = offset_bottom
self.offset_start = offset_start
self.offset_end = offset_end
self.action = get_action(action)
self.background = Background.get_or_new_from_json_dict_with_types(
background, {'linearGradient': LinearGradientBackground}
)
new_contents = []
if contents:
for it in contents:
new_contents.append(self.get_or_new_from_json_dict_with_types(
it, {
'box': BoxComponent,
'button': ButtonComponent,
'filler': FillerComponent,
'icon': IconComponent,
'image': ImageComponent,
'span': SpanComponent,
'separator': SeparatorComponent,
'text': TextComponent,
'video': VideoComponent
}
))
self.contents = new_contents
[docs]class FillerComponent(FlexComponent):
"""FillerComponent.
https://developers.line.biz/en/reference/messaging-api/#filler
This is an invisible component to fill extra space between components.
"""
[docs] def __init__(self, flex=None, **kwargs):
"""__init__ method.
:param kwargs:
"""
super(FillerComponent, self).__init__(**kwargs)
self.type = 'filler'
self.flex = flex
[docs]class IconComponent(FlexComponent):
"""IconComponent.
https://developers.line.biz/en/reference/messaging-api/#icon
This component draws an icon.
"""
[docs] def __init__(self,
url=None,
margin=None,
position=None,
offset_top=None,
offset_bottom=None,
offset_start=None,
offset_end=None,
size=None,
aspect_ratio=None,
**kwargs):
"""__init__ method.
:param str url: Image URL
Protocol: HTTPS
Image format: JPEG or PNG
:param str margin: Minimum space between this component
and the previous component in the parent box
:param str position: Reference position for placing this box
:param str offset_top: The top offset
:param str offset_bottom: The bottom offset
:param str offset_start: The left offset
:param str offset_end: The right offset
:param str size: Maximum size of the icon width
:param str aspect_ratio: Aspect ratio of the icon
:param kwargs:
"""
super(IconComponent, self).__init__(**kwargs)
self.type = 'icon'
self.url = url
self.margin = margin
self.position = position
self.offset_top = offset_top
self.offset_bottom = offset_bottom
self.offset_start = offset_start
self.offset_end = offset_end
self.size = size
self.aspect_ratio = aspect_ratio
[docs]class ImageComponent(FlexComponent):
"""ImageComponent.
https://developers.line.biz/en/reference/messaging-api/#f-image
This component draws an image.
"""
[docs] def __init__(self,
url=None,
flex=None,
margin=None,
position=None,
offset_top=None,
offset_bottom=None,
offset_start=None,
offset_end=None,
align=None,
gravity=None,
size=None,
aspect_ratio=None,
aspect_mode=None,
background_color=None,
action=None,
animated=False,
**kwargs):
"""__init__ method.
:param str url: Image URL
Protocol: HTTPS
Image format: JPEG or PNG
:param float flex: The ratio of the width or height of this component within the parent box
:param str margin: Minimum space between this component
and the previous component in the parent box
:param str position: Reference position for placing this box
:param str offset_top: The top offset
:param str offset_bottom: The bottom offset
:param str offset_start: The left offset
:param str offset_end: The right offset
:param str align: Horizontal alignment style
:param str gravity: Vertical alignment style
:param str size: Maximum size of the image width
:param str aspect_ratio: Aspect ratio of the image
:param str aspect_mode: Style of the image
:param str background_color: Background color of the image. Use a hexadecimal color code.
:param action: Action performed when this image is tapped
:type action: list[T <= :py:class:`linebot.models.actions.Action`]
:param bool animated: True to play an animated image. Default is False.
:param kwargs:
"""
super(ImageComponent, self).__init__(**kwargs)
self.type = 'image'
self.url = url
self.flex = flex
self.margin = margin
self.position = position
self.offset_top = offset_top
self.offset_bottom = offset_bottom
self.offset_start = offset_start
self.offset_end = offset_end
self.align = align
self.gravity = gravity
self.size = size
self.aspect_ratio = aspect_ratio
self.aspect_mode = aspect_mode
self.background_color = background_color
self.action = get_action(action)
self.animated = animated
[docs]class SeparatorComponent(FlexComponent):
"""SeparatorComponent.
https://developers.line.biz/en/reference/messaging-api/#separator
This component draws a separator between components in the parent box.
"""
[docs] def __init__(self, margin=None, color=None, **kwargs):
"""__init__ method.
:param str margin: Minimum space between this component
and the previous component in the parent box
:param str color: Color of the separator. Use a hexadecimal color code
:param kwargs:
"""
super(SeparatorComponent, self).__init__(**kwargs)
self.type = 'separator'
self.margin = margin
self.color = color
[docs]class SpanComponent(FlexComponent):
"""SpanComponent.
https://developers.line.biz/en/reference/messaging-api/#span
This component renders multiple text strings with different designs in one row.
"""
[docs] def __init__(self,
text=None,
color=None,
size=None,
weight=None,
style=None,
decoration=None,
**kwargs):
r"""__init__ method.
:param str text: Text
:param str color: Font color
:param str size: Font size
:param str weight: Font weight
:param str style: Style of the text
:param str decoration: Decoration of the text
:param kwargs:
"""
super(SpanComponent, self).__init__(**kwargs)
self.type = 'span'
self.text = text
self.size = size
self.weight = weight
self.color = color
self.style = style
self.decoration = decoration
[docs]class TextComponent(FlexComponent):
"""TextComponent.
https://developers.line.biz/en/reference/messaging-api/#f-text
This component draws text. You can format the text.
"""
[docs] def __init__(self,
text=None,
contents=None,
flex=None,
margin=None,
position=None,
offset_top=None,
offset_bottom=None,
offset_start=None,
offset_end=None,
size=None,
align=None,
gravity=None,
wrap=None,
line_spacing=None,
max_lines=None,
weight=None,
color=None,
action=None,
style=None,
decoration=None,
**kwargs):
r"""__init__ method.
:param str text: Text
:param contents: Array of spans
:type contents: list[T <= :py:class:`linebot.models.flex_message.SpanComponent`]
:param float flex: The ratio of the width or height of this component within the parent box
:param str margin: Minimum space between this component
and the previous component in the parent box
:param str position: Reference position for placing this box
:param str offset_top: The top offset
:param str offset_bottom: The bottom offset
:param str offset_start: The left offset
:param str offset_end: The right offset
:param str size: Font size
:param str align: Horizontal alignment style
:param str gravity: Vertical alignment style
:param bool wrap: rue to wrap text. The default value is False.
If set to True, you can use a new line character (\n) to begin on a new line.
:param str line_spacing: Line spacing in a wrapping text
:param int max_lines: Max number of lines
:param str weight: Font weight
:param str color: Font color
:param action: Action performed when this image is tapped
:type action: list[T <= :py:class:`linebot.models.actions.Action`]
:param str style: Style of the text
:param str decoration: Decoration of the text
:param kwargs:
"""
super(TextComponent, self).__init__(**kwargs)
self.type = 'text'
self.text = text
self.flex = flex
self.margin = margin
self.position = position
self.offset_top = offset_top
self.offset_bottom = offset_bottom
self.offset_start = offset_start
self.offset_end = offset_end
self.size = size
self.align = align
self.gravity = gravity
self.wrap = wrap
self.line_spacing = line_spacing
self.max_lines = max_lines
self.weight = weight
self.color = color
self.action = get_action(action)
self.style = style
self.decoration = decoration
if contents:
self.contents = [self.get_or_new_from_json_dict(it, SpanComponent) for it in contents]
else:
self.contents = None
[docs]class VideoComponent(FlexComponent):
"""VideoComponent.
https://developers.line.biz/en/reference/messaging-api/#f-video
This component renders a video.
"""
[docs] def __init__(self,
url=None,
preview_url=None,
alt_content=None,
aspect_ratio=None,
action=None,
**kwargs):
r"""__init__ method.
:param str url: URL of video file
:param str preview_url: URL of preview image
:param alt_content: Alternative content
:type alt_content: :py:class:`linebot.models.flex_message.ImageComponent`
| :py:class:`linebot.models.flex_message.BoxComponent`
:param float aspect_ratio: Aspect ratio of the video
:param action: Action performed when this video is tapped
:type action: list[T <= :py:class:`linebot.models.actions.Action`]
:param kwargs:
"""
super(VideoComponent, self).__init__(**kwargs)
self.type = 'video'
self.url = url
self.preview_url = preview_url
self.alt_content = self.get_or_new_from_json_dict_with_types(
alt_content, {
'image': ImageComponent,
'box': BoxComponent
}
)
self.aspect_ratio = aspect_ratio
self.action = get_action(action)