No internet connection
  1. Home
  2. Ideas

Post creation (upsert) API

By Christian Scheuer @chrscheuer
    2019-10-31 16:11:13.767Z

    Hi @KajMagnus.

    Thank you again for all your help designing & implementing the upsert API for categories.
    Our users are so happy with this feature :)

    I have another request in the same general area.
    We're building a feedback integration inside SoundFlow, and the idea is to allow users to report errors, bugs or to ask for feedback directly from within our app.
    Since we use the forum for such feedback, the idea is that we could programmatically create new threads on behalf of users.
    By doing it this way, we can ensure that their feedback includes all the relevant info we need (link to upload of compressed log files, system info, and possible state of the app etc.) - while not having to use an entirely different system for that (Talkyard is extremely good for handling feedback/support forums IMO).

    Would it be possible to extend the general upsert API to include creating new threads?

    • 32 replies

    There are 32 replies. Estimated reading time: 18 minutes

    1. Yes, & I like this idea. Something like this?:

      POST /-/v0/upsert-simple
      

      With a JSON payload like:

      {
        pages: [
          extId: ...,
          pageType: PageType.Problem,
          categoryRef: "extid:the-category's-external-id",
          createdByRef:  "ssoid:the-single-sign-on-id-for-the-user",
          title: "Error when ...",
          bodyHtmlUnsafe: "<p>There was this problem when ... Details:</p><pre> .... system info, app state .... </pre>",
        ]
      }
      
      1. CChristian Scheuer @chrscheuer
          2019-11-01 18:25:47.516Z

          Yay! Yea sounds like a good start :)
          And then we'd get a response back with a URL or enough info to construct a URL (I imagine many of the same thoughts that went into the category upsert API design will also apply here).
          One great thing here is we won't have to worry about the upsertion and slug creation - this will be more simple one-off inserts 99.99% of the time.

          1. Yes, what about the server returning this:

            {
              pages: [{
                id: ...,
                ...,
                urlPaths: {
                  canonical: '/path/to/page',
                  redirects: ['/old-path-now-redirects-to-canonical-path', '/another/old']
                }
              }]
            }
            

            Similar to the upsert-category request, which returns:

            {
              categories: [{
                id: ...,
                urlPaths: {
                  activeTopics: ...,
                  newTopics: ...,
                  topTopics: ...,
                }
              }]
            }
            

            (Sorry for the late reply — I've been working with more complete exports & imports of one's site, ... + moved to a different place here where I am now.)

            1. CChristian Scheuer @chrscheuer
                2019-11-12 16:02:45.958Z

                Yes this looks great :)

                1. CChristian Scheuer @chrscheuer
                    2019-11-13 23:42:02.144Z

                    A related API (we should probably discuss this in a separate thread but thought I would first mention it here for context) would be that we'd like to be able to query for a user's most recent contributions.

                    The feedback workflow we'd like for users in our app would be:

                    • Send feedback
                    • Choose between creating a new issue or adding to an existing one.

                    Now if they choose to create a new issue, we'd need the page creation API that we're discussing here.
                    If they choose to append feedback to an existing issue, we'd need a 3rd API to be able to add a post/reply to an existing page/thread.

                    The reason why we would need this, is that sometimes issues will have been manually created in the forum, or we'd need more than one set of logs for the same issue.

                    The option to add to an existing issue is what would require an API for us to list most recent issues that a user has contributed to or has been mentioned in. Maybe this could eventually evolve into a generic search API (I actually would probably prefer that). If it were a generic search API, then we could also use it for stuff like users searching for help with an issue, and then listing potentially matching issues. Close to what happens today inside Talkyard when creating a new post.

                    1. I like the idea of having such a find-topics-by-user / generic search API.

                      The add-post/reply API:

                      Would you want to reply to existing posts? Then you'd need the parent post's nr or extid: ... to refer to, in addition to the page's id.
                      Or would you like to append posts at the bottom of the page? (Then no parent post nr needed)

                      what about POST /-/v0/upsert-simple and this JSON:

                      {
                        posts: [{
                          extId: ...,
                          pageRef: "extid:the-page's-external-id",
                          parentNr: 123,   <— if replying to a specific post
                          createdByRef: "ssoid:the-single-sign-on-id-for-the-user",
                          text: "<p>I forgot to mention that ... </p>",
                          postType: PostType.Discussion  or  PostType.Progress
                        }]
                      }
                      

                      And a response like:

                      {
                        posts: [{
                          id: ...,
                          urlPath: ....,
                          nr: ...,
                          parentNr: ...,
                          postType: ...
                          text: ...,
                        }]
                      }
                      
                      1. CChristian Scheuer @chrscheuer
                          2019-11-23 05:01:45.771Z

                          This sounds great. Can you remind me what the ssoid: would be - would this be our external ID (ie. our own customer ID)?
                          I love how easy it seems to review this API given all the thorough work we did on the previous one :)

                          Given the amount of feedback we're receiving from users right now it is a very high priority for us to get automated feedback working so here's my vote for getting the page creation API up and running soon :) IMO the generic search API (I'm starting to gravitate towards using a TY API for search instead of our own engine as we previously discussed) could be 2nd in priority, and 3rd would be post addition to existing pages.

                          1. ssoid: is the SIngle Sign-On id. You can use that, or you can use extid: (external id) — whatever works best for you. I'd guess the ssoid and extid would be the same, in your case, and maybe most / almost-all cases for other communities too.

                            Yes I think most of the hard work has been done.

                            here's my vote for getting the page creation API up and running soon

                            I started looking into the iframe problem and people who got error messages when they posted comments. ... At the same time, making this page upsert API work, wouldn't take that long.

                            1. CChristian Scheuer @chrscheuer
                                2019-11-25 08:12:57.310Z

                                Sounds great! We were able to switch back from the iframe - there was a feature switch in Electron I hadn't noticed yet. So problem with iframe is averted for now :)

                                1. The page upsert API works now (on my localhost), ... Now I'm writing e2e tests, this took longer than what I thought (+ was away most of the day yesterday). I think I'll release a new server on Friday (sorry for the delay).

                                  1. CChristian Scheuer @chrscheuer
                                      2019-11-27 16:31:04.464Z

                                      Yay, awesome!! I'm still working on the feedback integration on our end here. It's gonna be super sweet :)

                                      1. Wow, this looks nice :- ) I'm thinking text people type in these different fields will get converted to HTML?

                                        Currently the Upsert API assumes the text one upserts, is formatted in HTML. Maybe there should be a way to choose CommonMark instead? There're the fields title and body, and, there could be another field bodyMarkupLang that you could set to CommonMark?

                                        1. CChristian Scheuer @chrscheuer
                                            2019-12-04 10:54:11.301Z

                                            Thank you :) Wonderful news - no worries about the delay, happy you're all fine again now!

                                            Oh yea that's a good point about the markdown.
                                            We have a rich text editor for SF but for simplicity I didn't turn that on in these fields yet.
                                            I'm fine that we have to do the conversion to HTML.
                                            It appears you're normally using markdownit with this setup right?

                                            markdownit({ html: true, linkify: true, breaks: true });
                                            

                                            It makes sense to me that we just use our own conversion to HTML. If we at some point switch to our own rich text editor (the one that powers our CMS and internal documentation system, based on slatejs), we would still need an HTML endpoint from TY. So it's not a big deal to not have a markdown endpoint.

                    2. Progress
                      with doing this idea
                    3. @KajMagnus marked this topic as Planned 2019-11-11 14:11:32.497Z.
                    4. Hi Christian, now I've upgraded this server, Talkyard .io, to a version with the upsert-pages API. I'll upgrade the Talkyard .net server tomorrow morning probably.

                      Here's an End-to-End test that shows how you can use the usert-pages API, combined with Single Sign-On:
                      https://github.com/debiki/talkyard/blob/master/tests/e2e/specs/api-w-sso-upsert-pages.2browsers.test.ts

                      (Here's without Single Sign-On, normal password login instead:
                      https://github.com/debiki/talkyard/blob/master/tests/e2e/specs/api-upsert-pages.2browsers.test.ts )

                      (This took a bit longer than to last Friday — I was away one whole day, and then I caught a cold and was in bed. Now all fine again :- ))

                      1. @KajMagnus marked this topic as Started 2019-12-02 06:12:31.424Z.
                      2. Now I've upgraded your server.

                        Let me know some time later when you have had time to try out the API :- )

                        1. C
                          Christian Scheuer @chrscheuer
                            2019-12-04 11:06:01.831Zreplies toKajMagnus:

                            NICE - thank you! Can't wait to try it out :)

                            1. C
                              Christian Scheuer @chrscheuer
                                2019-12-04 12:44:26.283Zreplies tochrscheuer:

                                Hi @KajMagnus.

                                I've tried it out now.
                                Here's the first result:
                                https://forum.soundflow.org/-1372/test-issue-5

                                I'm sending HTML to the "body" string, stuff like <h4>...</h4> but those seem to be stripped out by the API.
                                Any thoughts on what we should do instead?

                                1. I'll fix in the next version. This is probably me using basicWithImages (sorry) like so:

                                  Jsoup.clean(
                                    approvedSource, Whitelist.basicWithImages)))
                                  

                                  because now when I had a closer look, I noticed that basicWithImages doesn't allow things like <h1> <h2> and <table>.

                                  I'll change to: Whitelist.relaxed, which allows all that. Note:

                                  Links do not have an enforced rel=nofollow attribute, but you can add that if desired.

                                  So probably you want to inject rel=nofollow into any links people insert?

                                  Docs: https://jsoup.org/apidocs/org/jsoup/safety/Whitelist.html

                                  1. C
                                    Christian Scheuer @chrscheuer
                                      2019-12-04 17:31:42.250Zreplies toKajMagnus:

                                      So probably you want to inject rel=nofollow into any links people insert?

                                      Good point :) We'll add a nofollow rewrite rule to the markdownit renderer to process this.

                                      And thanks, would be great to have header support (and table too).

                                      1. Hi Christian, probably I'll upgrade your server tomorrow.

                                        I just upgraded this server Talkyard .io with the next version, which keeps <h1> <h2> ... etc, + debug friendly SSO login secret error messages. Have a nice weekend :- )

                                        1. C
                                          Christian Scheuer @chrscheuer
                                            2019-12-13 20:07:31.140Zreplies toKajMagnus:

                                            Awesome! Thanks for the update :)

                                            1. Now I've upgraded the server, ... Let me know when you've tried out the <h4> and SSO error messages :- )

                                              1. C
                                                Christian Scheuer @chrscheuer
                                                  2019-12-19 11:31:01.173Zreplies tochrscheuer:

                                                  One important thing I'm noticing is that I don't get notifications from new issues created with the API.
                                                  Not sure if that's by design (I can understand the arguments why) but on the other hand right now I am missing the threads people create via the API since I'm used to using the emails as my reference for what I should check.

                                                  1. Hi Christian, I'll make Talkyard send notifications for new issues created with the API.

                                                    I'm thinking about if this should be the default behavior, or not? Some thoughts:

                                                    • Maybe /-/upsert-simple could generate notifications by default.
                                                    • Whilst other endpoints for importing a complete site dump with 9999 items, would not do that.
                                                    • And/or Talkyard could look at timestamps: If the imported things have timestamps from long ago, then no notifications? And if timestamps are missing or shows the current time, then the items are new, and notifications get sent? (Or maybe this'd make API users confused)
                                                    • There could be an URL parameter, like &sendNotifications=true/false? Or a sendNotifications: true/false field in the JSON payload somewhere.

                                                    Any thoughts?

                                                    Glad to hear that it works :- )

                                                    1. C
                                                      Christian Scheuer @chrscheuer
                                                        2019-12-19 20:16:25.039Zreplies toKajMagnus:

                                                        Good thoughts...
                                                        I think having a discrete parameter to control whether to send notifications is better than "magic logic".
                                                        I'm fine if it defaults to be off - since right now the API supports inserting many items already.
                                                        I would generally think it would be weird to have to specify options via query parameters when also sending JSON payload data. It would be cleaner IMO to have it all be part of the JSON.
                                                        Maybe have an options object in the root, next to the categories and pages arrays, which could hold stuff like sendNotifications?

                                                        1. an options object in the root

                                                          That sounds like a good idea to me. It could be named upsertOptions so one won't confuse it with some settings or options object getting inserted into the settings database table. I'll look into this over the weekend and early next week (some days will disappear because of travelling & Christmas).

                                                          1. C
                                                            Christian Scheuer @chrscheuer
                                                              2019-12-27 19:57:45.230Zreplies toKajMagnus:

                                                              Sounds great :) Hope you're enjoying the holidays!

                                                              1. Thanks, yes nice Christmas holidays back in Gothenburg ... I was away for quite a while.

                                                                On Wednesday, most likely I'll upgrade your server to the next version, with upsertOptions.sendNotifications. POST this json:

                                                                {
                                                                  upsertOptions: { sendNotifications: true },
                                                                  pages: [pageToUpsert],
                                                                }
                                                                

                                                                Here's an end-to-end test with details: (I think the above info should be enough though)
                                                                https://github.com/debiki/talkyard/blob/177188d19a87c2d0abdd9f6e4e8a3915472cc020/tests/e2e/specs/api-upsert-page-notfs.2browsers.test.ts

                                                                1. C
                                                                  Christian Scheuer @chrscheuer
                                                                    2019-12-30 20:51:36.640Zreplies toKajMagnus:

                                                                    Wonderful, that looks great :) Thank you Magnus! I'll wait updating our code until you've launched the update just to be sure.

                                                                    1. Now I've upgraded your server to the new version

                                                                      1. C
                                                                        Christian Scheuer @chrscheuer
                                                                          2020-01-01 23:49:49.298Zreplies toKajMagnus:

                                                                          Awesome, thank you!