(For users) การส่งขอ Approval mail ด้วยไฟล์แนบผ่าน Microsoft Forms ด้วย Power Automate
Content difficulty — Technical
ในตอนนี้จะขอนำเสนอแนวทางเพื่อเป็นทางเลือกในระบบงาน paperless ขององค์กรครับ ซึ่ง solution นี้จริงๆแล้วสามารถทำเองได้หลากหลายแบบครับ ในตอนนี้จะใช้ Microsoft Forms ทำในส่วนของ Data entry ร่วมกับ Power Automate ในการทำส่ง Approve เอกสารครับ
Solution ประเภทนี้จริงๆแล้วสามารถทำได้หลายวิธี เช่น ใช้ PowerApps เพื่อ Data entry, SharePoint Online List หรือ ทำ Page จาก SharePoint Home page เพื่อ Approval request ก็ได้
เป็นต้นว่าเราอาจจะมี Form มาตรฐานที่เป็น Excel, Word หรือ PDF เพื่อใช้ในการส่งขอ Approve เช่นในกรณีนี้ขอเบิกค่าใช้จ่าย
Microsoft Forms
จากนั้นเราไปที่ Microsoft Forms ผ่าน https://forms.office.com (ใช้ Form ประเภท survey) สร้าง Form เพื่อจะให้ user สามารถเข้ามากรอกและส่งไฟล์แนบ ซึ่งเราจะ share form นี้แบบ ภายในผ่าน URL หรือ QR code เราก็ตั้งคำถามเพื่อให้ user กรอกได้ตามต้องการ
ในส่วนของการแนบเอกสาร Microsoft Forms สามารถเพิ่มคำถามส่วนที่เป็น File upload ได้แล้วสามารถ limit size ได้ด้วยโดย File upload จะทำให้ Form นี้ตอบได้เฉพาะคนใน Office 365 องค์กรเราเท่านั้น
Output ที่เก็บ Response ว่าคนกรอกอะไรจะถูกเก็บไว้ใน Microsoft Excel ซึ่ง ไฟล์แนบจะไปอยู่ใน OneDrive for Business ของคนทำ Form นี้ ซึ่งระบบจะไปสร้างใน folder path บน OneDrive คือ Files/App/Microsoft Forms/ชื่อ Form เรา/ชื่อคำถาม ส่วนชื่อไฟล์จะมีการ rename นิดนึงคือ ชื่อไฟล์_ตามด้วยชื่อคน upload
เนื่องด้วยถ้าทำ solution ประเภทนี้อาจจะพิจารณาว่าเพื่อส่วนรวมก็ควรให้ที่เก็บเอกสารแนบของ user ของเราไปอยู่ใน SharePoint Online มากกว่าใน OneDrive ของเรา ดังนั้น Form ตัวนี้เราจะทำเป็น Group Form ซึ่งเราต้องเลือกว่าจะ Share ไปใน Office 365 Group ไหน โดยเข้าไปที่ https://www.office.com/launch/forms/appitems?auth=2 แล้วไปแชร์ที่ Office 365 Group
Folder path ก็จะย้ายไปใน SharePoint Document Library แทนเนื่องจาก Office 365 Group ได้ผูกตัว SharePoint Site ของ Group นั้นไปด้วย จะอยู่ที่ Shared Documents/App/Microsoft Forms/ชื่อ Form เรา/ชื่อคำถาม จากตัวอย่างในในรูปล่างกรณีนี้ชื่อคำถามคือ เอกสารแนบ (ไม่เกิน 10MB)
Folder ใน SharePoint ก็สามารถกำหนด permission ได้เช่นกันซึ่งจะกล่าวในครั้งหน้า
Power Automate (Microsoft Flow)
การสร้าง Power Automate นั้นมี component อยู่ 2 ค่าคือ Trigger และ Action ซึ่ง Trigger คือ เงื่อนไขในการ run workflow นี้ และ Action คือ ชุดคำสั่งต่างๆ ที่จะทำงานต่อเมื่อมี Trigger
ซึ่งเราก็เลือก Connector ได้ตามที่เราต้องการว่าจะให้ไป trigger หรือ action ระหว่าง service อะไรกับ service อะไรซึ่งในที่นี้คือ Microsoft Forms, Outlook (สำหรับส่ง email approval) และ SharePoint Online (เก็บไฟล์แนบ)
ไปที่ https://flow.microsoft.com/manage เพื่อ create flow เลือกประเภทว่าเป็น Automate Flow (คลิก +new -> Automated-from blank) จากนั้น ตั้งชื่อใน Flow name แล้วเลือก When a new response is submitted เพื่อรับ Trigger จาก Microsoft Forms
เลือกส่วนของ trigger ว่าจะให้ Form ไหนมาเข้า rule นี้ปัญหาคือ ถ้าเราย้ายไปที่ Group Form เราจะไม่เห็นว่ามีชื่อ Form นั้นมีอยู่ใน list ให้เลือกเป็น Trigger แต่เราสามารถคลิก Enter custom value แทนได้เพื่อใส่ Form ID แทนการคลิกเลือกชื่อ
ตัว Form ID จะอยู่ใน URL ของ Form นั้นหน้าที่เรา edit form ตั้งคำถาม จะอยู่หลังคำว่า FormId= ให้เรา copy ค่าแล้วมา paste ใน custom value นั้น
จากนั้นคลิก +New step เพื่อเพิ่ม Action ให้ เอารายละเอียดของผู้ที่มากรอก Form session นั้นๆโดยเลือก action ตัว Get response details (จะเห็นเป็น action ที่เป็น connector ของ Microsoft Forms) โดยใส่ Form Id และ Response Id ซึ่งเราสามารถ คลิกเอา Dynamic content มาใส่ คราวนี้เราก็สามารถเอา profile ของคนกรอกได้ว่าเขา email อะไร, ตอบเมื่อไหร่ หรือ แนบไฟล์อะไร
ใช้ Get user profile (Office 365 users) เพื่อเป็น Action ดึง Profile เช่น Display name ของ user คนนั้น, Job title, Department ต่างๆ โดยใส่ Dynamic content เป็น Responder’s Email ที่เราได้ค่าจาก action ที่แล้ว
ค่า Profile ของ user คนนั้นทาง ทีม IT Admin เขาจะกรอกให้เราแล้วบางส่วนบน Active Directory และ User เจ้าตัวเขาเองอาจจะไปเพิ่มในส่วนของ Profile บางอันผ่าน Delve
จากนั้นเพิ่ม Action ชื่อ Get manager (Office 365 user) เพื่อใส่ Dynamic content เป็น Mail ของ user ที่ได้จาก step ที่แล้ว ซึ่งจะทำให้ระบบไปหาว่า user คนนั้นมี Manager คือใคร, profile เป็นยังไง
ทางทีม IT Admin จะต้องมีการ implement ในส่วนของ Organization ด้วยบน Active Directory เพื่อที่ว่าจะหาเจอ
ต่อมาเราจะ Add Action ชื่อ Parse JSON เพราะเนื่องจาก value ของคำตอบที่เป็น upload data บน Microsoft Forms เป็น JSON schema array โดยพอ add มาแล้ว ช่อง Content ให้ใส่ค่าของ Dyanmic content เป็นชื่อคำถามข้อที่เราตั้งเพื่อให้ upload file ใน Form ของเรา (ภายใต้ Get response details) ส่วน schema ให้เราคลิก Generate form sample แล้วใส่ โครงสร้างตัวอย่างของ JSON โดยใช้ตัวอย่างตามข้างล่างก็ได้ ซึ่งพอทำได้แล้วเราก็สามารถเอาค่าอย่างเช่น Filename, ID, size ของเอกสารที่ upload ของ user คนๆนั้นมาเป็นตัวแปรใน Flow ได้
ตัวอย่างเอาจากข้างล่างนี้ก็ได้ แต่ไป edit ใน notepad แก้ตัวฟันหนูจาก “ ให้เป็นตัวฟันหนูตรง
[
{
“name”: “test_Mod Admin 1.pdf”,
“link”: “https://contoso.sharepoint.com/teams/TeamsDemo-Thailand/Shared%20Documents/Apps/Microsoft%20Forms/Request%20Form/%E0%B9%80%E0%B8%AD%E0%B8%81%E0%B8%AA%E0%B8%B2%E0%B8%A3%E0%B9%81%E0%B8%99%E0%B8%9A%20(%E0%B9%84%E0%B8%A1%E0%B9%88%E0%B9%80%E0%B8%81%E0%B8%B4%E0%B8%99%2010MB)/test_Mod%20Admin%201.pdf",
“id”: “01TXQW5TKBGRJUHXTVFZGLDPOJTGHNHUDV”,
“type”: null,
“size”: 390537,
“referenceId”: “01TXQW5TMKWSEBACXT2NHLPO75PWHZELXV”,
“driveId”: “b!SuT0uwjADk2FB64bVo5GvgJAT7z2vfRFrWnoEAOqPshOKGvUYbreQKZq4GwH-rP7”,
“status”: 1,
“uploadSessionUrl”: null
}
]
Step ต่อไปใช้ action ชื่อ Get file content (Office 365 Outlook) เพื่อเอา Content จาก SharePoint Document Library ที่ไปเก็บ file โดย Site Address ก็ไปเลือกจากที่เรา Group Form ไปหา ส่วน File Identifier ให้ใส่ Path ของ Location ที่เก็บไฟล์ซึ่งจะเป็น Encode Path
Encode Path
ในจังหวะนี้จะมีความเป็นไปได้ 2 สถานการณ์
ความยากจะอยู่ตรงที่ Path มันจะถูก Encoded ตัว URL เป็นเครื่องหมาย ASCII ถ้ามี Folder เป็นภาษาไทย (ชื่อคำถามเราเป็นหนึ่งในนั้น) และการ เว้นวรรค หรือ / ก็จะถูกแปลงเช่นกัน โชคดีที่ path ของ Form เราค่อนข้างจะเป็น pattern เหมือนกัน
โดยสถานการณ์แรก ให้เราไปดูที่คำตอบของ Microsoft Forms ใน File Excel แล้วให้ Copy path ไว้ตั้งแต่หลังชื่อ site ของเรา สมมุติ SharePoint Site เราเป็น https://contoso.sharepoint.com/teams/TeamsDemo-Thailand/ ให้เรา copy path หลังจากนั้นจนก่อนถึงชื่อไฟล์เราตามที่ highlight ด้านล่าง
ค่าที่เรา copy เราต้องแปลงการ encode ซึ่งมี / ที่ยังไม่ได้แปลงให้แปลง character ตัว / ให้เป็น %252f ให้หมด
** ถ้าหน้าตา pattern ของ link ไม่ใช่แบบนี้ให้เลี่อนมาดูสถานการณ์ต่อไป
อีกสถานการณ์ที่เกิดขึ้นตัว SharePoint Online ปรับการ Encode ใหม่ตัว / จะเท่ากับ %2F ส่วนตัววรรคจะเป็น %20
เพราะฉะนั้น
/Shared Documents/Apps/Microsoft Forms/TCT Document/Please attach additional evidence (if any)/
จะกลายเป็น
%2FShared%20Documents%2FApps%2FMicrosoft%20Forms%2FTCT%20Document%2FPlease%20attach%20additional%20evidence%20(if%20any)%2F
ซึ่ง pattern หลักการจะเป็นแบบนี้ตาม path ของ SharePoint ที่เก็บไฟล์ของ Microsoft Forms ที่กล่าวตอนต้น
/Shared Documents/Apps/Microsoft Forms/ชื่อของแบบฟอร์ม/ชื่อคำถามข้อที่แนบ/
เพื่อความชัวร์สามารถลองทดสอบโดยที่ File Identifier ลองชี้ไฟล์ไปที่ path ตัวไฟล์ซักไฟล์ที่มีแนบไฟล์ไว้แล้วใน Form ของเราแล้วลอง test run flow ดูซักครั้งเพื่อไปเอาตัวอย่าง Output
เพราะถ้าเขียนไม่ถูกตาม pattern อาจจะทำให้ flow error หรือเวลายิง flow ผ่านก็จริงแต่อาจจะทำให้ผู้รับ approval mail ดูไฟล์แนบไม่ได้
เมื่อได้แล้วให้เรา Paste ในช่อง File Identifier แล้วตามดัว Dynamic Content ที่เป็น Parse JSON ตัว name ไปที่ช่อง File Identifier (ทุกอันต้องติดกันไม่เว้นบรรทัด)
พอ Add มาแล้วระบบจะใส่ Apply to each ครอบมาให้ เนื่องจากค่าเป็น Array
Next Steps
Step ต่อไปใช้ Action ชื่อ Send email with options (Office 365 Outlook) เพื่อสร้าง template ส่ง email ไปหาหัวหน้าเพื่อ Approve โดยใส่ To เป็น Mail ของ action ที่ได้จาก Get manager ในส่วนของ Attachment จะมี ค่า Name ที่เราจะเอามาจาก name ของ Parse JSON และ content เอาค่า File Content ของ Get file content
ถ้า IT Admin ไม่ได้มีการทำ Org chart อาจจะ fix email เป็นหัวหน้าเราก็ได้ในช่อง To แต่ทุก email ก็จะส่งหาเขา
Send email with options จะส่งเมล (To) ในนามเจ้าของ flow เสมอกรณีไปแชร์ให้คนอื่นมาใช้ MS Forms ทำให้ email ไปหาเจ้านายเขา แต่เป็นเราเจ้าของ flow ที่ส่งถ้าอยากให้ดูเป็น mail ที่ส่งจากคนอื่นอาจจะต้อง share flow ให้คนนั้นหรือ ถ้าจะทำเป็นเหมือนเมลส่งจากระบบจะต้องใช้ Action ชื่อ Approval ดูรายละเอียดตอนท้าย
ส่วนของ Body อาจจะต้องใช้ HTML เพราะเนื่องจาก Send email with options ยังไม่รอบรับตัว Text editor ซึ่งถ้าไม่ได้เป็น HTML จะทำให้มันติดกันไปหมดไม่ได้รองรับการเว้นบรรทัดหรือทำตัวหนา ตัวอย่าง HTML จะเป็นดังนี้ ตามภาพล่าง
จากนั้นจะใช้ Connector ชื่อ Conditions (Control) เพื่อสร้างเงื่อนไขเวลา Manager ตอบว่า Approve หรือ Reject โดย ใช้ Dynamic content ชื่อ SelectedOption is equal to Approve
สุดท้ายฝั่ง Yes และ No เราจะเขียน Action ที่ Approve และ Reject กลับไปหาคนกรอก Form โดยใช้ Action ของ Send an email (Office 365 Outlook) ซึ่ง Action นี้ Body ไม่จำเป็นต้องเขียน HTML เนื่องจาก Action นี้มี Text editor มาให้ เมื่อเสร็จแล้วให้คลิก Save ที่มุมขวาบนของ web page
ทดสอบ
โดยการ Test -> I’ll perform the trigger action แล้วลองไป ตอบใน Microsoft Forms ดู ซึ่งหลังจากนี้ Flow ก็จะทำงานตลอดเมื่อมีคนเข้ามากรอกใน Form
กรณีมีการแนบหลายไฟล์?
ในกรณีที่มีความต้องแนบหลายไฟล์และส่งไปใน mail เดียวจะมีความซับซ้อนกว่าในมุมของ Flow เพราะ Step จะมีมากขึ้น
อันดับแรกให้เพิ่ม action ตัว Initialize variable (connector ชื่อ Variables) โดยที่ชื่อเราอาจจะตั้งให้ชื่อว่า Attachments ส่วน Type เป็น Array
เข้ามาใน Loop ของ Apply to each ให้เพิ่ม action ที่ชื่อว่า Append to array variables (variables) โดย Name เลือกจาก ชื่อที่เราตั้งของ Initialize variable
ส่วนช่อง Value เราต้องใช้ schema ของ JSON คือ
{
“Name”: xxx,
“ContentBytes”: yyy
}
แก้ตัวฟันหนูจาก “ ให้เป็นตัวฟันหนูตรง
โดยที่ตรง xxx ให้ใส่เป็น Dynamic Content ของ name จาก action ของ Parse JSON และ yyy เป็น จะต้อง Add เป็น Expression แทน Dynamic content โดยใส่ค่า
body('Get_file_content')?['$content']
** ในกรณีหลังจากนี้ run flow แล้วส่งเมลแต่ผู้รับเห็นไฟล์แนบแต่อ่านไม่ได้ให้ใช้เป็นอันนี้แทน
base64ToBinary(body('Get_file_content')?['$content'])
หลังจากนั้นจะต้องเอา Action ที่เป็นการ ส่ง Email และ Condition ออกนอก loop ของ Apply to each เพื่อไม่ให้เป็นการส่ง email ซ้ำซ้อน เราสามารถลากออกไปได้ ถ้าทำไม่ใด้ให้ใช้วิธีการ copy to my clipboard ทั้งสอง action, ลบทิ้ง จากนั้นก็ +New Step เพื่อ add action จาก clipboard ที่เรา save ไว้ได้
สุดท้ายไปแก้ที่ Attachment ของ Action ของเราตัว Send email with options เพื่อใส่ variable ที่เป็น Array โดยการ คลิกให้มันเป็น JSON view จากนั้นลบทั้งหมดทิ้งแล้วใส่เป็น Variable ของ Dynamic Content แทน
กรณีไม่มีการแนบไฟล์?
เราสามารถ Block ตั้งแต่คำถามใน Microsoft Forms แล้วว่าต้องมีการแนบไฟล์ให้เรียบร้อยก่อนส่ง แต่ถ้าในกรณีที่เราต้องการให้การแนบไฟล์เป็น Optional แล้ว Flow ตัวนี้จะ failed ทันทีเนื่องจาก Parse JSON ไม่ได้
วิธี work around คือให้เราไป configure run after ตัว action ชื่อ Initialize variable กับ Send email with options ว่าให้ run ไม่ว่า step ก่อนหน้า success หรือ fail แล้ว คลิก done
ปัญหา Send email with options
ถ้าคนอื่นมาใช้ Form เราทำ request เจ้านายเขาจะเห็นเป็นเราส่ง mail ไปหาแทนเนื่องด้วยตัว connector นี้จะ run on behalf ของ owner ของ Flow
เราสามารถ แชร์ flow ให้คนอื่นที่ต้องการจะใช้ form เราให้ authen ตัว connector ที่เป็น Mail เขาเอง แต่ก็ทำให้เขาเป็น owner ร่วมและสามารถเข้ามา edit หรือ แก้ flow เราได้
อีกวิธีหนึ่งคือใช้ connector ชื่อ Start and wait for approval ในกรณีแนบไฟล์เดียว concept จะเหมือนกันกับ Send email with options ในด้าน input ที่ใส่ แต่ถ้าเป็นกรณีแนบหลายๆไฟล์ตัวนี้จะไม่รับ ContentByte เหมือนอันที่แล้ว แต่เป็น Content ธรรมดา ดังนั้นให้เราไปแก้ใน Append to array variable ก่อน
{
“Name”: xxx,
“Content”: yyy
}
แก้ตัวฟันหนูจาก “ ให้เป็นตัวฟันหนูตรง
โดยที่ตรง xxx ให้ใส่เป็น Dynamic Content ของ name จาก action ของ Parse JSON และ yyy เป็น จะต้อง Add เป็น Expression แทน Dynamic content โดยใส่ค่า
base64ToBinary(body('Get_file_content')?['$content'])
จากนั้นลบ Send email with options เปลี่ยนเป็น Create an approval แทน ซึ่ง Body จะเป็น markdown language แทน HTML ส่วน conditions ให้แก้เป็น Outcome
Start an wait for an approval อาจจะมี limit การแนบเบื้องต้นอยู่ที่ 5MB (แม้ว่าใน Microsoft Forms เราให้แนบได้มากกว่านั้น) ในกรณีนี้ให้คนที่เป็น Admin (Global Admin หรือ Power Platform Admin) ทดลองไปเพิ่ม limit ได้
ไปที่ https://admin.powerplatform.microsoft.com/environments แล้วเลือก environment ที่มี flow นั้น แล้วไปที่ Settings -> Email -> Email settings แล้วไปปรับ size ของ Attachment ตามสมควร