Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Friends get Friends Campaign LIFF Share Target Picker

Friends get Friends Campaign LIFF Share Target Picker

LINE Developers Thailand

September 02, 2022
Tweet

More Decks by LINE Developers Thailand

Other Decks in Technology

Transcript

  1. Friends get Friends Campaign
    LIFF Share Target Picker

    View Slide

  2. Atchariya Darote


    CEO AIYA


    LINE Certified Coach for API 2022
    Friends get Friends
    Campaign LIFF Share
    Target Picker

    View Slide

  3. • Friends get Friends Campaign Overview


    • LINE Front-end Framework (LIFF) Kick-off


    • LIFF Share Target Picker Insight


    • Scale up on Production
    Agenda

    View Slide

  4. Friends get Friends Campaign
    Overview

    View Slide

  5. Our Challenge
    How to increase


    the number of registration?

    View Slide

  6. Our Challenges
    ● Accessibility
    ● Traceability
    ● Compatibility

    View Slide

  7. 50 Million
    LINE User


    Access (every day)

    View Slide

  8. Friends get Friends LINE Journey
    Registration Invite to join
    Campaign Landing
    LIFF Share Target Picker Send Flex Message

    View Slide

  9. Friends get Friends Social Journey
    แช
    ร์ ลิ

    ค์
    ชวนเ
    พื ่
    อน
    คั
    ดลอก
    ลิ

    ค์
    รอง
    รั
    บโซเ
    ซี
    ยล
    อื่
    น Registration

    View Slide

  10. Default RichMenu RichMenu after join campaign
    Personalized RichMenu

    View Slide

  11. Friends get Friends Campaign
    Demonstration

    View Slide

  12. View Slide

  13. ● Share campaign via LINE
    ● Collect point
    ● Other social platforms

    compatibility
    Features

    View Slide

  14. Campaign Performance
    120%

    View Slide

  15. How we made the solution?
    Tech Stack
    Cloudfront
    Amazon
    S3
    Amazon

    View Slide

  16. LINE Front-end Framework (LIFF)


    View Slide

  17. https://liff-playground.netlify.app/
    LIFF Playground

    View Slide

  18. LIFF Starter CLI
    https://github.com/line/create-liff-app

    View Slide

  19. // Execute liff.init() when the app is initialized


    useEffect(() => {


    // to avoid `window is not defined` error


    import("@line/liff").then((liff) => {


    console.log("start liff.init()...");


    liff


    .init({ liffId: process.env.LIFF_ID })


    .then(() => {


    console.log("liff.init() done");


    setLiffObject(liff);


    })


    .catch((error) => {


    console.log(`liff.init() failed: ${error}`);


    if (!process.env.liffId) {


    console.info(


    "LIFF Starter: Please make sure that you provided `LIFF_ID` as an environmental variable."


    );


    }


    setLiffError(error.toString());


    });


    });


    }, []);


    Import LIFF SDK in NextJS
    https://github.com/line/line-liff-v2-starter/blob/master/src/nextjs/pages/_app.js

    View Slide

  20. What’s LIFF Share Target Picker?

    View Slide

  21. liff.shareTargetPicker([


    {


    type: 'text',


    text: 'Hello, World!',


    },


    ]);
    Sending messages to a user's friend
    Double-click to edit

    View Slide

  22. if (liff.isApiAvailable('shareTargetPicker')) {


    liff.shareTargetPicker([


    {


    type: 'text',


    text: 'Hello, World!',


    },


    ]);


    }
    Is LIFF Share Target Picker available?
    Target picker is supported on 10.3.0 or later for both LINE for iOS and LINE for Android.

    View Slide

  23. Enable LIFF Share Target Picker
    https://developers.line.biz/console/

    View Slide

  24. LIFF Share Target Picker Syntax
    Ref: https://developers.line.biz/en/reference/liff/#share-target-picker
    liff.shareTargetPicker(messages, options);
    liff.shareTargetPicker(


    [


    {


    type: "text",


    text: "Hello, World!",


    },


    ],


    {


    isMultiple: true,


    }


    )


    .then(function (res) {


    if (res) {


    // succeeded in sending a message through TargetPicker


    console.log(`[${res.status}] Message sent!`)


    }


    }).catch(function (error) {


    // something went wrong before sending a message


    console.log('something wrong happen')


    })
    5 Bubbles

    View Slide

  25. Types of Messaging API messages
    Image
    Video
    Audio
    Location
    Audio
    Video
    Text
    basic message type

    View Slide

  26. Template messages
    Only a URI action can be set as an action
    Button Carousel Image Carousel

    View Slide

  27. Flex Message
    Only a URI action can be set as an action

    View Slide

  28. LIFF Share Target Picker Policy
    Unknown friend’s profile
    Unknown number

    View Slide

  29. How to retrieve share statistic?

    View Slide

  30. const liffId = "LIFF_ID"


    await liff.init({ liffId })


    await liff.ready


    if (!liff.isLoggedIn()) {


    liff.login({ redirectUri: "https://example.com/path" });


    } else {


    const idToken = liff.getDecodedIDToken();


    const profile = {


    userId: idToken?.sub,


    displayName: idToken?.name,


    pictureUrl: idToken?.picture,


    };


    ...


    }


    LINE Login
    https://developers.line.biz/en/reference/liff/#login

    View Slide

  31. {


    "iss": "https://access.line.me",


    "sub": "U1234567890abcdef1234567890abcdef",


    "aud": "1234567890",


    "exp": 1504169092,


    "iat": 1504263657,


    "amr": ["pwd"],


    "name": "Taro Line",


    "picture": "https://sample_line.me/aBcdefg123456"


    }


    liff.getDecodedIDToken()
    EXAMPLE DECODED ID TOKEN
    ====> USER ID
    ====> PICTURE URL
    ====> DISPLAY NAME

    View Slide

  32. liff.getFriendship()
    liff.getFriendship().then((friendship) => {


    if (!friendship.friendFlag) {


    window.location.href = `https://line.me/R/oaMessage/
    @premium-id/?${encodeURIComponent(


    '"กด
    ส่
    ง"เพื่อรับลิง
    ก์
    ชวนเพื่อน'


    )}`;


    } else {





    }


    });

    View Slide

  33. Set Personalized Richmenu
    https://developers.line.biz/en/reference/messaging-api/#rich-menu
    const line = require("@line/bot-sdk");


    const client = new line.Client({


    channelAccessToken: "",


    });




    client.linkRichMenuToUser("", "");


    View Slide

  34. Save Data to Redis
    https://samsung-invite-friend.aiya.ai/R/cOkrVS
    const body = {...}


    const code = "cOkrVS"


    const userId = "Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"


    await redis.set(`fgf-user:${userId}`, code);


    await redis.set(`fgf-code:${code}`,JSON.stringify(body));

    View Slide

  35. Traceable
    Unique
    Affiliate Link
    https://samsung-invite-friend.aiya.ai/R/cOkrVS

    View Slide

  36. The Open Graph Protocol
    https://ogp.me/

















    property="twitter:description"


    content={config.TWITTER.description}


    />


















    View Slide

  37. The Open Graph Display

    View Slide

  38. In-app Browser Challenge

    View Slide

  39. https://invite.aiya.ai/xxx/join
    Mobile Detection
    export const isMobile = (userAgent: string) => {


    let mobile = false;


    let ua = userAgent.toLowerCase();


    if (


    /(android|bb\d+|meego).+mobile|liff|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|…/i.test(


    ua


    ) ||


    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|…/i.test(


    ua.substr(0, 4)


    )


    ) {


    mobile = true;


    } else if (/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(ua)) {


    mobile = true;


    }


    return mobile;


    };


    View Slide

  40. LINE URL scheme
    https://bit.ly/3B8eYNo
    ● https://line.me/R/
    ● https://liff.line.me/
    ● line:// (Deprecated)

    View Slide

  41. Local Storage

    View Slide

  42. Scale up on Production

    View Slide

  43. Our Challenges
    ● Slow insert database
    ● 500 concurrent for API
    ● Heavy page load traffic

    View Slide

  44. Serverless
    https://github.com/serverless-nextjs/serverless-next.js
    pageAppDev:


    component: '@sls-next/[email protected]'


    inputs:


    description: "aiya-ai"


    removeOldLambdaVersions: true


    tags:


    - cloudfront


    - nextjs


    bucketRegion: ap-southeast-1


    bucketName: "aiya-ai-ap"


    bucketTags:


    - "cloudfront"


    cloudfront:


    distributionId: E1I4P19Z5XXXX


    aliases: [


    'invite.aiya.ai',


    ]







    enableHTTPCompression: true


    timeout:


    defaultLambda: 15


    apiLambda: 15


    imageLambda: 15


    name:


    defaultLambda: aiya-ai-default


    apiLambda: aiya-ai-api


    imageLambda: aiya-ai-image


    publicDirectoryCache:


    value: public, max-age=604800


    test: /\.(gif|jpe?g|png|txt|xml)$/i


    policy: "arn:aws:iam::XXXXXXXX:policy/aiya-ai-policy"


    roleArn: "arn:aws:iam::XXXXXXXX:role/aiya-ai-role"


    build:


    cmd: 'yarn'


    args: ['build', 'page']


    View Slide

  45. AWS Cloud Service
    Cloudfront
    Amazon
    S3
    Amazon

    View Slide

  46. Atchariya Darote


    CEO AIYA


    LINE Certified Coach for API 2022
    Follow me:


    @aiyaclub

    View Slide

  47. the power of platform
    and community

    View Slide