และแล้วเราก็เดินทางมาถึงภาค 4 ของการส่งข้อความแจ้งเตือนแล้ว ซึ่งผมคิดว่าตอนนี้จะให้เป็นตอนจบแล้วล่ะ เพราะมันยาวเกินไปแล้ว 555 ใครยังไม่ได้อ่าน 3 ตอนก่อนหน้าเชิญได้ที่
- https://www.thepexcel.com/excel-line-email-notification-pt1/
- https://www.thepexcel.com/excel-line-email-notification-pt2/
- https://www.thepexcel.com/excel-line-email-notification-pt3/
ในตอนนี้เราจะไล่เก็บตกเรื่องเจ๋งๆ ที่ยังไม่ได้ทำใน 3 ตอนที่แล้ว ดังนี้
สารบัญ
เก็บตก 1 : วิธีส่งข้อความแจ้งเตือน Line Notification เข้า Group Chat
ก่อนหน้านี้ที่ผมสอนไปเป็นการส่ง Line ไปหา Line Notify ซึ่งเราจะเห็นอยู่คนเดียว ซึ่งไอแบบนี้มันเอาไปใช้งานจริงได้ลำบาก เพราะจะเป็นการเตือนตัวเองได้อย่างเดียว (จริงมะ)
ถ้าจะให้เกิดประโยชน์จริงๆ มันต้องแจ้งเตือนไปให้คนอื่นเห็นได้ด้วยสิ!
แต่เราไม่สามารถส่ง Line ไปหาคนอื่นได้แบบเดี่ยวๆ ตรงๆ แต่ว่าสิ่งที่ทำได้คือส่งเข้า Group Chat ที่มีคนอื่นอยู่ด้วย แบบนี้ถึงจะทำได้ครับ
Generate Token ใหม่สำหรับ Group Chat
ก่อนอื่นให้ไป Generate Token ใน https://notify-bot.line.me/ และไป My Page เหมือนเดิม แต่คราวนี้เราจะเลือกอันที่เป็น Group Chat แทน
จากนั้นก็เอา Token ที่ได้ไปใช้แทน Token เดิมได้
Invite Line Notify เข้ากลุ่มด้วย
การที่เราจะส่งข้อความเข้า Group ได้นั้น ไม่ใช่แค่เพียง Generate Token เท่านั้น แต่ว่าต้องเชิญเจ้า Line Notify นี่เข้ากลุ่มด้วย
พอเจ้า Line Notify เข้ากลุ่ม เราก็สามารถส่งแจ้งเตือนได้ตามปกติเลย
เก็บตก 2 : วิธีส่งรูปเข้า Line
การส่งรูปเข้า Line นั้น จากคู่มือ API มันบอกว่าเราสามารถทำได้ครับ โดยให้ใส่ค่า parameter ตามที่มันกำหนด ซึ่งตัวที่เกี่ยวข้องกับการส่งรูป ก็มี 3 ตัวที่ผมตีกรอบดังนี้
ซึ่งการส่งรูปจริงๆ จะมีอยู่ 2 ลักษณะ ก็คือ ส่งรูปที่อยู่ในเว็บ กับ การอัปโหลดรูปเอง
ส่งรูปที่อยู่ในเว็บอยู่แล้ว
การส่งรูปจากในเว็บ จะต้องใช้ imageThumbnail และ imageFullsize ดังนั้นผมจะแก้ Code ของ LineNotify ให้เป็นดังนี้
Sub LineNotify(msg As String, Optional stickID As Integer, Optional stickPack As Integer, Optional imgFullPath As String = "none", Optional imgThumbPath As String = "none")
Dim LineToken As String
Dim lineMessage As String
Dim objectXML As Object
Dim URL As String
'========================================
'Line Notify Token ที่ Generate มา
'group noti final
LineToken = "ใส่ Token ของคุณ"
'========================================
'Line Message
yourMessage = msg
lineMessage = "message=" & yourMessage
'========================================
'เพิ่มเงื่อนไข Sticker
If stickPack = 0 Or stickID = 0 Then
Else
lineMessage = lineMessage & "&stickerPackageId=" & stickPack & "&stickerId=" & stickID
End If
'เพิ่มเงื่อนไข image
If imgThumbPath = "none" Then
imgThumbPath = imgFullPath
End If
If imgFullPath <> "none" Then
lineMessage = lineMessage & "&imageThumbnail=" & imgThumbPath & "&imageFullsize=" & imgFullPath
End If
'========================================
Set objectXML = CreateObject("Microsoft.XMLHTTP")
URL = "https://notify-api.line.me/api/notify"
With objectXML
.Open "POST", URL, 0
.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
.SetRequestHeader "Authorization", "Bearer " & LineToken
.send (lineMessage)
Debug.Print objectXML.responseText
End With
Set objectXML = Nothing
End Sub
นั่นคือสามารถส่งค่า URL ที่เก็บรูปเข้าไปในคำสั่ง Line Notify ได้ ด้วยรูปแบบคำสั่งที่ผมออกแบบไว้ดังนี้
Call LineNotify(msg , stickID , stickPack , imgFullPath, imgThumbPath)
- โดยที่ถ้าใส่ stickID=0 หรือ stickPack=0 ก็จะไม่ส่ง Stickerเลย
- ถ้าไม่ใส่ imgFullPath ก็จะไม่ส่งรูปเลย
- ถ้าไม่ใส่ imgThumbPath ก็จะใช้รูป Thumbnail เดียวกับ imgFullPath
ดังนั้นถ้าเราลอง Test การส่งด้วยคำว่า
Sub testImg()
Call LineNotify("ทดสอบส่งรูป", 0, 0, "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-page.jpg")
End Sub
จากนั้นกด F5 จะได้ผลลัพธ์แบบนี้
แต่ถ้าเราใส่ทั้ง FullPath และ ThumbPath แยกกันเลย เช่น
Sub testImg2()
Call LineNotify("ทดสอบส่งรูป", 0, 0, "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-page.jpg", "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-book.jpg")
End Sub
มันก็จะส่งรูปแบบเล็กและใหญ่แยกกันเป็นคนละรูป โดยใน Chat จะแสดงเป็นรูปเล็ก (Thumbnail) ก่อน แต่พอคลิ๊กที่รูปเล็กแล้วจะแสดงเป็นรูปใหญ่ (Full Size )ที่เป็นคนละรูปกันได้
ส่งรูปด้วยการ Upload
สำหรับการ Upload นั้นเราต้องใช้คำสั่ง ImageFile ซึ่งจะต้องอ้างถึงตัวไฟล์เลย ซึ่งถ้าเป็นภาษาอื่นนี่ดู Code มันง่ายมากๆ แต่พอเป็น VBA นี่โหดจัดๆ
และเท่าที่เช็คดูใน Internet เหมือนกับว่าการส่งข้อมูลที่เป็นไฟล์ด้วย VBA นั้นจะต้องใช้ multipart/form-data แทน application/x-www-form-urlencoded ซึ่งจะซับซ้อนขึ้นเยอะและมีรูปแบบแปลกๆ เช่น
Content-Type: multipart/form-data; boundary=12345
--12345
Content-Disposition: form-data; name="sometext"
some text that you wrote in your html form ...
--12345
Content-Disposition: form-data; name="name_of_post_request" filename="filename.xyz"
content of filename.xyz that you upload in your form with input[type=file]
--12345
Content-Disposition: form-data; name="image" filename="picture_of_sunset.jpg"
content of picture_of_sunset.jpg ...
--12345--
ดังนั้นผมจะสร้าง Sub ใหม่ขึ้นมา เพื่อส่งรูปโดยเฉพาะ (แต่ถ้าเกิดส่งอย่างอื่นก็เรียกฟังก์ชันเดิมได้)
เท่าที่เช็คดูมีเว็บนี้ที่พอมีแนวทางในการใช้ VB ส่ง Binary File ได้ และก็ไปเจอ Post อันนี้ (ที่มีถามคำถามโดยคุณ kampanart ) ที่น่าจะดัดแปลง code มาจากเว็บฝรั่งอีกที ซึ่งใช้งานได้เลย งั้นผมลอกเลยนะ
ให้เราสร้าง sub ใหม่และ function ใหม่ เพิ่มจากของเดิม โดยใส่ Code ดังนี้
Sub LineNotifyUploadPic(msg As String, Optional UploadFilePath As String = "none")
Dim sFilepath As String
Dim nFile As Integer
Dim baBuffer() As Byte
Dim ssPostData1 As String
Dim ssPostData2 As String
Dim ssPostData3 As String
Dim Messagelength As Integer
Dim objectXML As Object
Dim arr1() As Byte
Dim arr2() As Byte
Dim arr3() As Byte
Dim arr4() As Byte
Const STR_BOUNDARY As String = "xxx---thepexcel---thepexcel---thepexcel---xxx"
'แก้ Token ตรงนี้
LineToken = "ใส่ Token ของตัวเอง"
sFilepath = UploadFilePath
sFileName = GetFilenameFromPath(sFilepath)
ssPostData1 = vbCrLf & _
"--" & STR_BOUNDARY & vbCrLf & _
"Content-Disposition: form-data; name=" & """message""" & vbCrLf & vbCrLf
arr1 = StrConv(ssPostData1, vbFromUnicode)
arr2 = (msg)
ssPostData2 = vbCrLf & _
"--" & STR_BOUNDARY & vbCrLf & _
"Content-Disposition: form-data; name=" & """imageFile""" & "; filename=" & sFileName & vbCrLf & _
"Content-Type: image/jpng" & vbCrLf & vbCrLf
arr3 = StrConv(ssPostData2, vbFromUnicode)
nFile = FreeFile
Open sFilepath For Binary Access Read As nFile
If LOF(nFile) > 0 Then
ReDim baBuffer(0 To LOF(nFile) - 1) As Byte
Get nFile, , baBuffer
imagear = baBuffer
End If
Close nFile
arr4 = StrConv(vbCrLf & "--" & STR_BOUNDARY & "--" & vbCrLf, vbFromUnicode)
Dim arraytotal As Long
Dim sendarray() As Byte
arraytotal = UBound(arr1) + UBound(arr2) + UBound(arr3) + UBound(imagear) + UBound(arr4) + 4
ReDim sendarray(arraytotal)
For i = 0 To UBound(arr1)
sendarray(i) = arr1(i)
Next
For i = 0 To UBound(arr2)
sendarray(UBound(arr1) + i + 1) = arr2(i)
Next
For i = 0 To UBound(arr3)
sendarray(UBound(arr1) + UBound(arr2) + i + 2) = arr3(i)
Next
For i = 0 To UBound(imagear)
sendarray(UBound(arr1) + UBound(arr2) + UBound(arr3) + i + 3) = imagear(i)
Next
For i = 0 To UBound(arr4)
sendarray(UBound(arr1) + UBound(arr2) + UBound(arr3) + UBound(imagear) + i + 4) = arr4(i)
Next
Set objectXML = CreateObject("Microsoft.XMLHTTP")
URL = "https://notify-api.line.me/api/notify"
With objectXML
.Open "POST", URL, 0
.SetRequestHeader "Content-Type", "multipart/form-data; boundary=" & STR_BOUNDARY
.SetRequestHeader "Authorization", "Bearer " & LineToken
.send sndar(sendarray)
Debug.Print .responseText
End With
Set objectXML = Nothing
End Sub
Public Function sndar(sendarray As Variant) As Byte()
sndar = sendarray
End Function
Public Function GetFilenameFromPath(ByVal strPath As String) As String
If Right$(strPath, 1) <> "\" And Len(strPath) > 0 Then
GetFilenameFromPath = GetFilenameFromPath(Left$(strPath, Len(strPath) - 1)) + Right$(strPath, 1)
End If
End Function
ซึ่งเวลาเรียกใช้งาน เราจะทำแบบนี้
Call LineNotifyUploadPic("ข้อความ", filepathของรูปในเครื่อง)
เช่น
Sub TestUploadPic()
Dim filepath As String
'แก้เป็น path ของรูปในเครื่องตัวเอง
filepath = "d:\thepexcel\sira-excel-powerup.jpg"
Call LineNotifyUploadPic(".", filepath)
End Sub
ซึ่งพอกด F5 เพื่อรัน ก็จะได้ผลลัพธ์ตามนี้เลย (รูปที่ส่ง คือรูปที่เราใส่เอาไว้ตามที่อยู่ใน filepath )
สรุป
Call LineNotify("ส่งข้อความเฉยๆ")
Call LineNotify("ส่งข้อความ และ sticker", 5, 1)
Call LineNotify("ทดสอบส่งข้อความ รูป1แบบ", 0, 0, "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-page.jpg")
Call LineNotify("ทดสอบส่งข้อความ รูป2แบบ", 0, 0, "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-page.jpg", "https://www.thepexcel.com/wp-content/uploads/2019/11/excel-power-up-book.jpg")
Call LineNotifyUploadPic("ส่งรูปแบบ upload", filepath)
เก็บตก 3 : การส่งข้อความซึ่งมีสัญลักษณ์พิเศษ
ก่อนหน้านี้เราส่งข้อความได้แล้ว เราส่งรูปได้แล้ว
แต่ถ้าสังเกตดูจะพบเมื่อเมื่อเราพิมพ์ข้อความที่มีสัญลักษณ์บางอย่าง มันจะไม่ไป เช่น สัญลักษณ์ & หรือ เครื่องหมาย +
วิธีแก้คือ ต้องทำการแทนที่ข้อความของเราด้วย อักขระแบบ % เช่น & ต้องแทนด้วย %26 (ดู code ทั้งหมดได้ที่นี่)
ดังนั้นเราจะสั่งแทนที่ Character บางอย่างด้วยสัญลักษณ์ % ได้ด้วยคำสั่ง replace ใน vba ครับ เช่น
'Line Message
yourMessage = msg
yourMessage = Replace(yourMessage, "&", "%26")
yourMessage = Replace(yourMessage, "+", "%2B")
แต่ทีนี้เนื่องจากมันมีหลาย Character พอสมควร เราจะ Copy Paste ทุกตัวใส้ไว้ใน Excel แล้วสั่งให้ Flash Fill เติมให้เราซะ เช่น
จากนั้นก็ copy code ด้านขวามาใส่ใน VBA เลย จบ จะได้แบบนี้
'Line Message
yourMessage = msg
yourMessage = Replace(yourMessage, "%", "%25")
yourMessage = Replace(yourMessage, "&", "%26")
yourMessage = Replace(yourMessage, "'", "%27")
yourMessage = Replace(yourMessage, "(", "%28")
yourMessage = Replace(yourMessage, ")", "%29")
yourMessage = Replace(yourMessage, "*", "%2A")
yourMessage = Replace(yourMessage, "+", "%2B")
yourMessage = Replace(yourMessage, ",", "%2C")
yourMessage = Replace(yourMessage, "/", "%2F")
yourMessage = Replace(yourMessage, ":", "%3A")
yourMessage = Replace(yourMessage, ";", "%3B")
yourMessage = Replace(yourMessage, "=", "%3D")
yourMessage = Replace(yourMessage, "?", "%3F")
yourMessage = Replace(yourMessage, "@", "%40")
yourMessage = Replace(yourMessage, "[", "%5B")
yourMessage = Replace(yourMessage, "]", "%5D")
ทีนี้เราก็จะส่งข้อความที่มี character พิเศษได้แล้วล่ะ
จบ
และแล้วเราก็จบ Series มหากาพส่งข้อมูลเข้า Line/Email แล้ว ใครเอาไปใช้แล้วเกิดประโยชน์ยังไงอย่าลืมมาเล่าให้ฟังบ้างนะครับ ^^