Skip to content

Commit 28cd5a7

Browse files
authored
New Messaging API endpoints for friend statistics (#198)
* add new api about insight * add insight example
1 parent 71136d5 commit 28cd5a7

File tree

8 files changed

+543
-0
lines changed

8 files changed

+543
-0
lines changed

README.rst

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,42 @@ https://developers.line.biz/en/reference/messaging-api/#revoke-channel-access-to
460460
461461
line_bot_api.revoke_channel_token(<access_token>)
462462
463+
get\_insight\_message\_delivery(self, date, timeout=None)
464+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
465+
466+
Get the number of messages sent on a specified day.
467+
468+
https://developers.line.biz/en/reference/messaging-api/#get-number-of-delivery-messages
469+
470+
.. code:: python
471+
472+
insight = line_bot_api.get_insight_message_delivery('20191231')
473+
print(insight.api_broadcast)
474+
475+
get\_insight\_followers(self, date, timeout=None)
476+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
477+
478+
Get the number of users who have added the bot on or before a specified date.
479+
480+
https://developers.line.biz/en/reference/messaging-api/#get-number-of-followers
481+
482+
.. code:: python
483+
484+
insight = line_bot_api.get_insight_followers('20191231')
485+
print(insight.followers)
486+
487+
get\_insight\_demographic(self, timeout=None)
488+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
489+
490+
Retrieve the demographic attributes for a bot's friends.
491+
492+
https://developers.line.biz/en/reference/messaging-api/#get-demographic
493+
494+
.. code:: python
495+
496+
insight = line_bot_api.get_insight_demographic()
497+
print(insight.genders)
498+
463499
※ Error handling
464500
^^^^^^^^^^^^^^^^
465501

docs/source/linebot.models.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ linebot.models.imagemap module
3232

3333
.. automodule:: linebot.models.imagemap
3434

35+
linebot.models.insight module
36+
------------------------------
37+
38+
.. automodule:: linebot.models.insight
39+
3540
linebot.models.messages module
3641
------------------------------
3742

examples/flask-kitchensink/app.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from __future__ import unicode_literals
1616

17+
import datetime
1718
import errno
1819
import os
1920
import sys
@@ -366,6 +367,37 @@ def handle_text_message(event):
366367
TextSendMessage(text='link_token: ' + link_token_response.link_token)
367368
]
368369
)
370+
elif text == 'insight_message_delivery':
371+
today = datetime.date.today().strftime("%Y%m%d")
372+
response = line_bot_api.get_insight_message_delivery(today)
373+
if response.status == 'ready':
374+
messages = [
375+
TextSendMessage(text='broadcast: ' + str(response.broadcast)),
376+
TextSendMessage(text='targeting: ' + str(response.targeting)),
377+
]
378+
else:
379+
messages = [TextSendMessage(text='status: ' + response.status)]
380+
line_bot_api.reply_message(event.reply_token, messages)
381+
elif text == 'insight_followers':
382+
today = datetime.date.today().strftime("%Y%m%d")
383+
response = line_bot_api.get_insight_followers(today)
384+
if response.status == 'ready':
385+
messages = [
386+
TextSendMessage(text='followers: ' + str(response.followers)),
387+
TextSendMessage(text='targetedReaches: ' + str(response.targeted_reaches)),
388+
TextSendMessage(text='blocks: ' + str(response.blocks)),
389+
]
390+
else:
391+
messages = [TextSendMessage(text='status: ' + response.status)]
392+
line_bot_api.reply_message(event.reply_token, messages)
393+
elif text == 'insight_demographic':
394+
response = line_bot_api.get_insight_demographic()
395+
if response.available:
396+
messages = ["{gender}: {percentage}".format(gender=it.gender, percentage=it.percentage)
397+
for it in response.genders]
398+
else:
399+
messages = [TextSendMessage(text='available: false')]
400+
line_bot_api.reply_message(event.reply_token, messages)
369401
else:
370402
line_bot_api.reply_message(
371403
event.reply_token, TextSendMessage(text=event.message.text))

linebot/api.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
MessageQuotaConsumptionResponse, IssueLinkTokenResponse, IssueChannelTokenResponse,
2727
MessageDeliveryBroadcastResponse, MessageDeliveryMulticastResponse,
2828
MessageDeliveryPushResponse, MessageDeliveryReplyResponse,
29+
InsightMessageDeliveryResponse, InsightFollowersResponse, InsightDemographicResponse,
2930
)
3031

3132

@@ -875,6 +876,63 @@ def revoke_channel_token(self, access_token, timeout=None):
875876
timeout=timeout
876877
)
877878

879+
def get_insight_message_delivery(self, date, timeout=None):
880+
"""Get the number of messages sent on a specified day.
881+
882+
https://developers.line.biz/en/reference/messaging-api/#get-number-of-delivery-messages
883+
884+
:param str date: Date for which to retrieve number of sent messages.
885+
:param timeout: (optional) How long to wait for the server
886+
to send data before giving up, as a float,
887+
or a (connect timeout, read timeout) float tuple.
888+
Default is self.http_client.timeout
889+
:type timeout: float | tuple(float, float)
890+
"""
891+
response = self._get(
892+
'/v2/bot/insight/message/delivery?date={date}'.format(date=date),
893+
timeout=timeout
894+
)
895+
896+
return InsightMessageDeliveryResponse.new_from_json_dict(response.json)
897+
898+
def get_insight_followers(self, date, timeout=None):
899+
"""Get the number of users who have added the bot on or before a specified date.
900+
901+
https://developers.line.biz/en/reference/messaging-api/#get-number-of-followers
902+
903+
:param str date: Date for which to retrieve the number of followers.
904+
:param timeout: (optional) How long to wait for the server
905+
to send data before giving up, as a float,
906+
or a (connect timeout, read timeout) float tuple.
907+
Default is self.http_client.timeout
908+
:type timeout: float | tuple(float, float)
909+
"""
910+
response = self._get(
911+
'/v2/bot/insight/followers?date={date}'.format(date=date),
912+
timeout=timeout
913+
)
914+
915+
return InsightFollowersResponse.new_from_json_dict(response.json)
916+
917+
def get_insight_demographic(self, timeout=None):
918+
"""Retrieve the demographic attributes for a bot's friends.
919+
920+
https://developers.line.biz/en/reference/messaging-api/#get-demographic
921+
922+
:param str date: Date for which to retrieve the number of followers.
923+
:param timeout: (optional) How long to wait for the server
924+
to send data before giving up, as a float,
925+
or a (connect timeout, read timeout) float tuple.
926+
Default is self.http_client.timeout
927+
:type timeout: float | tuple(float, float)
928+
"""
929+
response = self._get(
930+
'/v2/bot/insight/demographic',
931+
timeout=timeout
932+
)
933+
934+
return InsightDemographicResponse.new_from_json_dict(response.json)
935+
878936
def _get(self, path, params=None, headers=None, stream=False, timeout=None):
879937
url = self.endpoint + path
880938

linebot/models/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@
8181
Video,
8282
ExternalLink,
8383
)
84+
from .insight import ( # noqa
85+
DemographicInsight,
86+
AgeInsight,
87+
AreaInsight,
88+
AppTypeInsight,
89+
GenderInsight,
90+
SubscriptionPeriodInsight,
91+
)
8492
from .messages import ( # noqa
8593
Message,
8694
TextMessage,
@@ -105,6 +113,9 @@
105113
Content as MessageContent, # backward compatibility,
106114
IssueLinkTokenResponse,
107115
IssueChannelTokenResponse,
116+
InsightMessageDeliveryResponse,
117+
InsightFollowersResponse,
118+
InsightDemographicResponse,
108119
)
109120
from .rich_menu import ( # noqa
110121
RichMenu,

linebot/models/insight.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# https://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
"""linebot.models.insight module."""
16+
17+
from __future__ import unicode_literals
18+
19+
from abc import ABCMeta
20+
21+
from future.utils import with_metaclass
22+
23+
from .base import Base
24+
25+
26+
class DemographicInsight(with_metaclass(ABCMeta, Base)):
27+
"""Abstract Base Class of DemographicInsight."""
28+
29+
def __init__(self, percentage=None, **kwargs):
30+
"""__init__ method.
31+
32+
:param float percentage: Percentage.
33+
:param kwargs:
34+
"""
35+
super(DemographicInsight, self).__init__(**kwargs)
36+
self.percentage = percentage
37+
38+
39+
class GenderInsight(DemographicInsight):
40+
"""GenderInsight."""
41+
42+
def __init__(self, percentage=None, gender=None, **kwargs):
43+
"""__init__ method.
44+
45+
:param float percentage: Percentage.
46+
:param str gender: Gender
47+
:param kwargs:
48+
"""
49+
super(GenderInsight, self).__init__(percentage=percentage, **kwargs)
50+
51+
self.gender = gender
52+
53+
54+
class AgeInsight(DemographicInsight):
55+
"""AgeInsight."""
56+
57+
def __init__(self, percentage=None, age=None, **kwargs):
58+
"""__init__ method.
59+
60+
:param float percentage: Percentage.
61+
:param str age: Age
62+
:param kwargs:
63+
"""
64+
super(AgeInsight, self).__init__(percentage=percentage, **kwargs)
65+
66+
self.age = age
67+
68+
69+
class AreaInsight(DemographicInsight):
70+
"""AreaInsight."""
71+
72+
def __init__(self, percentage=None, area=None, **kwargs):
73+
"""__init__ method.
74+
75+
:param float percentage: Percentage.
76+
:param str area: Area
77+
:param kwargs:
78+
"""
79+
super(AreaInsight, self).__init__(percentage=percentage, **kwargs)
80+
81+
self.area = area
82+
83+
84+
class AppTypeInsight(DemographicInsight):
85+
"""AppTypeInsight."""
86+
87+
def __init__(self, percentage=None, app_type=None, **kwargs):
88+
"""__init__ method.
89+
90+
:param float percentage: Percentage.
91+
:param str app_type: OS
92+
:param kwargs:
93+
"""
94+
super(AppTypeInsight, self).__init__(percentage=percentage, **kwargs)
95+
96+
self.app_type = app_type
97+
98+
99+
class SubscriptionPeriodInsight(DemographicInsight):
100+
"""SubscriptionPeriodInsight."""
101+
102+
def __init__(self, percentage=None, subscription_period=None, **kwargs):
103+
"""__init__ method.
104+
105+
:param float percentage: Percentage.
106+
:param str subscription_period: Friendship duration
107+
:param kwargs:
108+
"""
109+
super(SubscriptionPeriodInsight, self).__init__(percentage=percentage, **kwargs)
110+
111+
self.subscription_period = subscription_period

0 commit comments

Comments
 (0)