Date   

Uploading Pictures via API getting inadequate_permissions #api

Eric di Domenico
 
Edited

I keep getting an inadequate_permissions when trying to add photos via the api.

Logging in and creating an album work but not adding the photo.

curl "https://groups.io/api/v1/addphotos" -H 'Cookie: groupsio=XXXX' -F "csrf=1691885163244178649" -F "album_id=212217" -F fileupload=spec/fixtures/image.jpeg && echo $?
{"object":"error","type":"inadequate_permissions","extra":""}
0

I've tried this using a Ruby script as well and I get the same error. I have also run this using the Paw.app... same error

Am I doing something wrong or is the add photos not working?

Edit: XXX used instead of actual cookie content of course.


Re: Example signup form?

sierragamers@...
 

Greetings Alison,

My application is probably very different. I'm using Dot Net from the server side. That said, I'm putting some code at the end of this message. 

The thing I struggled with was that I couldn't get dot net to post to Groups.IO's servers. I had a couple of challenges that were easily overcome, but only after I discovered what they were. Specifically, the authentication is two-fold; the CSRF .. AND, the cookie that is obtained when you log in. Being server side, I had to create an empty cookie container, collect a cookie on the login and then give it back later for the DirectAdd call. My second challenge took a day to solve. Apparently Groups.IO's servers want TSL1 or 2, and dot net was trying to communicate with TLS 3. All I knew was the call was inexplicable timing out. Argh.

Anyway .. there's no greater tip I can give you than to download Postman. https://www.getpostman.com/downloads/ I never would have figured it out otherwise. You really need to make the calls from Postman first to see the behavior. 

Anyway ... here's some excerpts from my code:

This is the method that does the login .... (It's not likely to be much help)

 
    Function loginToGroupsIo(ByVal email As String, ByVal password As String) As GioInfo
        Dim paramsInBody As Specialized.NameValueCollection = New Specialized.NameValueCollection
        Dim paramsOnUrl As Specialized.NameValueCollection = New Specialized.NameValueCollection
 
        paramsOnUrl.Add("email", email)
        paramsOnUrl.Add("password", password)
 
        Dim uri As String = "https://groups.io/api/v1/login"
 
        Dim cookieContainer As Net.CookieContainer = New Net.CookieContainer
        Dim rtn_generic As WpToolsV2.Rtn_generic = wp.GioPostHtmlv2(uri, paramsInBody, paramsOnUrl, "", cookieContainer)
        If (rtn_generic.success) Then
        Else
            reportF.Append(rtn_generic.reason)
            Return Nothing
        End If
 
        Dim js As JavaScriptSerializer = New JavaScriptSerializer
 
        Dim loginObject As Object = js.DeserializeObject(rtn_generic.reason)
        Dim userObject As Object = loginObject("user")
 
        Dim gi As GioInfo = New GioInfo
        gi.loggedInUserId = userObject("id")
        gi.csrf = userObject("csrf_token")
        gi.cookieContainer = cookieContainer
        gi.userObject = userObject
        gi.loginObject = loginObject
        Return gi
    End Function

And the code for the DirectAdd:

 
    Sub addViaDirectAdd(ByRef gi As GioInfo,
                         ByRef listOfEmails As List(Of String))
 
        Dim rtn_generic As WpToolsV2.Rtn_generic = Nothing
        Dim js As JavaScriptSerializer = New JavaScriptSerializer
        Dim paramsInBody As Specialized.NameValueCollection = New Specialized.NameValueCollection
        Dim paramsOnUrl As Specialized.NameValueCollection = New Specialized.NameValueCollection
 
        paramsInBody.Add("group_id", gi.groupid)
        paramsInBody.Add("group_name", gi.group_name)
        Dim newLine As String = vbCrLf
        Dim f As FastString = New FastString
        For Each email As String In listOfEmails
            f.Append(email & newLine)
        Next
 
        paramsInBody.Add("emails", f.concat)
        paramsInBody.Add("csrf", gi.csrf)
 
        Dim uri As String = "https://groups.io/api/v1/directadd"
 
        rtn_generic = wp.GioPostHtmlv2(uri, paramsInBody, paramsOnUrl, "", gi.cookieContainer)
 
 
        If (rtn_generic.success) Then
        Else
            reportF.Append(rtn_generic.reason)
            Return
        End If
 
    End Sub

Something worth noting ... 

Login is simple -- the parameters go on the URL. All of the other calls use the parameters inside the body of the email.

Here is the source for my actual method that does the posting. It won't help you .. but .. someone down the line might find it useful...

There is a lot of useless code within the method. I struggled to get it to work, so I was logging everything after every call so I could see what was happening. And, the code is a bit messy because "posting comes in various flavors" and I tried them all. At one point I was posting as a multi-part form, etc. 

Anyway .. I hope all this helps. Good luck!

 
    Public Function GioPostHtmlv2(
ByVal uri As String,
ByVal parametersInBody As Specialized.NameValueCollection,
ByVal parametersOnUrl As Specialized.NameValueCollection,
ByVal accessToken As String,
ByRef cookieContainer As CookieContainer) As Rtn_generic
        Dim f As FastString = New FastString
        f.Append("URI: " & uri & vbCrLf)
 
 
        ' make a parameter list
 
        Dim parametersf As FastString = New FastString
        Dim allKeys() As String = parametersOnUrl.AllKeys
 
        Dim firstTime As Boolean = True
        For Each key As String In allKeys
            If (firstTime) Then
                firstTime = False
                parametersf.Append("?")
            Else
                parametersf.Append("&")
            End If
            parametersf.Append(key & "=")
            parametersf.Append(HttpContext.Current.Server.UrlEncode(parametersOnUrl(key)))
        Next
 
        Dim postData As String = parametersf.concat
        If (postData Is Nothing) Then
            postData = ""
        End If
        uri &= postData
 
        f.Append("URI with Parms: " & uri & vbCrLf)
 
        System.Net.ServicePointManager.SecurityProtocol =
                        SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12
 
        Dim rtn As Rtn_generic = New Rtn_generic
 
 
        Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)
 
        request.ContentType = "application/x-www-form-urlencoded"
        f.Append(request.ContentType & vbCrLf)
 
        request.Method = "POST"
        request.KeepAlive = True
        request.Credentials = Net.CredentialCache.DefaultCredentials
        request.PreAuthenticate = True
        request.Accept = "application/json"
        If (accessToken = "") Then
        Else
            request.Headers.Add("Authorization", "Bearer " & accessToken)
        End If
 
        request.CookieContainer = cookieContainer
 
        Using requestStream As IO.Stream = request.GetRequestStream()
            parametersf.Reset()
 
            allKeys = parametersInBody.AllKeys
 
            firstTime = True
            For Each key As String In allKeys
                If (firstTime) Then
                    firstTime = False
                    parametersf.Append("")
                Else
                    parametersf.Append("&")
                End If
                parametersf.Append(key & "=")
                parametersf.Append(HttpContext.Current.Server.UrlEncode(parametersInBody(key)))
            Next
 
            postData = parametersf.concat
            If (postData Is Nothing) Then
                postData = ""
            End If
            f.Append("Parameters in the body:" & vbCrLf)
            f.Append(postData & vbCrLf)
            Dim parameterBytes As Byte() = Text.Encoding.UTF8.GetBytes(postData)
 
            requestStream.Write(parameterBytes, 0, parameterBytes.Count)
 
        End Using
 
        Dim response As Net.WebResponse = Nothing
 
        Try
 
            response = request.GetResponse()
 
            Using responseStream As IO.Stream = response.GetResponseStream()
 
                Using responseReader As New IO.StreamReader(responseStream)
 
                    Dim responseText = responseReader.ReadToEnd()
                    Diagnostics.Debug.Write(responseText)
                    rtn.success = True
                    rtn.reason = responseText
                End Using
 
            End Using
 
        Catch exception As Net.WebException
 
            response = exception.Response
 
            If (response IsNot Nothing) Then
 
                Using reader As New IO.StreamReader(response.GetResponseStream())
 
                    Dim responseText = reader.ReadToEnd()
                    Diagnostics.Debug.Write(responseText)
                    rtn.success = False
                    rtn.reason = responseText
                End Using
 
                response.Close()
 
            End If
 
        Finally
 
            request = Nothing
 
        End Try
 
        rtn.log = f.concat
 
        Return rtn
    End Function



Re: Example signup form?

ajomccauley@...
 

Thank you!  I actually have a premium subscription, so I can use direct add, yay!

So, I'm a web developer, I know PHP, MySQL, some Python, and some JavaScript, BUT, I haven't used REST, and I'm just, lost about where to start.  In particular, I don't understand how I would authenticate with the API, so that it lets me perform actions.

Any chance you have an example you wouldn't mind sharing, to help me get off the ground...?

Thanks so much!
-Alison


Re: Example signup form?

sierragamers@...
 

One tip for anyone experimenting with the API...

Download the free Windows utility called "Postman". I tested every api call in Postman prior to writing code. It saved me a ton of time.

PS I have no affiliation with whoever makes the utility other than having enjoyed using it.


Re: Example signup form?

sierragamers@...
 

There are a couple of subtle nuances to this....

Registering a user is easy (two api calls, login and registeruser). However, that only adds the user and doesn't subscribe them to your group. They can't be subscribed (added to your group) until they confirm their email address. Thus, adding them as a user is somewhat useless. 

There is a "directadd" api call that is great, but requires a paid premium subscription. I experimented with it yesterday and found it worked great. It adds the user to the group immediately (although they still have to create an account the first time they sign in)

In your case, what may make the most sense is to simply have them use an online form to sign up, from which you trigger a invitation to be sent (the invite endpoint). The invitation will give the user everything they need to create a password and join the group.

-Ken W


Re: BREAKING CHANGES #important

ajomccauley@...
 

Hi and thank you!  Did the change happen at the end of September?  I'm new to groups.io and the API, poking around, and when I ran the login object, it included a token field with a super long string in it -- but I see the cookie authentication info in the documentation, so, just wanted to check.  Thanks!


Example signup form?

ajomccauley@...
 

Hi! Can I use the API to create a custom member signup form?  I've looked in the docs, but I'm not sure if I'm not understanding how, or if I'm "not understanding" because it isn't possible to do.

Does anyone have an example of a custom signup form using the API (like that I could put on our organization website) they'd be willing to share or explain or both?

Thanks so much!


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

You wouldn't happen to have an example of mbox format would you? 

I've found a few articles, like this one:

https://www.jagwaresoftware.com/blog/what-is-a-mbox-file.html

But they don't seem to address what to do for replies to a message. Let's say I have an original posting and 10 replies... 

Do I just assume that if the subject line is the same the groups.io import will see anything after the first one as a reply?

I'll keep googling...

-Ken W


Re: Help! I'm confused on how to migrate via the api

Gilbert Coville <gilbert-groups@...>
 

That does sound like the best bet. The yahoo group transfers that have been occurring are all imported very nicely, so I imagine that a user list and mail corpus in mbox format will import very nicely as well.

Gilbert

On Nov 22, 2019, at 3:22 PM, sierragamers via Groups.Io <sierragamers=kensblog.com@groups.io> wrote:

Gilbert -- a frustrating day.

I could not find a way to post a message with a date. And .. then I couldn't find a way to post a message and know the message id I posted .. The getdraft call is supposed to return a draft object with a message_id in it, but it always returns zero.

You probably saw Mark Fletcher's comment that the API can't do what I wanted it to do. Darn! I thought I could work around it by just posting all the old messages under the single user name "Imported message from old board" .. but ..even that isn't working.

Mark suggested converting to a format he could import. I'll investigate that route tomorrow...

-Ken W


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

Gilbert -- a frustrating day. 

I could not find a way to post a message with a date. And .. then I couldn't find a way to post a message and know the message id I posted .. The getdraft call is supposed to return a draft object with a message_id in it, but it always returns zero. 

You probably saw Mark Fletcher's comment that the API can't do what I wanted it to do. Darn! I thought I could work around it by just posting all the old messages under the single user name "Imported message from old board" .. but ..even that isn't working.

Mark suggested converting to a format he could import. I'll investigate that route tomorrow...

-Ken W


Re: Help! I'm confused on how to migrate via the api

 

Ken,

On Fri, Nov 22, 2019 at 11:23 AM sierragamers via Groups.Io <sierragamers=kensblog.com@groups.io> wrote:

I am writing code to migrate an existing discussion board with thousands of users and posts. I need to insert all the existing messages via the API and can't do so so without having a registered user to post them under. If I post them under my userid -- then it will appear that I posted thousands of messages. And, if I post them as the users who originally wrote the messages -- they can't be posted until the user registers. 


The API is not designed for that and there is no way for you to do that using the API. If you can convert the messages into an mbox format, I can import them into your group, along with your users, like we do with Yahoo groups. For that, I ask that you pre-pay for a year of premium service for your group. Contact me off list if/when you're ready to go ahead with that.

Cheers,
Mark


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

In this case I was testing, so .. yes. I could use the login link. But ...

I am writing code to migrate an existing discussion board with thousands of users and posts. I need to insert all the existing messages via the API and can't do so so without having a registered user to post them under. If I post them under my userid -- then it will appear that I posted thousands of messages. And, if I post them as the users who originally wrote the messages -- they can't be posted until the user registers. 

I'm at a roadblock until I figure this out.

-Ken W


Re: Help! I'm confused on how to migrate via the api

Duane
 

On Fri, Nov 22, 2019 at 01:02 PM, <sierragamers@...> wrote:
Unfortunately I need to log them in first before they can post.
If it's an email address you own, use the Email Link to Log In button.  Otherwise there's no way to do it.

Duane


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

Darn!! I am stuck again.

I tried to post a message on behalf of a user who I registered via DIRECTADD

Unfortunately I need to log them in first before they can post. 

The login interface requires a username and password. I can't obtain a CSRF token without logging them in. And, I can't get a draft posting without a CSRF for the user.

Any ideas anyone?

-Ken Williams


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

Gilbert: 

I should have that answer for you in the next couple of hours... I will post here what I learn.

-Ken W


Re: Help! I'm confused on how to migrate via the api

Gilbert Coville <gilbert-groups@...>
 

When you import your messages, I’ll be very interested to know if they are entered (and placed into the message count matrix on the group’s home page) as the date/time that you perform the operation, or whether they take the date/time from the “Date:” lines in the messages.

The experiments I’ve tried by sending messages to the group (spoofed as original owners) took on the date/time of when they were received, not from the “Date:” header.

The Yahoo group transfers are using the original date/time info. That might be something that’s not available via the api.

Gilbert

On Nov 22, 2019, at 10:22 AM, sierragamers via Groups.Io <sierragamers=kensblog.com@groups.io> wrote:

I upgraded and tried the DirectAdd API.

It works fine, and is what I'll use for migration. It did do one thing I don't love ...

It sends an email to users that I can't stop. It means I can't get everything imported and THEN alert everyone. It will alert all the users immediately when I add them to the group and start the message import. Oh well ... I just hate spamming people when it can be avoided.

Thank you! This is looking very possible...


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

I upgraded and tried the DirectAdd API. 

It works fine, and is what I'll use for migration. It did do one thing I don't love ... 

It sends an email to users that I can't stop. It means I can't get everything imported and THEN alert everyone. It will alert all the users immediately when I add them to the group and start the message import. Oh well ... I just hate spamming people when it can be avoided.

Thank you! This is looking very possible... 


Re: Help! I'm confused on how to migrate via the api

sierragamers@...
 

Hmmm ... So .. I have several sites I'm migrating. They have thousands of posts and thousands of users. I wanted to migrate everything over and then let the users know. The problem will be that if it sends them all an email before I am ready to "go live" they are going to be confused. 

Oh well .. never a dull moment. I'll experiment and see what I can do.

Thank you! Much appreciated! Hopefully I can return the favor someday.

-Ken W


Re: Help! I'm confused on how to migrate via the api

Andrew Schaefer
 

The users get an email stating that they have been added, and it lets them finish setting up their account.

BTW I'm just a customer like you.

On Fri, Nov 22, 2019 at 12:28 PM sierragamers via Groups.Io <sierragamers=kensblog.com@groups.io> wrote:
Thank you! I saw that, and am happy to upgrade the site to premium. (The rest API says the site needs to be upgraded to use the directadd call)

The parameters to Directadd only are email address -- it doesn't have a password. So .. I was confused about what would happen to the user account. Does it generate them a fake password? Or what happens?

As soon as I get your subscription I'll upgrade to premium and give it a try.

-Ken W



Re: Help! I'm confused on how to migrate via the api

Duane
 

On Fri, Nov 22, 2019 at 11:28 AM, <sierragamers@...> wrote:
Does it generate them a fake password? Or what happens?
It just creates the account.  No password needed to log in, but one can be set if wanted.  See https://groups.io/g/GroupManagersForum/wiki/Logging-In

Duane

81 - 100 of 230