跳至主要内容

REFERENCE

SDK 範例

@asgard-js/core 與 @asgard-js/react 的用法與可以直接操作的範例。

組合式訊息原語

自訂渲染器讓你完全接管一則訊息怎麼畫。但多數情況下你想換的只是 內容,不是版面——滿寬的 bot 文字、靠右的 user 泡泡、快速回覆與訊息操作列的位置,這些都應該 照舊。

為此 SDK 把組成預設訊息列的原語都外露了,你可以直接拿來組。

  1. 原語一覽​

    原語作用
    TemplateBox訊息列的外框,決定對齊與方向(type: 'user' | 'bot')
    TemplateBoxContentbot 列的內容容器,負責快速回覆與訊息操作
    BotMessageTextbot 的文字本體,含 Markdown 渲染與主題色
    UserMessageTextuser 的文字泡泡
    Time已棄用,什麼都不畫(見下方)
  2. 用法​

    搭配 renderMessageContent,沒命中的訊息呼叫 renderDefaultContent() 回退預設:

    import {
    TemplateBox,
    TemplateBoxContent,
    BotMessageText,
    UserMessageText,
    } from "@asgard-js/react";
    import { MessageTemplateType } from "@asgard-js/core";

    <Chatbot
    renderMessageContent={({ message, renderDefaultContent }) => {
    // user 列:把開頭的提及字串換成 chip,其餘照舊
    if (message.type === "user" && message.text.startsWith(MENTION)) {
    return (
    <TemplateBox type="user" direction="horizontal">
    <UserMessageText>
    <span className="mention-chip">{MENTION}</span>
    {message.text.slice(MENTION.length)}
    </UserMessageText>
    </TemplateBox>
    );
    }

    // bot 文字列
    if (message.type === "bot") {
    const template = message.message?.template;
    const isText = template?.type === MessageTemplateType.TEXT || !template?.type;
    const text = message.isTyping ? message.typingText : message.message?.text;

    if (isText && text) {
    return (
    <TemplateBox type="bot" direction="horizontal">
    <TemplateBoxContent
    message={message}
    quickReplies={template?.quickReplies}
    references={template?.references}
    >
    <BotMessageText>{text}</BotMessageText>
    </TemplateBoxContent>
    </TemplateBox>
    );
    }
    }

    return renderDefaultContent();
    }}
    />
  3. 串流中的文字​

    message.isTyping 為真時要讀 message.typingText 而不是 message.message.text—— 後者要等訊息完成才有值。上面的範例已經處理了這件事。

  4. 為什麼不直接自己刻​

    自己刻的話,這些會跟著跑掉,而且會在 SDK 改版時繼續跑掉:

    • bot 文字是滿寬無泡泡的,user 才是泡泡——兩者版面規則不同
    • TemplateBoxContent 順帶處理快速回覆與訊息操作列的位置
    • 對齊、方向、主題色都綁在 TemplateBox 上,不是散在各處

    換句話說:換內容,不換版面。

  5. Time 已經不畫東西了​

    聊天介面任何地方都不再顯示訊息時間戳。<Time /> 保留為 no-op、TimeProps 的欄位全部忽略, 只是為了讓既有呼叫端繼續編譯得過;方便的時候把它刪掉即可。

    它原本畫的值從來就不是訊息自己的時間:SDK 是在每一幀抵達時蓋上 new Date(),而重新連線的 GET 會把整段歷史一次重播,於是每一則被重播的訊息都被重新蓋上「頁面打開的那一刻」。後端沒有 per-message 的時間戳可以拿來取代它。

    同理,ConversationMessage 上的 time 欄位也標為棄用——SDK 沒有任何地方會渲染它。

  6. ChatHeader​

    同樣的想法也適用於標題列。ChatHeader 已外露,可搭配 renderHeader 使用;若只想換標題區 而保留其餘結構,用 renderTitle 即可。詳見自訂 Header。

  7. 也看看​

準備好開始了嗎?

想知道 Asgard 怎麼用在你的團隊?跟我們聊聊。

聯絡我們