สรุปครึ่งบ่าย อยู่ในงานใหญ่ของชาวไลน์เดฟ LINE Thailand Developer Conference 2019

Minseo Chayabanjonglerd
MikkiPastel
Published in
12 min readMay 29, 2019
เพิ่งสั่งกล้องฟิล์มไปแต่มาไม่ทันงานนี้นะ ใช้แอป Huji ไปก่อนนะ

ครึ่งเช้าเขียนเสร็จแล้วพบว่ามัน 11 min read ซึ่งยาวมากๆ และตอนบ่ายเนื้อหาก็แน่นไม่แพ้ช่วงเช้าเลย เลยลองตั้งโพลถาม รู้ผลตั้งแต่นาทีแรกเลยต้องแยกตอนที่ 2 ออกมาจ้า (และบล็อกนี้ 12 min read ถ้ามันเป็น 23 min read จะอ่านกันไหมเนี่ย ถามจีง)

ความเดิมตอนที่แล้ว

How LINE using LIFF in e-Commerce — Nati Namvong

เราเองเคยได้สัมผัสความเทพของพี่เนและท่านอื่นๆใน Sellsuki ตอนไป workshop vue.js จ้า

ซึ่งเราเข้าห้องสายไปนิดนึง ;__; แต่พอเข้าใจว่าพี่เนอธิบายเรื่องการสร้าง LIFF อยู่ว่า ใช้เจ้า HTML5, js, CSS3 ซึ่งก็เหมือนการสร้างเว็บทั่วไปแหละ

จากนั้นอธิบายการทำงานระหว่างเว็บปกติทั่วไป และ LIFF ซึ่งจะคล้ายๆ deeplink ฝั่งแอปเลยเนอะ ซึ่งปกติกด link จาก LINE ไป In-App Browser เพื่อให้ webview มันไป render web ขึ้นมา แต่ LIFF คือให้เขาจะ render web ที่ฝังเจ้า LIFF SDK เอาไว้ ประมาณนี้ตามความเข้าใจของเรานะ

ซึ่งการแปะลงไปนั้นก็ต้อง init กันก่อนเนอะ และมันสามารถใส่ value หลายตัว พี่เนเลยยกมา 3 ตัว คือ

  • language ในไลน์ตั้งภาษาอะไร (ไทย/อังกฤษ)
  • context.type web ที่เปิดมาอยู่ใน schema ไหน มี 4 อัน คือ none สามารถเปิดจากไหนก็ได้, group, room, utou One-on-one chat
  • context.viewType แสดงผลแบบไหน มี 3 แบบ คือ compact สูง 50%, tall สูง 75%, full สูงเต็มจอ

เดี๋ยวนะ ทำไมเจ้าของบล็อกดูข้อมูลแน่นจัง เขียนมาครบหรอ เปล่า อ่าน document จ้า

การ get profile เพื่อระบุตัวตนของเรานั้น จะมี security โดยการใช้ Access Token โดย web จะส่งให้เพื่อยืนยันว่า user เป็นคนๆนี้นะ

เจ้า LIFF สามารถส่ง message ได้นะ ส่งในนามของ user ไม่ใช่ OA หรือ bot นะ (ถ้านึกไม่ออกให้ลองสั่งอาหารกับ Indie Dish ดูได้จ้า พอกด LIFF เลือกเมนูเสร็จ เมนูที่เราสั่งนั้น ออกมาจากฝั่งเราและส่งเข้าห้องแชทจ้า)

การที่มีเจ้า LIFF ช่วยทำให้ UX ของเจ้าบอทดีขึ้น เอาเว็บของเราติดตั้ง LIFF SDK ลงไป เช่น ซื้อของ จองตั๋วหนัง เล่นเกมส์

Use Case : LINE CAFE’ เป็นร้านกาแฟสวัสดิการของชาวไลน์เนอร์ ไม่รับเงินส่ง ไม่รับสั่งหน้าร้าน ให้สั่งได้เฉพาะผ่านไลน์ของร้านเท่านั้น การเลือกเมนูก็เปิดเจ้า LIFF ออกมา เพื่อซื้อกาแฟ จากนั้นตัดเงิน และสรุปออร์เดอร์ ซึ่งส่งจาก Messaging API จ้า นั่งทำงานสั่งกาแฟ จ่ายเงินเสร็จทำงานต่อเดี๋ยวกาแฟจะมาส่งเองจ้า

LIFF in LINE Product (อันนี้จำหัวข้อแบบเป๊ะๆไม่ได้) โปรเจกในความดูแลของพี่เนติมี 2 ตัวจ้า

  • LINE Shopping ฟีลประมาณอยู่ใน mall ใน supermarket ตอนนี้อยู่ในช่วง soft launch จ้า
  • LINE OA Plus เป็น web e-commerce ซึ่งอยู่ในขั้นของการ test อยู่ ถ้าไปเก็บสแตมป์กันก็จะเจอกับบูธข้างนอกแล้วเนอะ เขียนไว้ในบล็อกก่อนหน้านี้ ฟีลประมาณขายของตลาดนัด แบบขายออนไลน์ทั่วไปที่สามารถต่อราคาได้

Demo

  • LINE Shopping เป็นการรวมร่างกันของ LIFF + OA พอเปิดเจ้า LIFF เข้าไปแล้วเราสามารถ save สินค้า ซึ่งเบื้องหลังการทำงานคือ get profile และเก็บ data เอาไว้, ใช้ Rich Menu ทำ Promotion ต่างๆ, ซึ่ง LIFF ทั้งหมดใน Rich Menu นั้นมีตัวเดียวจ้า และส่ง parameter ที่เป็น query string ไปบอก
  • LINE OA Plus เป็นการร่วมร่างของ OA + web e-commerce ซึ่งเป็น customer platform ให้ตรงกับความต้องการของคนไทย ตัวนี้สามารถดู order history ได้นะ เราได้อัดคลิปการ demo เจ้าตัวนี้มาด้วยหล่ะ

สุดท้ายกับการตะลุยดงโค้ดในการสร้าง LIFF จ้า

ซึ่งทางพี่เนใช้ nuxt.js ใส่ script ที่ header เพื่อติดตั้ง LIFF และเพิ่ม feature ในการส่งรูปสินค้าที่เรากำลังดูผ่าน LIFF เพื่อสอบถามแม่ค้า ขั้นตอนคือส่งรูปจาก LIFF ส่งข้อความ และปิด LIFF จ้า

Enhance Customer’s Payment Experience with Rabbit LINE Pay API — Sitthi Thiammekha

ก่อนอื่นคุณหนึ่งแนะนำตัวและแนะนำ LAE ว่าคืออะไร ต้องทำอะไรบ้าง ตอนนี้มี 5 คนนะ

เจ้า Rabbit LINE Pay ทำให้การจ่ายเงินของเราง่ายและสะดวกขึ้น และ developer สามารถเอาไปใช้ได้โดยการ plug ลงไปและเรียก reserve API และได้ url ชุดหนึ่งเพื่อทำการชำระเงิน และ confirm transaction

ลำดับขั้นตอนการทำมีอะไรบ้าง

ก่อนอื่นสมัคร merchant รอไว้ก่อนเลย เพราะต้องรอ approve ก่อนถึงจะใช้ได้

ดังนั้น dev รอก่อนเลยจ้า สร้าง sandbox ก่อน ได้ username password ส่งเข้า email และ copy token และ secret key เก็บไว้ก่อน

ข้อควรระวัง ตอน login น้านนนนน ไม่เหมือน Login เข้าไลน์แบบปกตินะ มี @line.pay ด้วยจ้า

Endpoint

Reserve API ต้องการ json body และใส่พวก require ต่างๆให้ครบ

  • คุณหนึ่งแนะนำว่าให้ใส่ productImageUrl ด้วยเพื่อความน่าเชื่อถือจ้า
  • ส่วน confirmUrl นั้น LINE ส่ง callback ที่ url นี้ ซึ่งมีสองแบบคือ client ก็คือ redirect user ไปที่หน้านั้นๆ และ server คือยิง background ไปยัง API ของเรา
  • paytype ปกติจะเป็นแบบ normal ซึ่งเป็น default อยู่แล้ว ส่วน preapproved ระบบจะเก็บ token เพื่อเรียกเก็บเงินทีหลัง เช่นจ่ายอะไรสักอย่างรายเดือน
  • capture หลักจาก user ชำระเงิน ตอน confirm จะให้เรียกเก็บเงินเลยไหม ถ้าใช่ก็จะพาเข้าไปหน้าเก็บเงินซึ่งเราไม่ต้อง call API เพิ่ม

สร้าง payload ได้ response มาและ redirect ซึ่งใช้ได้แค่ตัว web อย่างเดียวในตอน test เนอะเพราะใน app จะเป็นบน production

Confirm API เอา transactionID ที่ได้ไปใช้ ถ้า user confirm แล้วอาจจะส่ง push message ไป ถ้าแบบ Client คือหลังจาก user ชำระเงินเสร็จแล้วพาไปไหนต่อ

Other API มีตัวอื่นๆที่น่าสนใจ

  • Capture API ถ้า user ชำระเงินแล้วจะเป็น auth และดูว่าเรียกเก็บเงินที่ transaction ไหน
  • Void ยกเลิกออร์เดอร์
  • Refund จ่ายเงินไปแล้วยกเลิกออร์เดอร์
  • Preapprove เอา reg key ไปใช้ต่อ เพื่อเรียกเก็บเงินทุก period เช่นทุกเดือน
  • get API ดึง transaction จาก id มาดู

Transaction สามารถดูย้อนหลังได้ใน sandbox บนหน้าเว็บนะ

Demo คุณหนึ่งทำการ demo การจ่ายเงินให้เราดู ประมาณแบบในคลิปนี้จ้า

ส่วนโค้ดอยู่ที่นี่จ้า

Reference คุณหนึ่งบอกว่าเว็บใช้งานยากในการ search หาในสิ่งที่จะต้องใช้

มีทั้ง document ให้อ่านและโลโก้เผื่อเราจะเอาไปใช้ต่อจ้า

เวลามีเหลืออยู่บ้างคุณหนึ่งเลยมาพูดถึง LAE ซึ่งแต่ละประเทศมีไม่ค่อยเยอะ ทางไลน์ต้องการเพิ่มอีก แต่เราก็ต้อง contribute ความรู้ในการใช้ LINE API อาจจะเป็นการเขียนบล็อก ตอบคำถามในกลุ่ม อัดคลิปวิดีโอสอน เราเข้าใจฟีลคุณหนึ่งนะ ทุกคนทำงานประจำกัน อย่างเราบางประจำเขียนแอปงี้ไม่ค่อยได้มาเล่นในส่วนนี้เท่าไหร่ เอาเป็นว่าก็พยายามทำเท่าที่ทำได้แล้วกันเนอะ ;)

SCB Connect inside Banking Infrastructure — Chanintorn Asavavichairoj, Kasidej Phulsuksombati

เป็น session ที่คนมาฟังเยอะมากกกกกกกกกกก เพราะคนรอฟังเยอะมากกกก

ชอบสไลด์แนะนำตัว ตรงข้อหัวดีด้วย แถมยังใช้ brand CI ด้วย

บางคนอาจจะงงๆ SCB Connect คืออะไร ทำไรได้บ้าง > แจ้งเตือน transaction, ให้บริการข้อมูลสินเชื่อ บัตรเครดิต, ส่ง gift, บริการพิเศษ, จองคิวที่สาขา, คุยกับบอท

Agenda ใน session นี้ค่ะ

Handling Chatbot Flow

synchorous กินเวลา แตก lamda function เป็น ticker เปลี่ยนเป็นตะกร้าเก็บงาน แล้ว retry ได้

และทำอย่างไรให้ secure ก็คือทำตาม API Spec โดยการ check signature และ set whitelist

Customer On-boarding

SCB Easy Authentication : user สามารถ register ได้เลย เพราะผ่าน kyc กับ SCB Connect แล้ว

ซึ่งส่วนนี้ใช้ LINE Login เพื่อทำการ auto login ให้ และ LIFF ในตอนแรกกม่กล้าใช้เพราะมีการ pass data แต่ตอนนี้ get access token ได้จบใน webview ซึ่งข้อดีอีกอย่างนึงคือ ทำ deeplink ได้

The anatomy of SCB Connect

DMZ คือโซนที่ไม่มีทหาร และคุยผ่านคิงหมด ก็คือ Enterprise system, RESTFUL API เก็บใน redis วาง proxy เป็นทางเข้า, scale microservice ง่ายขึ้นด้วย kubernet

AWS และ Cloud front ทำให้ตัวลูกเร็วขึ้น และใช้ DialogFlow ด้วย

Pushing tremendous messages

handle transaction ยังไง ถ้าเรา scale ไม่ balance มันจะ lost ตรง API ไป server นะ

RESTFUL — synchronous, point-to-point จะเริ่มปวดหัวกับพวก exception และ timeout

เลยเปลี่ยนมาเป็น event เพื่อให้คล่องตัวมากขึ้น

เท่าที่ฟังจะมี event sourcing คุยกับ microservice ทำให้ timeout น้อยลง streaming replay data ได้ซึ่งดีกว่า hubsub และไป check log ที่ kafra (เนื่องจากเราไม่ค่อยมีความรู้เรื่องพวกนี้อาจจะจดงงๆหน่อยจ้า)

ปัญหาคือ worker มีได้ไม่จำกัด แต่ scale ไม่ได้ เพราะ API Limit ของ LING แต่ตอนนี้ได้มากขึ้นเพราะ LINE Redesign

Message Type : chatbot, transaction, retargeting, ประเมิน, … จึงแบ่ง priority ของเวลาเพื่อ UX ที่ดี และใช้ reply เพื่อลด cost ของ Messaging API

ตัวบอทใช้ DialogFlow ทำ

และเห็น data ชุดนึง คือคนพิมพ์ . เข้ามาเยอะมาก เลยเล่นมุขนี้ซะเลย

Made the chatbot more intelligent

การเข้ามาของ LINE Resign ทำให้ loan conversation ดีขึ้น

How to make good chatbot?

NLU คือ Natural-language understanding เข้าใจ user journey ส่วน MLU คือ Machine learning มีความสำคัญแค่ 5% เท่านั้น ซึ่งคนให้ requirement ไม่ใช่ใครที่ไหน แต่เป็น user นั่นเอง ที่เป็นคนคุยกับ chatbot

ระบบคร่าวๆ คือข้อความส่งมาทางไลน์ และผ่าน adapter เพื่อเข้าไป monitoring ถ้า operator ดูในส่วนของ training ถ้าบางอย่างไม่สามรถทำได้ก็จะบอกทาง Engineer เพื่อทำ fulfillment ให้จ้า ส่วนเจ้า chatbase ก็เอาไว้ดู analytics จ้า

SBD Stack ทำบอทผ่าน DialogFlow และ Stackdriver เป็นคนเก็บ log จากนั้น export log ไปสร้าง log synx และ dump เข้า BigQuery และดู data ที่ผ่าน

และตอน demo สร้างความ surprise โดยการ เปิดของ production มาให้เราดูจ้า โอโหว intent ใน DialogFlow เยอะมากๆๆๆๆๆ

เปิดให้ดู setup ในการส่ง log ต่างๆเข้า Google Cloud

Data studio ที่น่าสนใจ

  • log cleaning เข้า data ของเมื่อวานเข้าไป
  • topic modeling ดู insight ว่าสร้าง feature อะไรตอบโจทย์ user

มีคลิปประกอบบางช่วงบางตอนครับ

Live Coding a Chatbot — Jirawat Karanwittayakarn

หนูเข้าสายไปนิดนึง แต่มาทันนะพี่ตี๋

ใน session นี้นั้น พี่ตี๋ทำ Live Score ผลบอลจ้า

โดยสิ่งที่จะ live coding กันนั้น มีประมาณนี้จ้า มี realtime update ผลบอลแบบสดๆ แบบทีมไหนยิงประตูได้ส่งเลยจ้า, support ทั้ง iOS และ Android, publish ได้รวดเร็ว, autoscale with Serverless ซึ่งใช้ Firebase, ทำให้คนรู้สึกว๊าวววว

พี่ตี๋ทำการ coding หลายขั้นตอน เราจึงขออนุญาตข้ามเรื่องตัวเลขขั้นตอนไปนะ

ก่อนอื่นสร้าง Rich Menu ขึ้นมาก่อน ระวังเรื่องขนาดของรูปและนามสกุลของรูปไม่ถูกต้องแล้วนะ เดี๋ยวนี้เราสามารถสร้าง Rich Menu ได้อย่างสะดวกสบาย ด้วย Rich Menu Maker พัฒนาโดย developer ชาวไทย มี 7 รูปแบบให้ได้ใส่กัน

ซึ่งภาพนี้คือเจ้า Rich Menu กดสับตะไคร้ กับ แจ้งเตือนผล

จากนั้นเข้าเว็บ LINE OA เพื่ออัพโหลด Rich Menu ด้านบนนี้ ซึ่ง free plan ก็สามารถใช้สิ่งนี้ได้นะ

จากนั้นเข้าหน้า console ของ Firebase เปิด realtime database เพื่อสร้าง ref ที่ชื่อว่า ucl และมี child ชื่อ score

ไปที่โค้ดของเรากันต่อในส่วนของ cloud function เพิ่ม Request dependency เลือก region ที่ใกล้ไทยมากสุดก็คือฮ่องกง set runtime timeout ที่ 4 วินาที (default รู้สึกว่าจะ 30 วินาที บางทีมันก็นานไปสำหรับ chatbot อ่ะ) และ memory 2 GB เมื่อตั้งค่าเสร็จแล้ว ไปสร้าง function 3 ตัวดังนี้

  • push : require userId เพื่อเพิ่ม message
  • reply : มีการ interact จาก user, reply token, message payload
  • broadcast : รับ message

หลังจาก deploy เราจะได้ webhook ที่เป็น url https มาเอาไปใส่ที่ไลน์บอทของเรา

ซึ่งใน Firebase Cloud Function น้านนน รองรับ node8 ซึ่งมีเรื่อง async/await เพื่อหลีกเลี่ยง callback hell ใครใช้ node6 อย่าลืมเปลี่ยนด้วยน้าา

ต่อมา สร้างตัวแปรที่ดึงค่าจาก Realtime Database ซึ่งตัวโค้ดอ่านจากบล็อกพี่ตี๋น่าจะดีกว่า ฮ่าๆ

อันนี้ยังดูธรรมดาๆ พี่ตี๋มี feature นึง คือ สามารถอัพโหลดรูปได้ เอาไว้ทำอะไรหล่ะ สรุปสั้นๆแถวนี้คือยืนยันตัวตนทีมบอลที่เราชอบน้านเองงงง~~

  • รูปที่ได้มานั้นเป็น binary เราต้อง write file โดยรับมาจาก event.message.id ถ้ารูปส่งมาจาก LIFF จะได้ url มา ซึ่งจะส่งในนามบุคคล (คือเราเป็นคนส่งให้เจ้าบอท) message.contentProvider.external และ UTF-8 ทำให้รูปเรานั้นไม่สมบูรณ์ เราจึงต้องทำให้สมบูรณ์โดยเจ้า buffer เขียนไฟล์ temp.jpg
  • define bucket กับ storage ก้อปหลัง // ไปแปะ
  • ใช้เสร็จอย่าลืมลบน้อง temp.jpg ซึ่งเป็น local file และ reply กลับไปหา user เพื่อ UX ที่ดีย์ ดังนั้นเราจะเสีย reply token ที่ใช้ได้ครั้งเดียวในรอบนี้
  • predict รูปด้วย Cloud Vision API ว่าในรูปมี logos อะไรบ้าง และ return ใส่ใน Quick Reply ซึ่งใส่ได้มากสุด 13 ตัว ดังนั้นจึงเพิ่ม condition ไปว่าให้เอามาแสดงเฉพาะอันที่ logo.score >= 0.7 และ set action.type = 'postback' เพื่อแนบ data ไปด้วย
ผลมันจะประมาณนี้จ้า
  • ส่ง push message push(userId, msg, quickReplyItem) เนื่องจากเราใช้ token ไปแล้ว
  • Check post back จาก reply message เพื่อ check data
  • ถ้า data update (เมื่อนักฟุตบอลยิงประตูเข้า) ส่ง message ให้ user โดยการ push
  • Final score ใช้ build on-job scheduler เพื่อตั้งเวลาจบการแข่งขัน
  • สรุปท้ายลองเปลี่ยนจากส่ง message เป็น Flex Message ส่วนเจ้า LIFF ก็ deploy บน Firebase Hosting ระหว่างที่พี่ตี๋ deploy นั้นก็วิดพื้นรอ บนพวกเราชาวเดฟด้วยความเป็นห่วงว่านั่งแต่หน้าคอม ไม่ค่อยได้ออกกำลังกายกัน 555

ในช่วงหนึ่งพี่ตี๋หยิบเสื้อหงส์มา นึกว่าจะแจกแฟนหงส์ 555 (ได้ข่าวว่ามีเสื้อครบรอบ 100 ปีด้วยใช่ม่ะ อันนี้ฟังจากข่าวนะ และเราไม่ใช่แฟนหงส์นะ) แต่จริงๆแล้วให้แฟนหงส์ใส่เสื้อหงส์ เพื่อทดลองในส่วน feature vision ว่าเอออันนี้เสื้อลิเวอร์พูลจริงๆนะ ซึ่งเจ้า Quick Reply ก็ขึ้นมาให้ถูกต้อง ตบมือสิรอรัยย

บรรยากาศโดยรวมจ้า

สุดท้ายพี่ตี๋สรุปการทำงานจ้า พยายามแล้วแต่ภาพจ้าไปหมด ฮืออออออ

เอาเป็นว่าพี่ตี๋เขียนบล็อกของ session นี้ ละเอียดยิบ ชอบรูป cover มากๆเลยค่า แนวเล่นตัวเองเจ็บน้อยสุด ฮ่าๆ

ส่วน stamp ตอนแรกคืองงๆว่าหายไปไหนบูธนึง ตอนหลังกินข้าวเที่ยงมาเจอว่าหายที่บูธ LINE Shopping เฉยเลย รอรับเสื้อหลังห้าโมงครึ่ง ซึ่งแถวรับเสื้อคิวยาวมากกกกกกกกเลยแหละ แบบต่อคิวยาวแบบทั้งกรอบตึกแล้ว เยอะพอๆกับคิวจับมือเฌอปรางเลย ฮ่าๆ เผลอๆอาจจะมากกว่าอีกมั้ง

สรุปงานก็ได้อะไรใหม่ๆในการทำให้ครบ loop เนอะ ยอมรับว่าบอทที่ทำก็ไม่ได้ดีอะไรมากมาย แต่อย่างน้อยๆอาจจะลองทำระบบร้านอาหารสักอย่างนึงก็น่าสนุกดีไม่น้อยเลยนะ :D ถึงแม้จะหลงกับพี่ๆน้องๆทีม dev ที่ Ookbee U. ค่อนข้างบ่อย สวนทางกับพี่เอกแล้วดันมาเม้าท์ตอนพักเบรกเฉยร่วมกับพี่โอ๋และคนอื่นๆ และได้รู้ว่ามีคนไล่แจกซีดีซิง 4–5 ที่งานจับมือด้วย 555 ได้เจอเทพ LAE ทุกท่านที่มาในงาน เจอหลายๆคนที่เรารู้จักบ้าง และไม่รู้จักบ้างก็ตาม (แต่เขาจำเราได้ไง ว่าเราเคยพูดเรื่อง Kotlin ที่งาน Code Mania) ถึงแม้ห้องเล็กจะแอร์เย็นจนเราไป post บน Facebook ว่างานน่าจะแจก hoodie แก้หนาวก็ตาม555 แต่แน่นอนว่า LINE Developer Thailand ดูแลเราอย่างดีทุกงานจริงๆนะ ยิ่งไลน์ยิ่งใกล้ชัดๆ ฮ่าๆ ขอบคุณพี่ๆ LINE ที่ดูแลพวกเราทุกคนเป็นอย่างดีค่ะ

และขออภัยด้วยที่บางรูปอาจจะเบลอๆไปบ้างนะ คือจังหวะรีบด้วยและจับโฟกัสลำบากอยู่ แม้แต่ตาเรายังโฟกัสยากด้วยเพราะห้องมืด บางสไลด์แบบอ้าวสว่างเลย สงสัยใกล้จะอายุเยอะแล้ว 555 (ความจริงอาจจะมีเรื่องสายตาสั้นร่วมด้วย เพราะเริ่มมองไกลไม่ชัดล้าว ;__;)

สรุปรวมของทุกอย่างที่ได้จากงานนี้จ้า ลังเลติ๊กเกอร์ แต่เราต้องเลือกพี่บราวน์ค่ะ ปีก่อนได้แต่โคนี่มา 555

อย่าลืมกด follow medium เราหรือไม่ก็ like page เพื่อ update ข่าวสารและบทความใหม่ๆจ้า

--

--

Minseo Chayabanjonglerd
MikkiPastel

Android Developer | Content Creator AKA. MikkiPastel | Web2 & Web3 Contributor