iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0

昨天我們完成了組成一個Bubble需要的4個區塊,今天我們透過這4個區塊把Bubble組起來,然後再用Bubble把Carousel組合起來,就可以回傳給Drive Service使用了。

  1. 首先,我們假設最小製作的單位就是Bubble,也就是一開始資料會從Bubble做輸入,那我們就可以寫一個newFolderBubble()以及定義輸入資料的NewFolderBubbleParam

    newFolderBubble()中,我們先宣告一個allFlexComponents,把4個區塊拿到的linebot.FlexComponent在這裡一一展開組合進allFlexComponents,然後塞進BubbleContainerContents裡回傳。

    // internal\domain\drive\flex.go
    type NewFolderBubbleParam struct {
    	Type          string
    	Name          string
    	Path          string
    	ID            string
    	InsideFolderM map[string]string
    	FileM         map[string]string
    }
    
    func newFolderBubble(param NewFolderBubbleParam) *linebot.BubbleContainer {
    	var allFlexComponents []linebot.FlexComponent
    
    	title := folderTitleFlexComponents(param.Type, param.Name, param.Path)
    	allFlexComponents = append(allFlexComponents, title...)
    
    	folder := folderFlexComponents(param.InsideFolderM)
    	allFlexComponents = append(allFlexComponents, folder...)
    
    	file := fileFlexComponents(param.FileM)
    	allFlexComponents = append(allFlexComponents, file...)
    
    	button := buttonFlexComponents(param.ID)
    	allFlexComponents = append(allFlexComponents, button...)
    
    	// Single Bubble
    	bubble := linebot.BubbleContainer{
    		Type: linebot.FlexContainerTypeBubble,
    		Body: &linebot.BoxComponent{
    			Type:   linebot.FlexComponentTypeBox,
    			Layout: linebot.FlexBoxLayoutTypeVertical,
    			// Insert Components
    			Contents: allFlexComponents,
    		},
    		Styles: &linebot.BubbleStyle{
    			Footer: &linebot.BlockStyle{
    				Separator: true,
    			},
    		},
    	}
    
    	return &bubble
    }
    
  2. 接著,有了Bubble之後就可以來組Carousel了。
    我們先定義一個對外的NewFolderCarousel(),會回傳我們定義的FolderCarousel,裡面存放linebot最終需要的CarouselContainer,然後NewFolderCarouselParam做為外部輸入的參數,要提供[]NewFolderBubbleParam

    NewFolderCarousel()會根據有多少個NewFolderBubbleParam被傳進來,調用newFolderBubble製作對應的Bubble,最後組合成FolderCarousel後回傳。

    // internal\domain\drive\flex.go
    type FolderCarousel struct {
    	CarouselContainer *linebot.CarouselContainer
    }
    type NewFolderCarouselParam struct {
    	BubbleParams []NewFolderBubbleParam
    }
    
    func NewFolderCarousel(carouselParams NewFolderCarouselParam) FolderCarousel {
    	var bubbles []*linebot.BubbleContainer
    	for _, v := range carouselParams.BubbleParams {
    		bubble := newFolderBubble(v)
    		bubbles = append(bubbles, bubble)
    	}
    
    	return FolderCarousel{
    		CarouselContainer: &linebot.CarouselContainer{
    			Type: linebot.FlexContainerTypeCarousel,
    			// Insert bubbles
    			Contents: bubbles,
    		},
    	}
    }
    
  3. 接著我們回Service層,寫一個TestFolderCarousel來調用domainDrive.NewFolderCarousel組出我們的Carousel,首先寫定義兩個map,分別代表資料夾內的子資料夾和檔案,接著我們填充params.BubbleParams把每一個Bubble要顯示的參數代入,最後把*domainDrive.FolderCarousel回傳出去。

    P.S. 不在這邊回傳*linebotXXX這種類型,是為了保持Service層的乾淨,讓Service層只會去碰到Domain跟Adapter。

    // internal\app\service\drive\drive_service.go
    func (dr *GoogleDriveService) TestFolderCarousel(ctx context.Context, lineID string) (*domainDrive.FolderCarousel, error) {
    	insideFolderM := map[string]string{
    		"001": "F1",
    		"002": "F2",
    	}
    	fileM := map[string]string{
    		"001": "file1",
    		"002": "file2",
    	}
    
    	var params domainDrive.NewFolderCarouselParam
    	params.BubbleParams = append(params.BubbleParams,
    		domainDrive.NewFolderBubbleParam{
    			Type:          "我的雲端硬碟",
    			Name:          "Folder1",
    			Path:          "/xx/xx",
    			ID:            "123",
    			InsideFolderM: insideFolderM,
    			FileM:         fileM,
    		},
    		domainDrive.NewFolderBubbleParam{
    			Type:          "我的雲端硬碟",
    			Name:          "Folder2",
    			Path:          "/yy/yy",
    			ID:            "1234",
    			InsideFolderM: insideFolderM,
    			FileM:         fileM,
    		},
    	)
    	carousel := domainDrive.NewFolderCarousel(params)
    	return &carousel, nil
    }
    
  4. 最後我們去Callback()來測試一下效果,從res取出CarouselContainer放入NewFlexMessage中。

    //internal\router\api\v1\callback.go
    if message.Text == "test" {
    		lineID := event.Source.UserID
    		res, err := app.DriveService.TestFolderCarousel(ctx, lineID)
    		if err != nil {
    			log.Println(err)
    			return
    		}
    		if _, err := app.LineBotClient.ReplyMessage(
    			event.ReplyToken,
    			linebot.NewFlexMessage("測試Flex Carousel", res.CarouselContainer),
    		).Do(); err != nil {
    			log.Println(err)
    			return
    		}
    }
    

    https://ithelp.ithome.com.tw/upload/images/20231013/20115990KcJcUJx5Ko.png

可以看到,我們已經能依照我們給定的資料去動態組合出需要的Carousel,這樣Flex Message的部分就沒問題了。

那我們今天就先到這裡,明天我們只要把資料一一替換成從GoogleDrive取得的就沒問題了,那我們明天見囉。


上一篇
Day27 用Go動態組合Flex Message 01
下一篇
Day29 Drive Service - 用Google Drive API取資料建立Carousel
系列文
Golang LineBot X GoogleDrive:LINE有各種限制!? 那就丟上Drive吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言