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 full-size slide

  2. Atchariya Darote


    CEO AIYA


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

    View full-size 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 full-size slide

  4. Friends get Friends Campaign
    Overview

    View full-size slide

  5. Our Challenge
    How to increase


    the number of registration?

    View full-size slide

  6. Our Challenges
    ● Accessibility
    ● Traceability
    ● Compatibility

    View full-size slide

  7. 50 Million
    LINE User


    Access (every day)

    View full-size slide

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

    View full-size slide

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

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

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

    View full-size slide

  10. Default RichMenu RichMenu after join campaign
    Personalized RichMenu

    View full-size slide

  11. Friends get Friends Campaign
    Demonstration

    View full-size slide

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

    compatibility
    Features

    View full-size slide

  13. Campaign Performance
    120%

    View full-size slide

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

    View full-size slide

  15. LINE Front-end Framework (LIFF)


    View full-size slide

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

    View full-size slide

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

    View full-size slide

  18. // 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 full-size slide

  19. What’s LIFF Share Target Picker?

    View full-size slide

  20. liff.shareTargetPicker([


    {


    type: 'text',


    text: 'Hello, World!',


    },


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

    View full-size slide

  21. 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 full-size slide

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

    View full-size slide

  23. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  28. How to retrieve share statistic?

    View full-size slide

  29. 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 full-size slide

  30. {


    "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 full-size slide

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


    if (!friendship.friendFlag) {


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


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


    )}`;


    } else {





    }


    });

    View full-size slide

  32. 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 full-size slide

  33. 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 full-size slide

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

    View full-size slide

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

















    property="twitter:description"


    content={config.TWITTER.description}


    />


















    View full-size slide

  36. The Open Graph Display

    View full-size slide

  37. In-app Browser Challenge

    View full-size slide

  38. 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 full-size slide

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

    View full-size slide

  40. Local Storage

    View full-size slide

  41. Scale up on Production

    View full-size slide

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

    View full-size slide

  43. 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 full-size slide

  44. AWS Cloud Service
    Cloudfront
    Amazon
    S3
    Amazon

    View full-size slide

  45. Atchariya Darote


    CEO AIYA


    LINE Certified Coach for API 2022
    Follow me:


    @aiyaclub

    View full-size slide

  46. the power of platform
    and community

    View full-size slide