Skip to content

Commit c04acf0

Browse files
Refactor BMS models and add new examples
- Removed unused development requirements from `uv.lock`. - Introduced new example scripts for various BMS message types, including carousel commerce, carousel feed, and commerce messages. - Added validation for required fields in BMS models to enhance error handling. - Updated imports in BMS module to include new validation functions. - Improved documentation in example scripts for better clarity on usage.
1 parent bee47b7 commit c04acf0

14 files changed

+883
-66
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
"""
2+
카카오 BMS 자유형 CAROUSEL_COMMERCE 타입 발송 예제
3+
캐러셀 커머스 형식으로, 여러 상품을 슬라이드로 보여주는 구조입니다.
4+
이미지 업로드 시 fileType은 'BMS_CAROUSEL_COMMERCE_LIST'를 사용해야 합니다. (2:1 비율 이미지 필수)
5+
head + list(상품카드들) + tail 구조입니다.
6+
head 없이 2-6개 아이템, head 포함 시 1-5개 아이템 가능합니다.
7+
가격 정보(regularPrice, discountPrice, discountRate, discountFixed)는 숫자 타입입니다.
8+
캐러셀 커머스 버튼은 WL, AL 타입만 지원합니다.
9+
쿠폰 제목 형식: "N원 할인 쿠폰", "N% 할인 쿠폰", "배송비 할인 쿠폰", "OOO 무료 쿠폰", "OOO UP 쿠폰"
10+
발신번호, 수신번호에 반드시 -, * 등 특수문자를 제거하여 기입하시기 바랍니다. 예) 01012345678
11+
"""
12+
13+
from os.path import abspath
14+
15+
from solapi import SolapiMessageService
16+
from solapi.model import Bms, KakaoOption, RequestMessage
17+
from solapi.model.kakao.bms import (
18+
BmsAppButton,
19+
BmsCarouselCommerceItem,
20+
BmsCarouselCommerceSchema,
21+
BmsCarouselHead,
22+
BmsCarouselTail,
23+
BmsCommerce,
24+
BmsCoupon,
25+
BmsWebButton,
26+
)
27+
from solapi.model.message_type import MessageType
28+
from solapi.model.request.storage import FileTypeEnum
29+
30+
message_service = SolapiMessageService(
31+
api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET"
32+
)
33+
34+
try:
35+
file_response = message_service.upload_file(
36+
file_path=abspath("../images/example_wide.jpg"),
37+
upload_type=FileTypeEnum.BMS_CAROUSEL_COMMERCE_LIST,
38+
)
39+
image_id = file_response.file_id
40+
print(f"파일 업로드 성공! File ID: {image_id}")
41+
42+
message = RequestMessage(
43+
from_="발신번호",
44+
to="수신번호",
45+
type=MessageType.BMS_FREE,
46+
kakao_options=KakaoOption(
47+
pf_id="연동한 비즈니스 채널의 pfId",
48+
bms=Bms(
49+
targeting="I",
50+
chat_bubble_type="CAROUSEL_COMMERCE",
51+
adult=False,
52+
additional_content="🔥 이번 주 한정 특가!",
53+
carousel=BmsCarouselCommerceSchema(
54+
head=BmsCarouselHead(
55+
header="홍길동님을 위한 추천",
56+
content="최근 관심 상품과 비슷한 아이템을 모았어요!",
57+
image_id=image_id,
58+
link_mobile="https://example.com/recommend",
59+
),
60+
items=[
61+
BmsCarouselCommerceItem(
62+
image_id=image_id,
63+
commerce=BmsCommerce(
64+
title="에어프라이어 대용량 5.5L",
65+
regular_price=159000,
66+
discount_price=119000,
67+
discount_rate=25,
68+
),
69+
additional_content="⚡ 무료배송",
70+
image_link="https://example.com/airfryer",
71+
buttons=[
72+
BmsWebButton(
73+
name="지금 구매",
74+
link_mobile="https://example.com",
75+
link_pc="https://example.com",
76+
),
77+
BmsAppButton(
78+
name="앱에서 보기",
79+
link_mobile="https://example.com",
80+
link_android="examplescheme://path",
81+
link_ios="examplescheme://path",
82+
),
83+
],
84+
coupon=BmsCoupon(
85+
title="10000원 할인 쿠폰",
86+
description="첫 구매 고객 전용 쿠폰입니다.",
87+
link_mobile="https://example.com/coupon",
88+
),
89+
),
90+
BmsCarouselCommerceItem(
91+
image_id=image_id,
92+
commerce=BmsCommerce(
93+
title="스마트 로봇청소기 프로",
94+
regular_price=499000,
95+
discount_price=399000,
96+
discount_fixed=100000,
97+
),
98+
buttons=[
99+
BmsWebButton(
100+
name="상세 보기",
101+
link_mobile="https://example.com",
102+
link_pc="https://example.com",
103+
),
104+
],
105+
),
106+
],
107+
tail=BmsCarouselTail(
108+
link_mobile="https://example.com/all-products",
109+
),
110+
),
111+
),
112+
),
113+
)
114+
115+
response = message_service.send(message)
116+
print("메시지 발송 성공!")
117+
print(f"Group ID: {response.group_info.group_id}")
118+
print(f"요청한 메시지 개수: {response.group_info.count.total}")
119+
print(f"성공한 메시지 개수: {response.group_info.count.registered_success}")
120+
except Exception as e:
121+
print(f"발송 실패: {str(e)}")
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""
2+
카카오 BMS 자유형 CAROUSEL_FEED 타입 발송 예제
3+
캐러셀 피드 형식으로, 여러 카드를 좌우로 슬라이드하는 구조입니다.
4+
이미지 업로드 시 fileType은 'BMS_CAROUSEL_FEED_LIST'를 사용해야 합니다. (2:1 비율 이미지 필수)
5+
head 없이 2-6개 아이템, head 포함 시 1-5개 아이템 가능합니다.
6+
캐러셀 피드 버튼은 WL, AL 타입만 지원합니다.
7+
쿠폰 제목 형식: "N원 할인 쿠폰", "N% 할인 쿠폰", "배송비 할인 쿠폰", "OOO 무료 쿠폰", "OOO UP 쿠폰"
8+
발신번호, 수신번호에 반드시 -, * 등 특수문자를 제거하여 기입하시기 바랍니다. 예) 01012345678
9+
"""
10+
11+
from os.path import abspath
12+
13+
from solapi import SolapiMessageService
14+
from solapi.model import Bms, KakaoOption, RequestMessage
15+
from solapi.model.kakao.bms import (
16+
BmsAppButton,
17+
BmsCarouselFeedItem,
18+
BmsCarouselFeedSchema,
19+
BmsCarouselTail,
20+
BmsCoupon,
21+
BmsWebButton,
22+
)
23+
from solapi.model.message_type import MessageType
24+
from solapi.model.request.storage import FileTypeEnum
25+
26+
message_service = SolapiMessageService(
27+
api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET"
28+
)
29+
30+
try:
31+
file_response = message_service.upload_file(
32+
file_path=abspath("../images/example_wide.jpg"),
33+
upload_type=FileTypeEnum.BMS_CAROUSEL_FEED_LIST,
34+
)
35+
image_id = file_response.file_id
36+
print(f"파일 업로드 성공! File ID: {image_id}")
37+
38+
message = RequestMessage(
39+
from_="발신번호",
40+
to="수신번호",
41+
type=MessageType.BMS_FREE,
42+
kakao_options=KakaoOption(
43+
pf_id="연동한 비즈니스 채널의 pfId",
44+
bms=Bms(
45+
targeting="I",
46+
chat_bubble_type="CAROUSEL_FEED",
47+
adult=False,
48+
carousel=BmsCarouselFeedSchema(
49+
items=[
50+
BmsCarouselFeedItem(
51+
header="🏃 마라톤 완주 도전!",
52+
content="첫 마라톤 완주를 목표로 8주 트레이닝 프로그램을 시작해보세요.",
53+
image_id=image_id,
54+
image_link="https://example.com/marathon",
55+
buttons=[
56+
BmsWebButton(
57+
name="프로그램 신청",
58+
link_mobile="https://example.com",
59+
link_pc="https://example.com",
60+
),
61+
BmsAppButton(
62+
name="앱에서 보기",
63+
link_mobile="https://example.com",
64+
link_android="examplescheme://path",
65+
link_ios="examplescheme://path",
66+
),
67+
],
68+
coupon=BmsCoupon(
69+
title="10% 할인 쿠폰",
70+
description="첫 등록 고객 전용 할인 쿠폰입니다.",
71+
link_mobile="https://example.com/coupon",
72+
),
73+
),
74+
BmsCarouselFeedItem(
75+
header="🧘 요가 입문 클래스",
76+
content="초보자를 위한 기초 요가 동작을 배워보세요. 유연성과 마음의 평화를 함께!",
77+
image_id=image_id,
78+
buttons=[
79+
BmsWebButton(
80+
name="클래스 보기",
81+
link_mobile="https://example.com",
82+
link_pc="https://example.com",
83+
),
84+
],
85+
),
86+
BmsCarouselFeedItem(
87+
header="💪 홈트레이닝 루틴",
88+
content="장비 없이도 OK! 집에서 하는 30분 전신 운동 루틴.",
89+
image_id=image_id,
90+
buttons=[
91+
BmsAppButton(
92+
name="영상 시청",
93+
link_mobile="https://example.com",
94+
link_android="examplescheme://path",
95+
link_ios="examplescheme://path",
96+
),
97+
],
98+
),
99+
],
100+
tail=BmsCarouselTail(
101+
link_mobile="https://example.com/more",
102+
link_pc="https://example.com/more",
103+
),
104+
),
105+
),
106+
),
107+
)
108+
109+
response = message_service.send(message)
110+
print("메시지 발송 성공!")
111+
print(f"Group ID: {response.group_info.group_id}")
112+
print(f"요청한 메시지 개수: {response.group_info.count.total}")
113+
print(f"성공한 메시지 개수: {response.group_info.count.registered_success}")
114+
except Exception as e:
115+
print(f"발송 실패: {str(e)}")
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
"""
2+
카카오 BMS 자유형 COMMERCE 타입 발송 예제
3+
커머스(상품) 메시지로, 상품 이미지와 가격 정보, 쿠폰을 포함합니다.
4+
이미지 업로드 시 fileType은 'BMS'를 사용해야 합니다. (2:1 비율 이미지 권장)
5+
COMMERCE 타입은 buttons가 필수입니다 (최소 1개).
6+
가격 정보(regularPrice, discountPrice, discountRate, discountFixed)는 숫자 타입입니다.
7+
쿠폰 제목 형식: "N원 할인 쿠폰", "N% 할인 쿠폰", "배송비 할인 쿠폰", "OOO 무료 쿠폰", "OOO UP 쿠폰"
8+
발신번호, 수신번호에 반드시 -, * 등 특수문자를 제거하여 기입하시기 바랍니다. 예) 01012345678
9+
"""
10+
11+
from os.path import abspath
12+
13+
from solapi import SolapiMessageService
14+
from solapi.model import Bms, KakaoOption, RequestMessage
15+
from solapi.model.kakao.bms import (
16+
BmsAppButton,
17+
BmsCommerce,
18+
BmsCoupon,
19+
BmsWebButton,
20+
)
21+
from solapi.model.message_type import MessageType
22+
from solapi.model.request.storage import FileTypeEnum
23+
24+
message_service = SolapiMessageService(
25+
api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET"
26+
)
27+
28+
try:
29+
file_response = message_service.upload_file(
30+
file_path=abspath("../images/example_wide.jpg"),
31+
upload_type=FileTypeEnum.BMS,
32+
)
33+
print(f"파일 업로드 성공! File ID: {file_response.file_id}")
34+
35+
message = RequestMessage(
36+
from_="발신번호",
37+
to="수신번호",
38+
type=MessageType.BMS_FREE,
39+
kakao_options=KakaoOption(
40+
pf_id="연동한 비즈니스 채널의 pfId",
41+
bms=Bms(
42+
targeting="I",
43+
chat_bubble_type="COMMERCE",
44+
adult=False,
45+
additional_content="🚀 오늘 주문 시 내일 도착! 무료배송",
46+
image_id=file_response.file_id,
47+
commerce=BmsCommerce(
48+
title="스마트 공기청정기 2024 신형",
49+
regular_price=299000,
50+
discount_price=209000,
51+
discount_rate=30,
52+
),
53+
buttons=[
54+
BmsWebButton(
55+
name="지금 구매하기",
56+
link_mobile="https://example.com",
57+
link_pc="https://example.com",
58+
),
59+
BmsAppButton(
60+
name="앱에서 보기",
61+
link_mobile="https://example.com",
62+
link_android="examplescheme://path",
63+
link_ios="examplescheme://path",
64+
),
65+
],
66+
coupon=BmsCoupon(
67+
title="포인트 UP 쿠폰",
68+
description="구매 시 2배 적립 쿠폰입니다.",
69+
link_mobile="https://example.com/coupon",
70+
),
71+
),
72+
),
73+
)
74+
75+
response = message_service.send(message)
76+
print("메시지 발송 성공!")
77+
print(f"Group ID: {response.group_info.group_id}")
78+
print(f"요청한 메시지 개수: {response.group_info.count.total}")
79+
print(f"성공한 메시지 개수: {response.group_info.count.registered_success}")
80+
except Exception as e:
81+
print(f"발송 실패: {str(e)}")
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
"""
2+
카카오 BMS 자유형 IMAGE 타입 발송 예제
3+
이미지 업로드 후 imageId를 사용하여 발송합니다.
4+
이미지 업로드 시 fileType은 반드시 'BMS'를 사용해야 합니다.
5+
발신번호, 수신번호에 반드시 -, * 등 특수문자를 제거하여 기입하시기 바랍니다. 예) 01012345678
6+
"""
7+
8+
from os.path import abspath
9+
10+
from solapi import SolapiMessageService
11+
from solapi.model import Bms, KakaoOption, RequestMessage
12+
from solapi.model.message_type import MessageType
13+
from solapi.model.request.storage import FileTypeEnum
14+
15+
message_service = SolapiMessageService(
16+
api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET"
17+
)
18+
19+
try:
20+
file_response = message_service.upload_file(
21+
file_path=abspath("../images/example.jpg"),
22+
upload_type=FileTypeEnum.BMS,
23+
)
24+
print(f"파일 업로드 성공! File ID: {file_response.file_id}")
25+
26+
message = RequestMessage(
27+
from_="발신번호",
28+
to="수신번호",
29+
text="🆕 신상품이 입고되었어요!\n지금 바로 확인해보세요.",
30+
type=MessageType.BMS_FREE,
31+
kakao_options=KakaoOption(
32+
pf_id="연동한 비즈니스 채널의 pfId",
33+
bms=Bms(
34+
targeting="I",
35+
chat_bubble_type="IMAGE",
36+
image_id=file_response.file_id,
37+
),
38+
),
39+
)
40+
41+
response = message_service.send(message)
42+
print("메시지 발송 성공!")
43+
print(f"Group ID: {response.group_info.group_id}")
44+
print(f"요청한 메시지 개수: {response.group_info.count.total}")
45+
print(f"성공한 메시지 개수: {response.group_info.count.registered_success}")
46+
except Exception as e:
47+
print(f"발송 실패: {str(e)}")

0 commit comments

Comments
 (0)