A Golang SDK for Medium's OAuth2 API

Overview

Medium SDK for Go

This repository contains the open source SDK for integrating Medium's OAuth2 API into your Go app.

Install

go get github.com/Medium/medium-sdk-go

Usage

Create a client, then call commands on it.

package main

import (
	medium "github.com/medium/medium-sdk-go"
	"log"
)

func main() {
	// Go to https://medium.com/me/applications to get your applicationId and applicationSecret.
	m := medium.NewClient("YOUR_APPLICATION_ID", "YOUR_APPLICATION_SECRET")

	// Build the URL where you can send the user to obtain an authorization code.
	url := m.GetAuthorizationURL("secretstate", "https://yoursite.com/callback/medium",
        medium.ScopeBasicProfile, medium.ScopePublishPost)

	// (Send the user to the authorization URL to obtain an authorization code.)

	// Exchange the authorization code for an access token.
	at, err := m.ExchangeAuthorizationCode("YOUR_AUTHORIZATION_CODE", "https://yoursite.com/callback/medium")
	if err != nil {
		log.Fatal(err)
	}

	// The access token is automatically set on the client for you after
	// a successful exchange, but if you already have a token, you can set it
	// directly.
	m.AccessToken = at.AccessToken

	// If you have a self-issued access token, you can skip these steps and
	// create a new client directly:
	m2 := medium.NewClientWithAccessToken("SELF_ISSUED_ACCESS_TOKEN")

	// Get profile details of the user identified by the access token.
	// Empty string mean current user, otherwise you need to indicate
	// the user id (alphanumeric string with 65 chars)
	u, err := m2.GetUser("")
	if err != nil {
		log.Fatal(err)
	}

	// Create a draft post.
	p, err := m.CreatePost(medium.CreatePostOptions{
		UserID:        u.ID,
		Title:         "Title",
		Content:       "<h2>Title</h2><p>Content</p>",
		ContentFormat: medium.ContentFormatHTML,
		PublishStatus: medium.PublishStatusDraft,
	})
	if err != nil {
		log.Fatal(err)
	}

	// When your access token expires, use the refresh token to get a new one.
	nt, err := m.ExchangeRefreshToken(at.RefreshToken)
	if err != nil {
		log.Fatal(err)
	}

	// Confirm everything went ok. p.URL has the location of the created post.
	log.Println(url, at, u, p, nt)
}

Contributing

Questions, comments, bug reports, and pull requests are all welcomed. If you haven't contributed to a Medium project before please head over to the Open Source Project and fill out an OCLA (it should be pretty painless).

Authors

Jamie Talbot

Dan Pupius

Andrew Bonventre

License

Copyright 2015 A Medium Corporation

Licensed under Apache License Version 2.0. Details in the attached LICENSE file.

Comments
  • Adding contributors and publications

    Adding contributors and publications

    Some minor suggestions. I've also modified GetUser a little bit, instead of calling only /v1/me, you can also provide other user names.

    • Providing API endpoint for other users
    • Providing API endpoint for user publications
    • Providing API endpoint for publication contributors
    opened by njuettner 5
  • Fetch the redirected url

    Fetch the redirected url

    I am writing a command line tool for publishing to Medium. This will be my first program where I access any API using golang.

    I have followed the instructions until the point where I can build a url using secret state, redirect url, and scopes.

    package main
    
    import (
        "fmt"
        "net/http"
    
        "github.com/Medium/medium-sdk-go"
    )
    
    func check(e error) {
        if e != nil {
            panic(e)
        }
    }
    
    func mediumAuth() {
        m := medium.NewClient("clientIDString", "clientSecretString")
    
        url := m.GetAuthorizationURL("supersecretstring", "http://hasit.me/callback/medium", medium.ScopeBasicProfile, medium.ScopePublishPost)
    
        //next step
    }
    
    
    func main() {
        mediumAuth()
    }
    

    The next step is to open the url to let user give permission for accessing his/her profile. I can successfully open the url.

    exec.Command("open", url).Start()
    

    Now, once the user clicks on the url, how can I fetch the redirected url? I even tried using http GET but the response is not the one that I want.

    resp, err := http.Get(url)
    

    Help will be appreciated.

    opened by hasit 4
  • all: export internal types for third-party package

    all: export internal types for third-party package

    Export several internal types. If unexported, third-party package that depends Medium/medium-sdk-go is needs large switch-case.

    For example, go core runtime exported parser.Mode type.(but it's uint, not string) https://github.com/golang/go/blob/45d42fdceaa60a51c0057222df5dace810ed13de/src/go/parser/interface.go#L53-L62

    Another example, see https://github.com/Ableton/go-travis/blob/b25a158d7c0c123f9adf8bdae591722a74d56fd4/authentication.go#L19-L22. That is can write below code.

    token := travis.AccessToken(os.Getenv("TRAVIS_ACCESS_TOKEN"))
    

    In real example, e.g: (Note that below code is rough, maybe not works)

    package main
    
    import (
    	"errors"
    	"flag"
    	"fmt"
    	"io/ioutil"
    	"log"
    	"os"
    
    	medium "github.com/Medium/medium-sdk-go"
    )
    
    var (
    	postTitle  = flag.String("title", "", "article title")
    	postStatus = flag.String("status", "", "publish status")
    )
    
    func main() {
    	flag.Parse()
    
    	m := medium.NewClientWithAccessToken(os.Getenv("MEDIUM_SECRET_ACCESS_KEY"))
    	usr, err := m.GetUser("")
    	if err != nil {
    		log.Fatal(errors.New(err, "could not get medium user information"))
    	}
    
    	mdfilename := flag.Arg(0)
    	buf, err := ioutil.ReadFile(mdfilename)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	createOption := medium.CreatePostOptions{
    		UserID:        usr.ID,
    		Title:         *postTitle,
    		Content:       string(buf),
    		ContentFormat: medium.ContentFormatMarkdown,
    	}
    	createOption.PublishStatus = *postStatus // type error
    
    	// needs...
    	// switch *postStatus {
    	// case "draft":
    	// 	createOption.PublishStatus = medium.PublishStatusDraft
    	// case "unlisted":
    	// 	createOption.PublishStatus = medium.PublishStatusUnlisted
    	// case "public":
    	// 	createOption.PublishStatus = medium.PublishStatusPublic
    	// }
    
    	// want to...
    	// createOption.PublishStatus = medium.PublishStatus(*postStatus)
    
    	_, err = m.CreatePost(createOption)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	fmt.Print("posted")
    }
    
    opened by zchee 2
  • Make client creation with self-issed tokens easier. Fixes #9

    Make client creation with self-issed tokens easier. Fixes #9

    Hello @dpup, @vinibaggio,

    Please review the following commits I made in branch 'jamie-self-issued'.

    0dc3042aae4c751351572f110b418aa72efe9fe0 (2015-10-08 13:31:45 -0700) Make client creation with self-issed tokens easier. Fixes #9

    Thoughts on naming, @dpup?

    [email protected] [email protected]

    MANUAL TESTING=not manually tested

    opened by majelbstoat 2
  • Add Markdown content type

    Add Markdown content type

    Hello @kylehg, @ktzhu,

    Please review the following commits I made in branch 'jamie-markdown-support'.

    9cd8344c637259fcd564e62149fedffd1b55dbff (2015-10-03 13:07:32 -0700) Add Markdown content type

    [email protected] [email protected]

    MANUAL TESTING=not manually tested

    Code review reminders. By giving a LGTM you attest that:

    • Commits are adequately tested
    • Code is easy to understand and conforms to our style guides
    • Incomplete code is marked with TODOs
    • Logging and metrics are suitable
    opened by majelbstoat 2
  • Make the code more idiomatic

    Make the code more idiomatic

    Hello @dpup, @vinibaggio,

    Please review the following commits I made in branch 'jamie-refinements'.

    2b662ab5818acee2ed4908979d30b59a763be712 (2015-09-29 11:07:26 -0700) Make the code more idiomatic

    [email protected] [email protected]

    MANUAL TESTING=tested with a toy app

    Code review reminders. By giving a LGTM you attest that:

    • Commits are adequately tested
    • Code is easy to understand and conforms to our style guides
    • Incomplete code is marked with TODOs
    • Logging and metrics are suitable
    opened by majelbstoat 2
  • Allow Transport to be set on the client and fix access token assignment bug

    Allow Transport to be set on the client and fix access token assignment bug

    • On App Engine, one cannot use http.DefaultTransport but has to use urlfetch.Transport with a given context: https://godoc.org/google.golang.org/appengine/urlfetch#Transport. Allow for any transport that satisfies the http.RoundTripper interface to be used by the client.
    • Upon successfully acquiring an access token, the client was incorrectly checking for a non-nil error in order to assign the token to the client per the documentation.
    opened by andybons 1
  • Update docs to point to app creation UI

    Update docs to point to app creation UI

    Hello @majelbstoat,

    Please review the following commits I made in branch 'kyle-app-creation'.

    8e039215bb771d6c7635299ba83b993f430e5fff (2015-11-18 15:39:57 -0800) Update docs to point to app creation UI

    [email protected]

    opened by kylehg 1
  • Fix readme example

    Fix readme example

    Hello @majelbstoat,

    Please review the following commits I made in branch 'jamie-readme-fix'.

    8a34e278a1fb938c87cf229d0772c42e70c1495b (2015-09-30 11:17:34 -0700) Fix readme example

    [email protected]

    MANUAL TESTING=not manually tested

    Code review reminders. By giving a LGTM you attest that:

    • Commits are adequately tested
    • Code is easy to understand and conforms to our style guides
    • Incomplete code is marked with TODOs
    • Logging and metrics are suitable
    opened by majelbstoat 1
  • Document usage or extend API for self-issued access tokens

    Document usage or extend API for self-issued access tokens

    It's possible to use the package with an AccessToken only.

            m := &medium.Medium{
                    AccessToken: "TOKEN",
                    Host:        "https://api.medium.com",
            }
    

    I think this should be documented or better yet API extended for this use case.

    opened by baris 0
  • Update README.md

    Update README.md

    Hello @majelbstoat,

    Please review the following commits I made in branch 'jamie-readme'.

    0ad8a808358570fe9206de49430430d87324b692 (2015-09-27 22:09:46 -0700) Update README.md

    [email protected]

    MANUAL TESTING=not manually tested

    Code review reminders. By giving a LGTM you attest that:

    • Commits are adequately tested
    • Code is easy to understand and conforms to our style guides
    • Incomplete code is marked with TODOs
    • Logging and metrics are suitable
    opened by majelbstoat 0
  • API Error: User not found!

    API Error: User not found!

    Medium API doesn't work. I have created an APP and authorized my user. Fetched the access_token successfully. But when I try to fetch an authorized user's info, I have gotten the below error message: {"errors":[{"message":"User not found","code":6004}]}

    These are the logs: http://prntscr.com/qarjrp http://prntscr.com/qark4h

    I have tried to create a new "Integration tokens" from my User settings and tried to use it instead of the access token. But the same result. I can not get authorized user's information. What is wrong? Could you help me, please? I have contacted the Medium support team several times. But their support is very bad. They reply very late and every time writes unrelated messages.

    Thanks in advance.

    opened by sexavet94 0
  • json: cannot unmarshal array into Go value of type medium.Publications

    json: cannot unmarshal array into Go value of type medium.Publications

    Executing the code below (access code deleted),

    package main
    
    import (
    	"fmt"
    	"log"
    
    	medium "github.com/medium/medium-sdk-go"
    )
    
    func main() {
    	m2 := medium.NewClientWithAccessToken("")
    
    	user, err := m2.GetUser("")
    	fmt.Printf("User is %q\n", user)
    	pubs, err := m2.GetUserPublications(user.ID)
    	if err != nil {
    		log.Fatal(err)
    	}
    	fmt.Printf("No. of publications: %d\n", len(pubs.Data))
    }
    

    leads to:

    User is &{"1278b5260445c10f4e13b9f37f4f60e9e59376cbd8e5230bf1efd5f700160f860" "debugjois" "ದೀಪಕ್/दीपक/دیپک/Deepak" "https://medium.com/@debugjois" "https://cdn-images-1.medium.com/fit/c/400/400/1*VY6glnPvt0Zbgi-uplEV0g.jpeg"}
    2018/02/07 16:25:19 json: cannot unmarshal array into Go value of type medium.Publications
    exit status 1
    
    
    opened by deepakjois 1
Owner
Medium
Welcome to Medium, where words matter.
Medium
Nextengine-sdk-go: the NextEngine SDK for the Go programming language

NextEngine SDK for Go nextengine-sdk-go is the NextEngine SDK for the Go programming language. Getting Started Install go get github.com/takaaki-s/nex

null 0 Dec 7, 2021
Commercetools-go-sdk is fork of original commercetools-go-sdk

commercetools-go-sdk The Commercetools Go SDK is automatically generated based on the official API specifications of Commercetools. It should therefor

Flink 0 Dec 13, 2021
Sdk-go - Go version of the Synapse SDK

synapsesdk-go Synapse Protocol's Go SDK. Currently in super duper alpha, do not

null 0 Jan 7, 2022
Redash-go-sdk - An SDK for the programmatic management of Redash, in Go

Redash Go SDK An SDK for the programmatic management of Redash. The main compone

RecoLabs 26 Sep 9, 2022
🚀 BiliBili API SDK in Golang

BiliGO BiliBili API SDK in Golang 简介 BiliBili API 的 Golang 实现,目前已经实现了 100+ API,还在进一步更新中 特性 良好的设计,支持自定义 client 与 UA 完善的单元测试,易懂的函数命名,极少的第三方库依赖 代码、结构体注释完

iyear 43 Sep 21, 2022
A Golang SDK for binance API

go-binance A Golang SDK for binance API. All the REST APIs listed in binance API document are implemented, as well as the websocket APIs. For best com

null 0 Oct 28, 2021
Zenvia API - Golang SDK

Zenvia API - Golang SDK Zenvia API (2.0) Why? This project is part of my personal portfolio, so, I'll be happy if you could provide me any feedback ab

Vinícius Boscardin 5 Nov 5, 2021
Unofficial getpocket.com API Golang SDK

GetPocket API Golang SDK https://getpocket.com/developer/ Example usage: package main import ( "context" "fmt" pocket "github.com/ernur-eskermes/p

Ernur Eskermes 0 Nov 28, 2021
Golang SDK for Dusupay payment gateway API (Unofficial)

Dusupay API SDK GO (Unofficial) Description Unofficial Dusupay payment gateway API Client for Go API documentation https://docs.dusupay.com/ Installat

Anton Kornilov 2 Sep 27, 2022
A Facebook Graph API SDK For Go.

A Facebook Graph API SDK In Golang This is a Go package that fully supports the Facebook Graph API with file upload, batch request and marketing API.

Huan Du 1.1k Sep 15, 2022
Unofficial SDK of official notion API in Go

notion-go A go client for the Notion API Description This aims to be an unofficial Go version of the official SDK which is written in JavaScript. Inst

Pei-Ming Wu 11 May 12, 2022
Go written SDK for Notion.so API

go-notion Go written Notion SDK. Note: The Notion API is in beta phase Supported APIs It supports all APIs for Notion API (as for 2021-05-15). Blocks

Ketion.so 12 Dec 10, 2021
The Fabric Token SDK is a set of API and services that lets developers create token-based distributed application on Hyperledger Fabric.

The Fabric Token SDK is a set of API and services that let developers create token-based distributed application on Hyperledger Fabric.

null 54 Sep 18, 2022
SDK to provide access to JUNO API (Open Banking) (2.0.0)

Juno API - Golang SDK Juno API (Open Banking) (2.0.0) Why? This project is part of my personal portfolio, so, I'll be happy if you could provide me an

Vinícius Boscardin 4 Aug 9, 2021
Instagram Messaging API GO SDK

Instagram Messaging API GO SDK Introduction Instabot, Instagram Messaging API GO SDK makes it easy to work with instagram messaging API. It uses Insta

Shahin Mahmud 30 Jul 23, 2022
Unofficial Go SDK for GoPay Payments REST API

Unofficial Go SDK for GoPay Payments REST API Installation go get https://github.com/apparently-studio/gopay-go-api Basic usage client := gopay.NewCl

Apparently Studio 2 Feb 5, 2022
unofficial NBA Stats API SDK in Go

nba api go (nag) is an unofficial NBA Stats API in Go. it is very much a Go port of nba_api. endpoints alltimeleadersgrids assistleaders assisttracker

aprp 1 Sep 23, 2022
SDK for API MercadoBitcoin

MercadoBitcoin SDK Easy way to consume the public api informations from MercadoBitcoin Example of API consume of Version 3 Simple code writed on main.

Thiago Zilli Sarmento 6 May 24, 2022
Reverse-engineered API + SDK for the Amizone Student Portal.

go-amizone go-amizone is a simple and robust Go library and API server for the Amizone student portal. This library is intended to be used as a self-h

Tushar 8 Sep 23, 2022