Funções da API do Windows e declarações de tipo
Primeiro, vamos definir um par de funções da API do Windows usando o Declare palavra-chave. Também vamos criar alguns tipos de dados definidos pelo usuário usando o Tipo comunicado.
#If VBA7 Then
Public Declare PtrSafe Sub GetSystemTime Lib "Kernel32" (lpSystemTime As SYSTEMTIME)
Public Declare PtrSafe Function SystemTimeToFileTime Lib "Kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As LongPtr
Public Declare PtrSafe Function LocalFileTimeToFileTime Lib "Kernel32" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As LongPtr
Public Declare PtrSafe Function FileTimeToSystemTime Lib "Kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As LongPtr
#Else
Public Declare Sub GetSystemTime Lib "Kernel32" (lpSystemTime As SYSTEMTIME)
Public Declare Function SystemTimeToFileTime Lib "Kernel32" (lpSystemTime As SYSTEMTIME, lpFileTime As FILETIME) As Long
Public Declare Function LocalFileTimeToFileTime Lib "Kernel32" (lpLocalFileTime As FILETIME, lpFileTime As FILETIME) As Long
Public Declare Function FileTimeToSystemTime Lib "Kernel32" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
#End If
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Public Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
A sintaxe #If VBA7 Então ... # Else ... # End If, PtrSafe palavra-chave, e LongPtr tipo de dados são usados para permitir que o código seja executado na versão 64 bits do Office (ver este artigo MSDN para mais informações).
Novamente, conforme mencionado acima, o código como está (usando o Microsoft Script Control), não será executado no Office 64 bits. Mas, se decidir escrever alternativas / uso que não precisam Microsoft Script Control (ou no caso aparentemente improvável que a Microsoft lança uma versão de 64 bits do msscript.ocx), vai ser útil para ter suas declarações de função API 64-bit de pronto.
CONSTANTES
A seguir, vamos definir algumas constantes. Para obtermos as chaves de API do Twitter necessárias e os tokens, precisaremos nos inscrever no Twitter como um desenvolvedor, em seguida, registrar o aplicativo.
Neste exemplo, também usaremos encurtador de links do Google para encurtar os links incluídos nos tweets. Se quiser fazer o mesmo, precisará se inscrever como um desenvolvedor do Google e obter uma chave de API.
Const cnsAPIMethodP As String = "POST"
Const cnsAPIMethodG As String = "GET"
Const cnsOauthConsumerKey As String = "yourtwitterconsumerkey"
Const cnsOauthConsumerSecret As String = "yourtwitterconsumersecret"
Const cnsOauthToken As String = "yourtwitteraccesstoken"
Const cnsOauthTokenSecret As String = "yourtwitteraccesstokensecret"
Const cnsURLPost As String = "https://api.twitter.com/1.1/statuses/update.json"
Const cnsURLMedia As String = "https://api.twitter.com/1.1/statuses/update_with_media.json"
Const cnsURLStatus As String = "https://api.twitter.com/1.1/help/configuration.json"
Const cnsMethod As String = "HMAC-SHA1"
Const cnsOauthVersion As String = "1.0"
'Following only necessary if using Google's goo.gl link shortener API
Const cnsGoogleShortenerURL As String = "https://www.googleapis.com/urlshortener/v1/url"
Const cnsGoogleShortenerKey As String = "yourgoogleshortenerkeyhere"
Funções auxiliares
Em seguida, olharemos para algumas funções auxiliares para criar / enviar nossos tweets.
O LocalTimeToUTC função converte um valor de data em formato UTC. Graças ao código do Allen Wyatt.
Public Function LocalTimeToUTC(dteTime As Date) As Date
Dim dteLocalFileTime As FILETIME
Dim dteFileTime As FILETIME
Dim dteLocalSystemTime As SYSTEMTIME
Dim dteSystemTime As SYSTEMTIME
dteLocalSystemTime.wYear = CInt(Year(dteTime))
dteLocalSystemTime.wMonth = CInt(Month(dteTime))
dteLocalSystemTime.wDay = CInt(Day(dteTime))
dteLocalSystemTime.wHour = CInt(Hour(dteTime))
dteLocalSystemTime.wMinute = CInt(Minute(dteTime))
dteLocalSystemTime.wSecond = CInt(Second(dteTime))
Call SystemTimeToFileTime(dteLocalSystemTime, _
dteLocalFileTime)
Call LocalFileTimeToFileTime(dteLocalFileTime, _
dteFileTime)
Call FileTimeToSystemTime(dteFileTime, dteSystemTime)
LocalTimeToUTC = CDate(dteSystemTime.wMonth & "/" & _
dteSystemTime.wDay & "/" & _
dteSystemTime.wYear & " " & _
dteSystemTime.wHour & ":" & _
dteSystemTime.wMinute & ":" & _
dteSystemTime.wSecond)
End Function
O Twitter usa o OAuth Autorization para validar todas as solicitações. Um dos parâmetros necessários do OAuth é um timestamp (ou seja, o número de segundos decorridos desde 1 de janeiro de 1970 00:00:00 GMT). A função get_timestamp fornece uma seqüência timestamp no formato exigido.
Public Function get_timestamp() As String
get_timestamp = DateDiff("s", #1/1/1970#, LocalTimeToUTC(Now))
End Function
A função EncodeBase64 recebe um array de bytes e converte para uma string codificada em base64. É usado para converter dados binários em uma cadeia de caracteres ASCII. Pensava que esta era uma técnica escorregadia; criar um documento XML (usando o objeto MSXML2.DOMDocument), crie um nó e e atribuia os dados binários para ele. Em seguida, basta ler a propriedade de texto do mesmo nó (MSMXL2.DOMDocument irá lidar com a conversão automaticamente). Graças a Tim Hastings para o código.
Public Function EncodeBase64(ByRef arrData() As Byte) As String
Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
Set objXML = New MSXML2.DOMDocument
' byte array to base64
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeBase64 = objNode.Text
Set objNode = Nothing
Set objXML = Nothing
End Function
O Base64_HMACSHA1 é uma função que utiliza um par de classes do namespace .Net Sistema de hash uma string em um SHA-1 digere e calcula um código de autenticação HMAC usando uma chave secreta. (você pode usar o método VBA CreateObject para utilizar quaisquer classes .Net que são 'explicitamente expostas como componentes COM') Graças ao código da HK1.
Public Function Base64_HMACSHA1(ByVal sTextToHash As String, ByVal sSharedSecretKey As String) As String
Dim asc As Object
Dim enc As Object
Dim TextToHash() As Byte
Dim SharedSecretKey() As Byte
Set asc = CreateObject("System.Text.UTF8Encoding")
Set enc = CreateObject("System.Security.Cryptography.HMACSHA1")
TextToHash = asc.Getbytes_4(sTextToHash)
SharedSecretKey = asc.Getbytes_4(sSharedSecretKey)
enc.key = SharedSecretKey
Dim bytes() As Byte
bytes = enc.ComputeHash_2((TextToHash))
Base64_HMACSHA1 = EncodeBase64(bytes)
Set asc = Nothing
Set enc = Nothing
End Function
A função binary_file_to_string recebe um arquivo binário (como um arquivo de imagem) e a converte para uma string. Vamos eventualmente usar esta função quando quisermos incluir imagens em nossos tweets. Nada muito complicado aqui; apenas ler um arquivo binário em um array de bytes, em seguida, usaremos a função VBA built-in StrConv para converter a matriz de bytes para uma cadeia Unicode.
Public Function binary_file_to_string(strFileName) As String
Dim bytArr() As Byte
Dim strConvData As String
Dim intFile As Integer
intFile = FreeFile
Open strFileName For Binary Access Read As intFile
If LOF(intFile) > 0 Then
ReDim bytArr(0 To LOF(intFile) - 1) As Byte
Get intFile, , bytArr
strConvData = StrConv(bytArr, vbUnicode)
End If
Close intFile
binary_file_to_string = strConvData
End Function
Mais tarde, em nosso código, precisaremos gerar valores únicos. A função get_GUID fornece uma maneira fácil de gerar tal string (retira caracteres não-alfanumérico, daí a remoção dos hífens do GUID e das chaves exteriores.) Graças ao código do Oorang via vbaexpress.com.