谷歌联系人API与服务帐户访问



我做了一个应用程序来插入、显示和删除我的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属性是用来指示令牌刷新时间,而不是可以存储的代码。

相关内容

  • 没有找到相关文章

最新更新