├── README.md ├── composer.json ├── composer.lock ├── controller_01.png ├── controller_02.png ├── controller_03.png ├── controller_04.png ├── controller_05.png └── index.php /README.md: -------------------------------------------------------------------------------- 1 | # Demo bot for using rich menus with the Messaging API 2 | 3 | This is a demo bot that demonstrates how you can use the Messaging API to create different rich menus for your bot. Run this bot application to see how the rich menus appear on the LINE app. 4 | 5 | ## Requirements 6 | 7 | To run this bot, you'll need the following. 8 | 9 | - Channel secret and channel access token. (For more information, see the [Getting started with the Messaging API](https://developers.line.me/en/docs/messaging-api/getting-started/) page of the [LINE Developers site](https://developers.line.me/)). 10 | - PHP version 5.6 or higher. 11 | 12 | 13 | ## Reference documentation 14 | 15 | For more information on how to use rich menus with the Messaging API, see the following pages. 16 | 17 | - [Using rich menus](https://developers.line.me/en/docs/messaging-api/using-rich-menus/) 18 | - [Rich menu API reference documentation](https://developers.line.me/en/docs/messaging-api/reference/) 19 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "linecorp/line-bot-sdk": "^2.3" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "1cbb509bc58e72bda4a4f17bb1260cfb", 8 | "packages": [ 9 | { 10 | "name": "linecorp/line-bot-sdk", 11 | "version": "2.3.0", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/line/line-bot-sdk-php.git", 15 | "reference": "38528aaa3a1abc2809974ab65cdcb7579f9eb927" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/line/line-bot-sdk-php/zipball/38528aaa3a1abc2809974ab65cdcb7579f9eb927", 20 | "reference": "38528aaa3a1abc2809974ab65cdcb7579f9eb927", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "php": ">=5.4" 25 | }, 26 | "require-dev": { 27 | "apigen/apigen": "~4.1", 28 | "indigophp/hash-compat": "~1.1.0", 29 | "phpmd/phpmd": "~2.4", 30 | "phpunit/phpunit": "^4.8.24", 31 | "squizlabs/php_codesniffer": "~2.6" 32 | }, 33 | "type": "library", 34 | "autoload": { 35 | "psr-4": { 36 | "LINE\\": "src/" 37 | } 38 | }, 39 | "notification-url": "https://packagist.org/downloads/", 40 | "license": [ 41 | "Apache License Version 2.0" 42 | ], 43 | "authors": [ 44 | { 45 | "name": "moznion", 46 | "email": "moznion@gmail.com" 47 | }, 48 | { 49 | "name": "Satoru Yoshihara", 50 | "email": "vaduz0@gmail.com" 51 | } 52 | ], 53 | "description": "SDK of the LINE BOT API for PHP", 54 | "homepage": "https://github.com/line/line-bot-sdk-php", 55 | "keywords": [ 56 | "bot", 57 | "line", 58 | "sdk" 59 | ], 60 | "time": "2017-09-20T10:22:04+00:00" 61 | } 62 | ], 63 | "packages-dev": [], 64 | "aliases": [], 65 | "minimum-stability": "stable", 66 | "stability-flags": [], 67 | "prefer-stable": false, 68 | "prefer-lowest": false, 69 | "platform": [], 70 | "platform-dev": [] 71 | } 72 | -------------------------------------------------------------------------------- /controller_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/demo-rich-menu-bot/fabbe3a450c7bee4f5c337a16eceb03cd23ad952/controller_01.png -------------------------------------------------------------------------------- /controller_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/demo-rich-menu-bot/fabbe3a450c7bee4f5c337a16eceb03cd23ad952/controller_02.png -------------------------------------------------------------------------------- /controller_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/demo-rich-menu-bot/fabbe3a450c7bee4f5c337a16eceb03cd23ad952/controller_03.png -------------------------------------------------------------------------------- /controller_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/demo-rich-menu-bot/fabbe3a450c7bee4f5c337a16eceb03cd23ad952/controller_04.png -------------------------------------------------------------------------------- /controller_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/line/demo-rich-menu-bot/fabbe3a450c7bee4f5c337a16eceb03cd23ad952/controller_05.png -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | getenv('CHANNEL_SECRET')]); 9 | $signature = $_SERVER['HTTP_' . \LINE\LINEBot\Constant\HTTPHeader::LINE_SIGNATURE]; 10 | 11 | $events = $bot->parseEventRequest(file_get_contents('php://input'), $signature); 12 | foreach ($events as $event) { 13 | 14 | if ($event instanceof \LINE\LINEBot\Event\MessageEvent) { 15 | if($event instanceof \LINE\LINEBot\Event\MessageEvent\TextMessage) { 16 | 17 | if($event->getText() === 'create') { 18 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(createNewRichmenu(getenv('CHANNEL_ACCESS_TOKEN')))); 19 | } 20 | else if($event->getText() === 'list') { 21 | $result = getListOfRichmenu(getenv('CHANNEL_ACCESS_TOKEN')); 22 | 23 | if(isset($result['richmenus']) && count($result['richmenus']) > 0) { 24 | $builders = new \LINE\LINEBot\MessageBuilder\MultiMessageBuilder(); 25 | $columns = Array(); 26 | for($i = 0; $i < count($result['richmenus']); $i++) { 27 | $richmenu = $result['richmenus'][$i]; 28 | $actionArray = array(); 29 | array_push($actionArray, new LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder ( 30 | 'upload image', 'upload::' . $richmenu['richMenuId'])); 31 | array_push($actionArray, new LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder ( 32 | 'delete', 'delete::' . $richmenu['richMenuId'])); 33 | array_push($actionArray, new LINE\LINEBot\TemplateActionBuilder\MessageTemplateActionBuilder ( 34 | 'link', 'link::' . $richmenu['richMenuId'])); 35 | $column = new \LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder ( 36 | null, 37 | $richmenu['richMenuId'], 38 | null, 39 | $actionArray 40 | ); 41 | array_push($columns, $column); 42 | 43 | if($i == 4 || $i == count($result['richmenus']) - 1) { 44 | $builder = new \LINE\LINEBot\MessageBuilder\TemplateMessageBuilder( 45 | 'Richmenu', 46 | new \LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder($columns) 47 | ); 48 | $builders->add($builder); 49 | 50 | unset($columns); 51 | $columns = Array(); 52 | } 53 | } 54 | $bot->replyMessage($event->getReplyToken(), $builders); 55 | } 56 | else { 57 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder('No richmenu.')); 58 | } 59 | } 60 | else if($event->getText() === 'unlink') { 61 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(unlinkFromUser(getenv('CHANNEL_ACCESS_TOKEN'), $event->getUserId()))); 62 | } 63 | else if($event->getText() === 'check') { 64 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(checkRichmenuOfUser(getenv('CHANNEL_ACCESS_TOKEN'), $event->getUserId()))); 65 | } 66 | else if(substr($event->getText(),0, 8) === 'upload::') { 67 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(uploadRandomImageToRichmenu(getenv('CHANNEL_ACCESS_TOKEN'), substr($event->getText(), 8)))); 68 | } 69 | else if(substr($event->getText(),0, 8) === 'delete::') { 70 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(deleteRichmenu(getenv('CHANNEL_ACCESS_TOKEN'), substr($event->getText(), 8)))); 71 | } 72 | else if(substr($event->getText(),0, 6) === 'link::') { 73 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder(linkToUser(getenv('CHANNEL_ACCESS_TOKEN'), $event->getUserId(), substr($event->getText(), 6)))); 74 | } 75 | else { 76 | $bot->replyMessage($event->getReplyToken(),new \LINE\LINEBot\MessageBuilder\TextMessageBuilder( 77 | '"create" - create new Richmenu to channel.' . PHP_EOL . 78 | '"list" - show all Richmenu created via API' . PHP_EOL . 79 | '"list > upload" - upload image to Richmenu. Image choosen randomly' . PHP_EOL . 80 | '"list > delete" - delete Richmenu' . PHP_EOL . 81 | '"list > link" - link Richmenu to user(you)' . PHP_EOL . 82 | '"unlink" - remove link to Richmenu of user(you)' . PHP_EOL . 83 | '"check" - show Richmenu ID linked to user(you)' . PHP_EOL 84 | )); 85 | } 86 | } 87 | } 88 | } 89 | 90 | function createNewRichmenu($channelAccessToken) { 91 | $sh = <<< EOF 92 | curl -X POST \ 93 | -H 'Authorization: Bearer $channelAccessToken' \ 94 | -H 'Content-Type:application/json' \ 95 | -d '{"size": {"width": 2500,"height": 1686},"selected": false,"name": "Controller","chatBarText": "Controller","areas": [{"bounds": {"x": 551,"y": 325,"width": 321,"height": 321},"action": {"type": "message","text": "up"}},{"bounds": {"x": 876,"y": 651,"width": 321,"height": 321},"action": {"type": "message","text": "right"}},{"bounds": {"x": 551,"y": 972,"width": 321,"height": 321},"action": {"type": "message","text": "down"}},{"bounds": {"x": 225,"y": 651,"width": 321,"height": 321},"action": {"type": "message","text": "left"}},{"bounds": {"x": 1433,"y": 657,"width": 367,"height": 367},"action": {"type": "message","text": "btn b"}},{"bounds": {"x": 1907,"y": 657,"width": 367,"height": 367},"action": {"type": "message","text": "btn a"}}]}' https://api.line.me/v2/bot/richmenu; 96 | EOF; 97 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 98 | if(isset($result['richMenuId'])) { 99 | return $result['richMenuId']; 100 | } 101 | else { 102 | return $result['message']; 103 | } 104 | } 105 | 106 | function getListOfRichmenu($channelAccessToken) { 107 | $sh = <<< EOF 108 | curl \ 109 | -H 'Authorization: Bearer $channelAccessToken' \ 110 | https://api.line.me/v2/bot/richmenu/list; 111 | EOF; 112 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 113 | return $result; 114 | } 115 | 116 | function checkRichmenuOfUser($channelAccessToken, $userId) { 117 | $sh = <<< EOF 118 | curl \ 119 | -H 'Authorization: Bearer $channelAccessToken' \ 120 | https://api.line.me/v2/bot/user/$userId/richmenu 121 | EOF; 122 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 123 | if(isset($result['richMenuId'])) { 124 | return $result['richMenuId']; 125 | } 126 | else { 127 | return $result['message']; 128 | } 129 | } 130 | 131 | function unlinkFromUser($channelAccessToken, $userId) { 132 | $sh = <<< EOF 133 | curl -X DELETE \ 134 | -H 'Authorization: Bearer $channelAccessToken' \ 135 | https://api.line.me/v2/bot/user/$userId/richmenu 136 | EOF; 137 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 138 | if(isset($result['message'])) { 139 | return $result['message']; 140 | } 141 | else { 142 | return 'success'; 143 | } 144 | } 145 | 146 | function deleteRichmenu($channelAccessToken, $richmenuId) { 147 | if(!isRichmenuIdValid($richmenuId)) { 148 | return 'invalid richmenu id'; 149 | } 150 | $sh = <<< EOF 151 | curl -X DELETE \ 152 | -H 'Authorization: Bearer $channelAccessToken' \ 153 | https://api.line.me/v2/bot/richmenu/$richmenuId 154 | EOF; 155 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 156 | if(isset($result['message'])) { 157 | return $result['message']; 158 | } 159 | else { 160 | return 'success'; 161 | } 162 | } 163 | 164 | function linkToUser($channelAccessToken, $userId, $richmenuId) { 165 | if(!isRichmenuIdValid($richmenuId)) { 166 | return 'invalid richmenu id'; 167 | } 168 | $sh = <<< EOF 169 | curl -X POST \ 170 | -H 'Authorization: Bearer $channelAccessToken' \ 171 | -H 'Content-Length: 0' \ 172 | https://api.line.me/v2/bot/user/$userId/richmenu/$richmenuId 173 | EOF; 174 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 175 | if(isset($result['message'])) { 176 | return $result['message']; 177 | } 178 | else { 179 | return 'success'; 180 | } 181 | } 182 | 183 | function uploadRandomImageToRichmenu($channelAccessToken, $richmenuId) { 184 | if(!isRichmenuIdValid($richmenuId)) { 185 | return 'invalid richmenu id'; 186 | } 187 | $randomImageIndex = rand(1, 5); 188 | $imagePath = realpath('') . '/' . 'controller_0' . $randomImageIndex . '.png'; 189 | $sh = <<< EOF 190 | curl -X POST \ 191 | -H 'Authorization: Bearer $channelAccessToken' \ 192 | -H 'Content-Type: image/png' \ 193 | -H 'Expect:' \ 194 | -T $imagePath \ 195 | https://api.line.me/v2/bot/richmenu/$richmenuId/content 196 | EOF; 197 | $result = json_decode(shell_exec(str_replace('\\', '', str_replace(PHP_EOL, '', $sh))), true); 198 | if(isset($result['message'])) { 199 | return $result['message']; 200 | } 201 | else { 202 | return 'success. Image #0' . $randomImageIndex . ' has uploaded onto ' . $richmenuId; 203 | } 204 | } 205 | 206 | function isRichmenuIdValid($string) { 207 | if(preg_match('/^[a-zA-Z0-9-]+$/', $string)) { 208 | return true; 209 | } else { 210 | return false; 211 | } 212 | } 213 | 214 | ?> 215 | --------------------------------------------------------------------------------