具有服务帐户访问权限的Google通讯录API

时间:2015-07-07 21:48:58

标签: .net vb.net google-api google-contacts service-accounts

我制作了一个申请,可以从我的Google帐户中插入,显示和删除联系人。它在2周前正常运行,但在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.在插入联系之前,分配给"我的联系人" (饲养所有群体的第1组):

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

此功能正在运作,但不符合预期:我可以插入新条目,正常删除和查看条目,但在我的Google帐户中#34; myaccount@google.com"一切都没有发生。在对foruns进行一些搜索之后,我怀疑他们是在服务帐户" myserviceaccount@developer.gserviceaccount.com",以便解决问题:

有人可以指定范围,凭据或此代码的其他部分中的错误以及我如何使服务帐户访问权限保存我的" myaccount@google.com"联系人?

2 个答案:

答案 0 :(得分:0)

我认为您无法使用服务帐户。服务帐户是其自己的SUDO用户,它有一个驱动器帐户,一个Google日历帐户,可能还有一个联系人帐户,就像任何其他用户一样。

据说除非您提供访问权限,否则它无权访问您的个人Google通讯录,据我所知,无法授予其他人访问您的联系人的权限。您一直在做的是将用户插入服务帐户Google通讯录帐户。

我建议你研究一下使用Oauth2,使用你的Google帐户验证你的代码,然后存储刷新令牌。下次运行代码时,可以使用刷新令牌为您获取新的访问令牌。您将不得不第一次通过身份验证过程。

答案 1 :(得分:0)

已解决此范围:

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属性用于表示令牌刷新时间,而不是它是可以存储的代码。