Google+无法插入时刻 - 之后的一年和6次修订

时间:2014-03-17 09:52:29

标签: api oauth google-api google-plus google-api-dotnet-client

注意:使用登录按钮一个选项

一年前,我遇到了创造片刻的问题。当时我使用的是Google+ API .Net客户端版本1.2。正如我所描述的in this post,虽然代码不时插入片刻,但我还是有效。我希望这个过程现在更稳定,更容易实现,看起来可以在示例中看到你可以download here - 本文中的当前版本是v1.8。因此,我根据下载中的SimpleOAuth2示例创建了一个简单项目,但实施了Google+。这是我提出的代码:

public partial class _Default : System.Web.UI.Page
{        
    private PlusService service;

// Application logic should manage users authentication. 
// This sample works with only one user. You can change
// it by retrieving data from the session.
private const string UserId = "user-id";

protected void Page_Load(object sender, EventArgs e)
{
    GoogleAuthorizationCodeFlow flow;
    var assembly = Assembly.GetExecutingAssembly();
    using (var stream = assembly.GetManifestResourceStream(
          "GPlusSample.client_secrets.json"))
    {
        flow = new GoogleAuthorizationCodeFlow(
                   new GoogleAuthorizationCodeFlow.Initializer
        {
            DataStore = new FileDataStore("GPlusSample.Store"),
            ClientSecretsStream = stream,
            // 
            // Tried only this scope but it did not work
            //Scopes = new[] { PlusService.Scope.PlusMe }
            //
            // I tried the following: but did not work either
            //Scopes = new[] { PlusService.Scope.PlusMe, 
            //            "https://www.googleapis.com/auth/plus.moments.write" }
            //
            // I tried this as well and it failed
            //Scopes = new[] { PlusService.Scope.PlusLogin }
            //
            // Maybe this... but still no joy
            Scopes = new[] { PlusService.Scope.PlusLogin, 
                             PlusService.Scope.PlusMe }
        });
    }

    var uri = Request.Url.ToString();
    var code = Request["code"];
    if (code != null)
    {
        var token = flow.ExchangeCodeForTokenAsync(UserId, code,
            uri.Substring(0, uri.IndexOf("?")), CancellationToken.None).Result;

        // Extract the right state.
        var oauthState = AuthWebUtility.ExtracRedirectFromState(
            flow.DataStore, UserId, Request["state"]).Result;
        Response.Redirect(oauthState);
    }
    else
    {
        var result = new AuthorizationCodeWebApp(flow, uri, uri)
            .AuthorizeAsync(UserId, CancellationToken.None).Result;
        if (result.RedirectUri != null)
        {
            // Redirect the user to the authorization server.
            Response.Redirect(result.RedirectUri);
        }
        else
        {
            // The data store contains the user credential, 
            // so the user has been already authenticated.
            service = new PlusService(new BaseClientService.Initializer
            {
                ApplicationName = "Plus API Sample",
                HttpClientInitializer = result.Credential
            });
        }
    }
}

/// <summary>Gets the TasksLists of the user.</summary>
public async System.Threading.Tasks.Task InsertMoment()
{
    try
    {                
        var me = service.People.Get("me").Execute();

        var request = service.Moments.Insert(new Moment()
        {
            Target = new ItemScope { 
                Id=Guid.NewGuid().ToString(),
                Image="http://www.google.com/s2/static/images/GoogleyEyes.png",
                Type="",
                Name = "test message",
                Description="test",
                Text="test message",                        
            },
            Type = "http://schemas.google.com/AddActivity",                    
        }, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
        var response =await request.ExecuteAsync();
        output.Text = "<h1>" + response.Id + "</h1>";
    }
    catch (Exception ex)
    {
        var str = ex.ToString();
        str = str.Replace(Environment.NewLine, Environment.NewLine + "<br/>");
        str = str.Replace("  ", " &nbsp;");
        output.Text = string.Format("<font color=\"red\">{0}</font>", str);
    }
} 

protected async void createMomentButton_Click(object sender, EventArgs e)
{
    await InsertMoment();
}
}

该代码总是给我一个401 Unauthorized错误,即使我的项目已启用Google+ API 。这是我得到的实际错误:

  

service plus引发了异常:Google.GoogleApiException:   Google.Apis.Requests.RequestError未经授权[401]错误[   消息[未经授权]位置[ - ]原因[未经授权]   域[全球]]

有趣的是,即使对People.Get(&#34; me&#34;)的调用有效,插入时刻也会失败 - get(&#34; me&#34;)可以使用我在上面列出的所有范围组合。重要的是要注意每次尝试新范围时,我首先退出我的Google帐户并删除存储在GPlusSample.Store中的访问令牌。

修改

我尝试设置Url而不是Ian建议的单个项目,我得到了完全相同的错误。

var request = service.Moments.Insert(new Moment()
{
    Target = new ItemScope {
        Url = "https://developers.google.com/+/web/snippet/examples/thing"
        },
    Type = "http://schemas.google.com/AddActivity",
}, me.Id, MomentsResource.InsertRequest.CollectionEnum.Vault);
var response =await request.ExecuteAsync();

1 个答案:

答案 0 :(得分:0)

https://www.googleapis.com/auth/plus.login是撰写时刻的正确范围,但您还需要请求您要编写的特定应用活动类型。这个参数是request_visible_actions,它采用空格分隔的类型参数列表(在https://developers.google.com/+/api/moment-types/上列出 - 例如http://schemas.google.com/AddActivity)。

客户端库可能没有添加request_visible_actions的方法,因此您可能需要将其添加到您手动将用户重定向到的auth URL(请记住对应用程序活动类型URL进行URL编码!)