我做了一个应用程序来插入、显示和删除我的Google帐户中的联系人。直到两周前,它才正常运行,但在谷歌停止支持客户端登录(用户/密码访问)之后,迫使使用OAuth2通过令牌访问,这是一个巨大的问题(我不是专业的软件开发)。
在更新后进行了广泛的搜索,我已经将我的代码调整为以下逻辑:
Const service_id = "My_Service_ID.apps.googleusercontent.com"
Const service_email = "My_Service_Account_Email@developer.gserviceaccount.com"
Const nome_aplicacao = "My_Application_Name"
Const user_id = service_email
1。使用从p12密钥获得的凭据创建令牌,并返回带有该令牌的contactsRequest:
Private Function CriaContactRequest() As ContactsRequest
Try
Dim certificate As New X509Certificate2(Server.MapPath("/chave/key.p12"), "notasecret", X509KeyStorageFlags.Exportable)
Dim credential As New ServiceAccountCredential(New ServiceAccountCredential.Initializer(service_email) With { _
.Scopes = New String() {"https://www.google.com/m8/feeds https://www.google.com/m8/feeds/groups/default/full"}
}.FromCertificate(certificate))
credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait()
Dim rs = New RequestSettings(nome_aplicacao) With { _
.OAuth2Parameters = New OAuth2Parameters() With { _
.AccessToken = credential.Token.AccessToken, .RefreshToken = "6000" _
} _
}
Dim cr As New ContactsRequest(rs)
Return cr
Catch ex As Exception
Throw ex
End Try
End Function
2。显示所有联系人:
Public Sub ExibeContatos()
Try
Dim f As Feed(Of Contact) = CriaContactRequest().GetContacts()
If f.Entries.Count > 0 Then
' Loop to show contacts here....
Else
Response.Write("Não existem contatos.")
End If
Catch ex As HttpException
Response.Write("Erro Exibe Contatos: " & ex.Message)
End Try
End Sub
3。插入联系人:
Public Sub InsereContatoGoogle(oContato As Contact)
Try
Dim feedUri As New Uri(ContactsQuery.CreateContactsUri(user_id))
InserenNoGrupoPrincipal(oContato)
CriaContactRequest().Insert(feedUri, oContato)
Catch ex As Exception
Response.Write("Erro Insere Contato Google: " & ex.Message)
End Try
End Sub
4。在插入联系人之前,分配给"我的联系人"(所有组中的第一组):
Private Function InserenNoGrupoPrincipal(oContato As Contact) As Contact
Try
Dim f As Feed(Of Group) = CriaContactRequest().GetGroups(user_id)
Dim GrupoPrincipal As New GroupMembership
GrupoPrincipal.HRef = f.Entries.ElementAt(0).Id
oContato.GroupMembership.Add(GrupoPrincipal)
Catch ex As Exception
Response.Write("Erro Insere Grupo Principal: " & ex.Message)
End Try
Return oContato
End Function
5。基于电子邮件填充的矢量删除联系人的代码:
Public Sub ApagaContato(emailToExclude As String())
Dim query As ContactsQuery = New ContactsQuery(ContactsQuery.CreateContactsUri(user_id))
query.BaseAddress = emailToExclude(0)
Dim feed As Feed(Of Contact)
Try
Dim cr As ContactsRequest = CriaContactRequest()
feed = cr.GetContacts()
For Each c As Contact In feed.Entries
For x As Integer = 0 To c.Emails.Count - 1
For y As Integer = 0 To emailToExclude.Length - 1
If c.Emails.Item(x).Address = emailToExclude(y) Then
cr.Delete(c)
End If
Next
Next
Next
Catch ex As Exception
Response.Write("Erro Apaga Contato: " & ex.Message)
End Try
End Sub
这个功能正在工作,但不像预期的那样:我可以插入新条目,删除和查看条目正常,但在我的谷歌帐户"myaccount@google.com
"没有发生任何事情。在论坛上搜索了一下之后,我怀疑他们在服务帐户"myserviceaccount@developer.gserviceaccount.com
"中,所以这就是问题所在:
有人可以指定什么是错误的范围,凭据或这段代码的其他部分,我如何使服务帐户访问保存更改在我的"myaccount@google.com"联系人?
我认为您无法使用服务帐户进行此操作。服务帐户是它自己的SUDO用户,它有一个驱动器帐户,一个Google日历帐户,可能还有一个联系人帐户,就像任何其他用户一样。
也就是说,它不能访问你的个人谷歌联系人,除非你给它访问权限,据我所知,没有办法授予其他人访问你的联系人。您所做的是将用户插入到服务帐户Google Contacts帐户中。
我建议你看看使用Oauth2,验证你的代码一次使用你的谷歌帐户,然后存储刷新令牌。下次运行代码时,可以使用刷新令牌来获得新的访问令牌。您必须在第一次进行身份验证过程。
解析此作用域:
Private Function CriaContactRequest(Optional scope As String = "https://www.google.com/m8/feeds https://www.google.com/m8/feeds/groups/default/full") As ContactsRequest
Try
Dim rs = New RequestSettings(nome_aplicacao) With { _
.OAuth2Parameters = New OAuth2Parameters() With { _
.AccessToken = refresh_token, _
.RefreshToken = refresh_token, _
.ClientId = client_id, _
.ClientSecret = client_secret, _
.RedirectUri = redirect_uri, _
.Scope = scope _
} _
}
Dim cr As New ContactsRequest(rs)
Return cr
Catch ex As Exception
Throw ex
End Try
End Function
我错误地认为refresh_token属性是用来指示令牌刷新时间,而不是可以存储的代码。