├── Procfile ├── requirements.txt ├── README.md └── app.py /Procfile: -------------------------------------------------------------------------------- 1 | web: python app.py -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | line-bot-sdk 2 | flask 3 | requests -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## For install Tutorial [HERE](https://www.youtube.com/watch?v=tffqvyI_K3A) 2 | ## Deploy to Heroku 3 | #Ganti token dan chanel screet mu! di file app.py 4 | ```python 5 | # Channel Access Token 6 | line_bot_api = LineBotApi('ISI TOKEN OD KALIAN') 7 | # Channel Secret 8 | handler = WebhookHandler('ISI CHHANEL SCREET') 9 | ``` 10 | 11 | 1. sudo apt-get install heroku 12 | 2. sudo pip install line-bot-sdk 13 | 3. sudo pip install flask 14 | 4. curl https://cli-assets.heroku.com/install-ubuntu.sh | sh 15 | 5. git clone https://github.com/Aditmadzs/oalinebot 16 | 6. EDIT TOKEN + SECRET DULU 17 | 7. Buka folder git kalian 18 | ```shell= 19 | cd oalinebot 20 | ``` 21 | 8. Login Ke Heroku 22 | ```shell= 23 | heroku login 24 | ``` 25 | 9. Buat aplikasi di heroku 26 | ```shell= 27 | heroku apps:create nama 28 | ``` 29 | 10. Git Remote Ke Heroku 30 | ```shell= 31 | heroku git:remote nama 32 | ``` 33 | 11. Init ke git 34 | ```shell= 35 | git init 36 | ``` 37 | 12. Tambahkan git 38 | ```shell 39 | git add . 40 | ``` 41 | 13. Lalu commit 42 | ```shell 43 | git commit -m "Aditmadzs" 44 | ``` 45 | 14. Push ke heroku 46 | ```shell 47 | git push heroku master 48 | ``` 49 | 15. Masukan Webhook URL 50 | ```shell 51 | nama-aplikasi-di-heroku.herokuapp.com/callback 52 | ``` 53 | 16. Tambahkan /callback dibelakang link webhook URL 54 | 55 | 17. Jalankan app.py 56 | ```shell 57 | python3 app.py 58 | ``` 59 | #### TextSendMessage (text pesan) 60 | ```python 61 | message = TextSendMessage(text='Hello, world') 62 | line_bot_api.reply_message(event.reply_token, message) 63 | ``` 64 | #### ImageSendMessage (pesan gambar) 65 | ```python 66 | message = ImageSendMessage( 67 | original_content_url='https://example.com/original.jpg', 68 | preview_image_url='https://example.com/preview.jpg' 69 | ) 70 | line_bot_api.reply_message(event.reply_token, message) 71 | ``` 72 | 73 | #### VideoSendMessage (pesan video) 74 | ```python 75 | message = VideoSendMessage( 76 | original_content_url='https://example.com/original.mp4', 77 | preview_image_url='https://example.com/preview.jpg' 78 | ) 79 | line_bot_api.reply_message(event.reply_token, message) 80 | ``` 81 | 82 | #### AudioSendMessage (Pesan audio) 83 | ```python 84 | message = AudioSendMessage( 85 | original_content_url='https://example.com/original.m4a', 86 | duration=240000 87 | ) 88 | line_bot_api.reply_message(event.reply_token, message) 89 | ``` 90 | #### LocationSendMessage (pesan lokasi) 91 | ```python 92 | message = LocationSendMessage( 93 | title='my location', 94 | address='Tokyo', 95 | latitude=35.65910807942215, 96 | longitude=139.70372892916203 97 | ) 98 | line_bot_api.reply_message(event.reply_token, message) 99 | ``` 100 | 101 | #### StickerSendMessage (Pesan stiker) 102 | ```python 103 | message = StickerSendMessage( 104 | package_id='1', 105 | sticker_id='1' 106 | ) 107 | line_bot_api.reply_message(event.reply_token, message) 108 | ``` 109 | 110 | #### ImagemapSendMessage 111 | ```python 112 | message = ImagemapSendMessage( 113 | base_url='https://example.com/base', 114 | alt_text='this is an imagemap', 115 | base_size=BaseSize(height=1040, width=1040), 116 | actions=[ 117 | URIImagemapAction( 118 | link_uri='https://example.com/', 119 | area=ImagemapArea( 120 | x=0, y=0, width=520, height=1040 121 | ) 122 | ), 123 | MessageImagemapAction( 124 | text='hello', 125 | area=ImagemapArea( 126 | x=520, y=0, width=520, height=1040 127 | ) 128 | ) 129 | ] 130 | ) 131 | line_bot_api.reply_message(event.reply_token, message) 132 | ``` 133 | 134 | #### TemplateSendMessage - ButtonsTemplate (Template) 135 | ```python 136 | message = TemplateSendMessage( 137 | alt_text='Buttons template', 138 | template=ButtonsTemplate( 139 | thumbnail_image_url='https://example.com/image.jpg', 140 | title='Menu', 141 | text='Please select', 142 | actions=[ 143 | PostbackTemplateAction( 144 | label='postback', 145 | text='postback text', 146 | data='action=buy&itemid=1' 147 | ), 148 | MessageTemplateAction( 149 | label='message', 150 | text='message text' 151 | ), 152 | URITemplateAction( 153 | label='uri', 154 | uri='http://example.com/' 155 | ) 156 | ] 157 | ) 158 | ) 159 | line_bot_api.reply_message(event.reply_token, message) 160 | ``` 161 | 162 | #### TemplateSendMessage - ConfirmTemplate 163 | ```python 164 | message = TemplateSendMessage( 165 | alt_text='Confirm template', 166 | template=ConfirmTemplate( 167 | text='Are you sure?', 168 | actions=[ 169 | PostbackTemplateAction( 170 | label='postback', 171 | text='postback text', 172 | data='action=buy&itemid=1' 173 | ), 174 | MessageTemplateAction( 175 | label='message', 176 | text='message text' 177 | ) 178 | ] 179 | ) 180 | ) 181 | line_bot_api.reply_message(event.reply_token, message) 182 | ``` 183 | 184 | #### TemplateSendMessage - CarouselTemplate 185 | ```python 186 | message = TemplateSendMessage( 187 | alt_text='Carousel template', 188 | template=CarouselTemplate( 189 | columns=[ 190 | CarouselColumn( 191 | thumbnail_image_url='https://example.com/item1.jpg', 192 | title='this is menu1', 193 | text='description1', 194 | actions=[ 195 | PostbackTemplateAction( 196 | label='postback1', 197 | text='postback text1', 198 | data='action=buy&itemid=1' 199 | ), 200 | MessageTemplateAction( 201 | label='message1', 202 | text='message text1' 203 | ), 204 | URITemplateAction( 205 | label='uri1', 206 | uri='http://example.com/1' 207 | ) 208 | ] 209 | ), 210 | CarouselColumn( 211 | thumbnail_image_url='https://example.com/item2.jpg', 212 | title='this is menu2', 213 | text='description2', 214 | actions=[ 215 | PostbackTemplateAction( 216 | label='postback2', 217 | text='postback text2', 218 | data='action=buy&itemid=2' 219 | ), 220 | MessageTemplateAction( 221 | label='message2', 222 | text='message text2' 223 | ), 224 | URITemplateAction( 225 | label='uri2', 226 | uri='http://example.com/2' 227 | ) 228 | ] 229 | ) 230 | ] 231 | ) 232 | ) 233 | line_bot_api.reply_message(event.reply_token, message) 234 | ``` 235 | 236 | #### TemplateSendMessage - ImageCarouselTemplate 237 | ```python 238 | message = TemplateSendMessage( 239 | alt_text='ImageCarousel template', 240 | template=ImageCarouselTemplate( 241 | columns=[ 242 | ImageCarouselColumn( 243 | image_url='https://example.com/item1.jpg', 244 | action=PostbackTemplateAction( 245 | label='postback1', 246 | text='postback text1', 247 | data='action=buy&itemid=1' 248 | ) 249 | ), 250 | ImageCarouselColumn( 251 | image_url='https://example.com/item2.jpg', 252 | action=PostbackTemplateAction( 253 | label='postback2', 254 | text='postback text2', 255 | data='action=buy&itemid=2' 256 | ) 257 | ) 258 | ] 259 | ) 260 | ) 261 | line_bot_api.reply_message(event.reply_token, message) 262 | ``` 263 | # Thanks to 264 | - Arsybai 265 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, request, abort 2 | 3 | from linebot import ( 4 | LineBotApi, WebhookHandler 5 | ) 6 | from linebot.exceptions import ( 7 | InvalidSignatureError 8 | ) 9 | from linebot.models import * 10 | import requests, json 11 | 12 | 13 | import errno 14 | import os 15 | import sys, random 16 | import tempfile 17 | 18 | from linebot.models import ( 19 | MessageEvent, TextMessage, TextSendMessage, 20 | SourceUser, SourceGroup, SourceRoom, 21 | TemplateSendMessage, ConfirmTemplate, MessageAction, 22 | ButtonsTemplate, ImageCarouselTemplate, ImageCarouselColumn, URIAction, 23 | PostbackAction, DatetimePickerAction, 24 | CarouselTemplate, CarouselColumn, PostbackEvent, 25 | StickerMessage, StickerSendMessage, LocationMessage, LocationSendMessage, 26 | ImageMessage, VideoMessage, AudioMessage, FileMessage, 27 | UnfollowEvent, FollowEvent, JoinEvent, LeaveEvent, BeaconEvent, 28 | FlexSendMessage, BubbleContainer, ImageComponent, BoxComponent, 29 | TextComponent, SpacerComponent, IconComponent, ButtonComponent, 30 | SeparatorComponent, 31 | ) 32 | 33 | app = Flask(__name__) 34 | 35 | # Channel Access Token 36 | line_bot_api = LineBotApi('ISI TOKEN OA KALIAN') 37 | # Channel Secret 38 | handler = WebhookHandler('ISI CHHANEL SCREET') 39 | #===========[ NOTE SAVER ]======================= 40 | notes = {} 41 | 42 | # Post Request 43 | @app.route("/callback", methods=['POST']) 44 | def callback(): 45 | signature = request.headers['X-Line-Signature'] 46 | body = request.get_data(as_text=True) 47 | app.logger.info("Request body: " + body) 48 | try: 49 | handler.handle(body, signature) 50 | except InvalidSignatureError: 51 | abort(400) 52 | return 'OK' 53 | 54 | @handler.add(MessageEvent, message=TextMessage) 55 | def handle_message(event): 56 | text = event.message.text #simplify for receove message 57 | sender = event.source.user_id #get user_id 58 | gid = event.source.sender_id #get group_id 59 | #=====[ LEAVE GROUP OR ROOM ]========== 60 | if text == 'bye': 61 | if isinstance(event.source, SourceGroup): 62 | line_bot_api.reply_message( 63 | event.reply_token, TextSendMessage(text='Leaving group')) 64 | line_bot_api.leave_group(event.source.group_id) 65 | elif isinstance(event.source, SourceRoom): 66 | line_bot_api.reply_message( 67 | event.reply_token, TextSendMessage(text='Leaving group')) 68 | line_bot_api.leave_room(event.source.room_id) 69 | else: 70 | line_bot_api.reply_message( 71 | event.reply_token, 72 | TextSendMessage(text="Bot can't leave from 1:1 chat")) 73 | #=====[ TEMPLATE MESSAGE ]============= 74 | elif text == '/template': 75 | buttons_template = TemplateSendMessage( 76 | alt_text='template', 77 | template=ButtonsTemplate( 78 | title='[ TEMPLATE MSG ]', 79 | text= 'Tap the Button', 80 | actions=[ 81 | MessageTemplateAction( 82 | label='Culum 1', 83 | text='/aditmadzs' 84 | ), 85 | MessageTemplateAction( 86 | label='CULUM 2', 87 | text='/aditmadzs' 88 | ), 89 | MessageTemplateAction( 90 | label='CULUM 3', 91 | text='/aditmadzs' 92 | ) 93 | ] 94 | ) 95 | ) 96 | 97 | line_bot_api.reply_message(event.reply_token, buttons_template) 98 | #=====[ CAROUSEL MESSAGE ]========== 99 | elif text == '/carousel': 100 | message = TemplateSendMessage( 101 | alt_text='OTHER MENU', 102 | template=CarouselTemplate( 103 | columns=[ 104 | CarouselColumn( 105 | title='ADD ME', 106 | text='Contact Aditmadzs', 107 | actions=[ 108 | URITemplateAction( 109 | label='>TAP HERE<', 110 | uri='https://line.me/ti/p/~adit_cmct' 111 | ) 112 | ] 113 | ), 114 | CarouselColumn( 115 | title='Instagram', 116 | text='FIND ME ON INSTAGRAM', 117 | actions=[ 118 | URITemplateAction( 119 | label='>TAP HERE!<', 120 | uri='http://line.me/ti/p/~adit_cmct' 121 | ) 122 | ] 123 | ) 124 | ] 125 | ) 126 | ) 127 | line_bot_api.reply_message(event.reply_token, message) 128 | #=====[ FLEX MESSAGE ]========== 129 | elif text == 'flex': 130 | bubble = BubbleContainer( 131 | direction='ltr', 132 | hero=ImageComponent( 133 | url='https://lh5.googleusercontent.com/VoOmR6tVRwKEow0HySsJ_UdrQrqrpwUwSzQnGa0yBeqSex-4Osar2w-JohT6yPu4Vl4qchND78aU2c5a5Bhl=w1366-h641-rw', 134 | size='full', 135 | aspect_ratio='20:13', 136 | aspect_mode='cover', 137 | action=URIAction(uri='http://line.me/ti/p/~adit_cmct', label='label') 138 | ), 139 | body=BoxComponent( 140 | layout='vertical', 141 | contents=[ 142 | # title 143 | TextComponent(text='Aditmadzs', weight='bold', size='xl'), 144 | # review 145 | BoxComponent( 146 | layout='baseline', 147 | margin='md', 148 | contents=[ 149 | IconComponent(size='sm', url='https://example.com/gold_star.png'), 150 | IconComponent(size='sm', url='https://example.com/grey_star.png'), 151 | IconComponent(size='sm', url='https://example.com/gold_star.png'), 152 | IconComponent(size='sm', url='https://example.com/gold_star.png'), 153 | IconComponent(size='sm', url='https://example.com/grey_star.png'), 154 | TextComponent(text='4.0', size='sm', color='#999999', margin='md', 155 | flex=0) 156 | ] 157 | ), 158 | # info 159 | BoxComponent( 160 | layout='vertical', 161 | margin='lg', 162 | spacing='sm', 163 | contents=[ 164 | BoxComponent( 165 | layout='baseline', 166 | spacing='sm', 167 | contents=[ 168 | TextComponent( 169 | text='Place', 170 | color='#aaaaaa', 171 | size='sm', 172 | flex=1 173 | ), 174 | TextComponent( 175 | text='Tangerang, Indonesia', 176 | wrap=True, 177 | color='#666666', 178 | size='sm', 179 | flex=5 180 | ) 181 | ], 182 | ), 183 | BoxComponent( 184 | layout='baseline', 185 | spacing='sm', 186 | contents=[ 187 | TextComponent( 188 | text='Time', 189 | color='#aaaaaa', 190 | size='sm', 191 | flex=1 192 | ), 193 | TextComponent( 194 | text="10:00 - 23:00", 195 | wrap=True, 196 | color='#666666', 197 | size='sm', 198 | flex=5, 199 | ), 200 | ], 201 | ), 202 | ], 203 | ) 204 | ], 205 | ), 206 | footer=BoxComponent( 207 | layout='vertical', 208 | spacing='sm', 209 | contents=[ 210 | # separator 211 | SeparatorComponent(), 212 | # websiteAction 213 | ButtonComponent( 214 | style='link', 215 | height='sm', 216 | action=URIAction(label='Aditmadzs', uri="https://line.me/ti/p/~adit_cmct") 217 | ) 218 | ] 219 | ), 220 | ) 221 | message = FlexSendMessage(alt_text="hello", contents=bubble) 222 | line_bot_api.reply_message( 223 | event.reply_token, 224 | message 225 | ) 226 | #======================================================================================================================= 227 | import os 228 | if __name__ == "__main__": 229 | port = int(os.environ.get('PORT', 5000)) 230 | app.run(host='0.0.0.0', port=port) 231 | --------------------------------------------------------------------------------