Skip to content

Commit dbb86f6

Browse files
committed
1 parent 4f900fe commit dbb86f6

File tree

5 files changed

+472
-3
lines changed

5 files changed

+472
-3
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# -*- coding: utf-8 -*-
2+
import logging
3+
from linebot import LineBotApi as LineBotApi_ori
4+
5+
logging.basicConfig(
6+
level=logging.DEBUG,
7+
format='%(asctime)s %(levelname)s %(message)s',
8+
datefmt='%Y-%m-%d %H:%M',
9+
handlers=[logging.FileHandler('my.log', 'w', 'utf-8'), ]
10+
)
11+
12+
channel_access_token = 'xxxxxxx'
13+
14+
tester = [
15+
"Utesttestesttesttesttestestest18",
16+
"Utesttestesttesttesttestestest61",
17+
"Utesttestesttesttesttestestest59",
18+
"Utesttestesttesttesttestestest89",
19+
"Utesttestesttesttesttestestest79",
20+
"Utesttestesttesttesttestestest8c",
21+
"Utesttestesttesttesttestestestc3",
22+
"Utesttestesttesttesttestestest29",
23+
"Utesttestesttesttesttestestest03",
24+
]
25+
26+
line_ids = {
27+
"tester": tester,
28+
"tester1": tester[:5],
29+
"測試": tester[:4],
30+
"tester2": tester[:3],
31+
"tester3": tester[:2],
32+
"tester john": tester[:1],
33+
}
34+
35+
request_id = "xxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
36+
37+
38+
class LineBotApi(LineBotApi_ori):
39+
def create_audience_group(self, audience_group_name, audiences, is_ifa=False, mode="normal", timeout=None):
40+
if mode in ["force", "append"]:
41+
audience_group_id = self.get_audience_gid_by_name(audience_group_name)
42+
if audience_group_id is not None and mode == "force":
43+
self.delete_audience_group(audience_group_id)
44+
elif audience_group_id is not None and mode == "append":
45+
self.add_audiences_to_audience_group(audience_group_id, audiences)
46+
return audience_group_id
47+
return super(LineBotApi, self).create_audience_group(audience_group_name, audiences, is_ifa, timeout)
48+
49+
def get_audience_gid_by_name(self, description, timeout=None):
50+
audience_groups = super(LineBotApi, self).get_audience_group_list(description=description, timeout=timeout)
51+
for audience_group in audience_groups:
52+
if audience_group.description.encode('utf-8') == description:
53+
return audience_group.audience_group_id
54+
else:
55+
return None
56+
57+
def delete_audience_groups(self, audienceGroupIds):
58+
for audienceGroupId in audienceGroupIds:
59+
if audienceGroupId is not None:
60+
self.delete_audience_group(audienceGroupId)
61+
62+
63+
def initialize_env():
64+
_audience_group_id = [line_bot_api.get_audience_gid_by_name(gn) for gn in line_ids.keys()]
65+
_audience_group_id += [line_bot_api.get_audience_gid_by_name(gn + "_new") for gn in line_ids.keys()]
66+
_audience_group_id += [line_bot_api.get_audience_gid_by_name(gn) for gn in
67+
['test_impression_based', 'test_click_based']]
68+
line_bot_api.delete_audience_groups(_audience_group_id)
69+
70+
71+
def add_audience_groups_cust(mode="normal"):
72+
_audience_group_ids = []
73+
for audience_name, line_id in line_ids.items():
74+
if len(line_id) > 0:
75+
new_gid = line_bot_api.create_audience_group(audience_name, line_id, mode=mode)
76+
_audience_group_ids.append(new_gid)
77+
return _audience_group_ids
78+
79+
80+
def main():
81+
initialize_env()
82+
to_be_delete = []
83+
84+
# Test create_impression_based_audience_group
85+
_audience_group_id = line_bot_api.create_impression_based_audience_group('test_impression_based', request_id)
86+
to_be_delete.append(_audience_group_id)
87+
logging.info("create_impression_based_audience_group result :\n{}".format(_audience_group_id))
88+
89+
# Test create_click_based_audience_group
90+
_audience_group_id = line_bot_api.create_click_based_audience_group('test_click_based', request_id)
91+
to_be_delete.append(_audience_group_id)
92+
logging.info("create_click_based_audience_group result :\n{}".format(_audience_group_id))
93+
94+
# Test create_audience_group (normal)
95+
_audience_group_ids = add_audience_groups_cust()
96+
logging.info("create_audience_group(normal) result :\n{}".format(_audience_group_ids))
97+
98+
# Test create_audience_group (force)
99+
_audience_group_ids = add_audience_groups_cust("force")
100+
logging.info("create_audience_group(force) result :\n{}".format(_audience_group_ids))
101+
102+
# Test create_audience_group (append)
103+
_audience_group_ids = add_audience_groups_cust("append")
104+
logging.info("create_audience_group(append) result :\n{}".format(_audience_group_ids))
105+
106+
# Test get_audience_group_list
107+
_audience_group_ids = [line_bot_api.get_audience_gid_by_name(gn) for gn in line_ids.keys()]
108+
logging.info("get_audience_group_list result :\n{}".format(_audience_group_ids))
109+
110+
# Test rename_audience_group
111+
[line_bot_api.rename_audience_group(gid, gn + "_new") for gn, gid in zip(line_ids.keys(), _audience_group_ids)]
112+
113+
# Test add_audiences_to_audience_group
114+
[line_bot_api.add_audiences_to_audience_group(gid, tester[-3:], upload_description='test_{}'.format(gid))
115+
for gid in _audience_group_ids]
116+
117+
# Test list all audience groups
118+
_audience_groups = line_bot_api.get_audience_group(_audience_group_ids[1])
119+
logging.info("Get audience group by 1st id :\n{}".format(_audience_groups))
120+
121+
# Test get_audience_group
122+
_audience_groups = [line_bot_api.get_audience_group(gid) for gid in _audience_group_ids]
123+
logging.info("get_audience_group result :\n{}".format(_audience_groups))
124+
125+
# Test delete_audience_group
126+
[line_bot_api.delete_audience_group(gid) for gid in _audience_group_ids]
127+
128+
# Test delete_audience_groups
129+
line_bot_api.delete_audience_groups(to_be_delete)
130+
131+
# Test change_audience_group_authority_level
132+
line_bot_api.change_audience_group_authority_level('PUBLIC')
133+
134+
# Test get_audience_group_authority_level
135+
_result = line_bot_api.get_audience_group_authority_level()
136+
logging.info("change_audience_group_authority_level result :\n{}".format(_result))
137+
138+
# Test list all audience groups
139+
_audience_groups = line_bot_api.get_audience_group_list()
140+
logging.info("All audience groups :\n{}".format(_audience_groups))
141+
142+
143+
if __name__ == '__main__':
144+
line_bot_api = LineBotApi(channel_access_token)
145+
main()

linebot/api.py

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
InsightMessageDeliveryResponse, InsightFollowersResponse, InsightDemographicResponse,
3030
InsightMessageEventResponse, BroadcastResponse, NarrowcastResponse,
3131
MessageProgressNarrowcastResponse, BotInfo, GetWebhookResponse, TestWebhookResponse,
32+
AudienceGroup,
3233
)
3334
from .models.responses import Group
3435

@@ -1148,6 +1149,244 @@ def get_bot_info(self, timeout=None):
11481149

11491150
return BotInfo.new_from_json_dict(response.json)
11501151

1152+
def create_audience_group(self, audience_group_name, audiences=[],
1153+
is_ifa=False, timeout=None):
1154+
"""Create an audience group.
1155+
1156+
https://developers.line.biz/en/reference/messaging-api/#create-upload-audience-group
1157+
1158+
:param str audience_group_name: The audience's name
1159+
:param list audiences: An array of user IDs or IFAs
1160+
:param bool is_ifa: true | false
1161+
:return: audience group id
1162+
"""
1163+
response = self._post(
1164+
'/v2/bot/audienceGroup/upload',
1165+
data=json.dumps({
1166+
"description": audience_group_name,
1167+
"isIfaAudience": is_ifa,
1168+
"audiences": [{"id": audience} for audience in audiences[:10000]],
1169+
}),
1170+
timeout=timeout
1171+
)
1172+
audience_group_id = response.json.get('audienceGroupId')
1173+
if 10000 < len(audiences):
1174+
self.add_audiences_to_audience_group(audience_group_id, audiences[10000:])
1175+
1176+
return audience_group_id
1177+
1178+
def get_audience_group(self, audience_group_id, timeout=None):
1179+
"""Get the object of audience group.
1180+
1181+
https://developers.line.biz/en/reference/messaging-api/#get-audience-group
1182+
1183+
:param str audience_group_id: The audience ID
1184+
:param timeout: (optional) How long to wait for the server
1185+
to send data before giving up, as a float,
1186+
or a (connect timeout, read timeout) float tuple.
1187+
Default is self.http_client.timeout
1188+
:type timeout: float | tuple(float, float)
1189+
:return: AudienceGroup instance
1190+
"""
1191+
response = self._get(
1192+
'/v2/bot/audienceGroup/{audience_group_id}'.format(
1193+
audience_group_id=audience_group_id),
1194+
timeout=timeout
1195+
)
1196+
result = dict(jobs=response.json.get('jobs', []), **response.json.get('audienceGroup', {}))
1197+
return AudienceGroup.new_from_json_dict(result)
1198+
1199+
def get_audience_group_list(self, page=1, description=None, status=None, size=20,
1200+
include_external_public_group=None, create_route=None,
1201+
timeout=None):
1202+
"""Get data for more than one audience.
1203+
1204+
https://developers.line.biz/en/reference/messaging-api/#get-audience-groups
1205+
1206+
:param int page: The page to return when getting (paginated) results. Must be 1 or higher
1207+
:param str description: The name of the audience(s) to return
1208+
:param str status: IN_PROGRESS | READY | FAILED | EXPIRED
1209+
:param int size: The number of audiences per page. Default: 20, Max: 40
1210+
:param bool include_external_public_group: true | false
1211+
:param str create_route: How the audience was created.
1212+
:type create_route: OA_MANAGER | MESSAGING_API
1213+
:return: AudienceGroup instance
1214+
"""
1215+
params = dict([(param, eval(param)) for param in
1216+
['page', 'description', 'status', 'size',
1217+
'includesExternalPublicGroup', 'createRoute']
1218+
if eval(param) is not None])
1219+
response = self._get(
1220+
'/v2/bot/audienceGroup/list?',
1221+
params=params,
1222+
timeout=timeout
1223+
)
1224+
result = []
1225+
for audience_group in response.json.get('audienceGroups', []):
1226+
result.append(AudienceGroup.new_from_json_dict(audience_group))
1227+
if response.json.get('hasNextPage', False):
1228+
result += self.get_audience_group_list(page + 1, description, status, size,
1229+
include_external_public_group,
1230+
create_route, timeout)
1231+
return result
1232+
1233+
def delete_audience_group(self, audience_group_id, timeout=None):
1234+
"""Delete an existing audience.
1235+
1236+
https://developers.line.biz/en/reference/messaging-api/#set-description-audience-group
1237+
1238+
:param str audience_group_id: The audience ID
1239+
:param timeout: (optional) How long to wait for the server
1240+
to send data before giving up, as a float,
1241+
or a (connect timeout, read timeout) float tuple.
1242+
Default is self.http_client.timeout
1243+
:type timeout: float | tuple(float, float)
1244+
"""
1245+
self._delete(
1246+
'/v2/bot/audienceGroup/{}'.format(audience_group_id),
1247+
timeout=timeout
1248+
)
1249+
1250+
def rename_audience_group(self, audience_group_id, audience_group_name, timeout=None):
1251+
"""Modify the name of an existing audience.
1252+
1253+
https://developers.line.biz/en/reference/messaging-api/#set-description-audience-group
1254+
1255+
:param str audience_group_id: The audience ID
1256+
:param str audience_group_name: The new audience's name
1257+
:param timeout: (optional) How long to wait for the server
1258+
to send data before giving up, as a float,
1259+
or a (connect timeout, read timeout) float tuple.
1260+
Default is self.http_client.timeout
1261+
:type timeout: float | tuple(float, float)
1262+
"""
1263+
self._put(
1264+
'/v2/bot/audienceGroup/{}/updateDescription'.format(audience_group_id),
1265+
data=json.dumps({
1266+
"description": audience_group_name,
1267+
}),
1268+
timeout=timeout
1269+
)
1270+
1271+
def add_audiences_to_audience_group(self, audience_group_id, audiences, is_ifa=False,
1272+
upload_description=None, timeout=None):
1273+
"""Add new user IDs or IFAs to an audience for uploading user IDs.
1274+
1275+
https://developers.line.biz/en/reference/messaging-api/#update-upload-audience-group
1276+
1277+
:param str audience_group_id: The audience ID
1278+
:param list audiences: An array of user IDs or IFAs
1279+
:param timeout: (optional) How long to wait for the server
1280+
to send data before giving up, as a float,
1281+
or a (connect timeout, read timeout) float tuple.
1282+
Default is self.http_client.timeout
1283+
:param bool is_ifa: If this is false (default), recipients are specified by user IDs.
1284+
If true, recipients must be specified by IFAs.
1285+
:param str upload_description: The description to register for the job
1286+
:type timeout: float | tuple(float, float)
1287+
"""
1288+
audiences_chunks = [audiences[i:i + 10000] for i in range(0, len(audiences), 10000)]
1289+
for _audiences in audiences_chunks:
1290+
self._put(
1291+
'/v2/bot/audienceGroup/upload',
1292+
data=json.dumps({
1293+
"audienceGroupId": audience_group_id,
1294+
"audiences": [{"id": audience} for audience in _audiences],
1295+
"isIfaAudience": is_ifa,
1296+
"uploadDescription": upload_description,
1297+
}),
1298+
timeout=timeout
1299+
)
1300+
1301+
def get_audience_group_authority_level(self, timeout=None):
1302+
"""Get the authority level of the audience.
1303+
1304+
https://developers.line.biz/en/reference/messaging-api/#get-authority-level
1305+
1306+
:param timeout: (optional) How long to wait for the server
1307+
to send data before giving up, as a float,
1308+
or a (connect timeout, read timeout) float tuple.
1309+
Default is self.http_client.timeout
1310+
:type timeout: float | tuple(float, float)
1311+
:return: json
1312+
"""
1313+
response = self._get(
1314+
'/v2/bot/audienceGroup/authorityLevel',
1315+
timeout=timeout
1316+
)
1317+
1318+
return response.json
1319+
1320+
def change_audience_group_authority_level(self, authority_level='PUBLIC', timeout=None):
1321+
"""Change the authority level of all audiences created in the same channel.
1322+
1323+
https://developers.line.biz/en/reference/messaging-api/#change-authority-level
1324+
1325+
:param str authority_level: PUBLIC | PRIVATE.
1326+
"""
1327+
self._put(
1328+
'/v2/bot/audienceGroup/authorityLevel',
1329+
data=json.dumps({
1330+
"authorityLevel": authority_level,
1331+
}),
1332+
timeout=timeout
1333+
)
1334+
1335+
def create_click_based_audience_group(self, audience_group_name, request_id,
1336+
click_url='', timeout=None):
1337+
"""Create an audience for click-based retargeting.
1338+
1339+
https://developers.line.biz/en/reference/messaging-api/#create-click-audience-group
1340+
1341+
:param str audience_group_name: The audience's name. Audience names must be unique.
1342+
:param str request_id: The request ID of a message sent in the past 60 days.
1343+
:param str click_url: The URL clicked by the user.
1344+
If empty, users who clicked any URL in the message are added to the list of recipients.
1345+
:param timeout: (optional) How long to wait for the server
1346+
to send data before giving up, as a float,
1347+
or a (connect timeout, read timeout) float tuple.
1348+
Default is self.http_client.timeout
1349+
:type timeout: float | tuple(float, float)
1350+
:return: audience group id
1351+
"""
1352+
response = self._post(
1353+
'/v2/bot/audienceGroup/click',
1354+
data=json.dumps({
1355+
"description": audience_group_name,
1356+
"requestId": request_id,
1357+
"clickUrl": click_url,
1358+
}),
1359+
timeout=timeout
1360+
)
1361+
1362+
return response.json.get('audienceGroupId')
1363+
1364+
def create_impression_based_audience_group(self, audience_group_name, request_id,
1365+
timeout=None):
1366+
"""Create an audience for impression-based retargeting.
1367+
1368+
https://developers.line.biz/en/reference/messaging-api/#create-imp-audience-group
1369+
1370+
:param str audience_group_name: The audience's name. Audience names must be unique.
1371+
:param str request_id: The request ID of a message sent in the past 60 days.
1372+
:param timeout: (optional) How long to wait for the server
1373+
to send data before giving up, as a float,
1374+
or a (connect timeout, read timeout) float tuple.
1375+
Default is self.http_client.timeout
1376+
:type timeout: float | tuple(float, float)
1377+
:return: audience group id
1378+
"""
1379+
response = self._post(
1380+
'/v2/bot/audienceGroup/imp',
1381+
data=json.dumps({
1382+
"description": audience_group_name,
1383+
"requestId": request_id,
1384+
}),
1385+
timeout=timeout
1386+
)
1387+
1388+
return response.json.get('audienceGroupId')
1389+
11511390
def set_webhook_endpoint(self, webhook_endpoint, timeout=None):
11521391
"""Set the webhook endpoint URL.
11531392

0 commit comments

Comments
 (0)