私は、Instagram APIとやりとりする小さなコマンドラインベースのGo botを構築中です。応答を返した後のHTTPサーバーのシャットダウン
Instagram APIはOAuthベースであり、コマンドラインベースのアプリケーションにはあまり適していません。
これを回避するには、ブラウザで適切な認証URLを開き、ローカルサーバーを使用してリダイレクトURIをスピンアップします。この方法で、アクセストークンをキャプチャし、正常に表示することができますこれをURLから手動で取得します。
これまでのところ、アプリケーションはブラウザを認証URLに正常に開くことができ、認証してローカルのHTTPサーバーにリダイレクトします。
アクセストークンがユーザーに表示された後、HTTPサーバーが必要なくなり、この後、手動でサーバーをシャットダウンする必要があります。
は、これを行うために、私はこのanswerからインスピレーションを描き、下記まで叩い:
package main
import (
"fmt"
"io"
"log"
"net/http"
"os/exec"
"runtime"
"time"
)
var client_id = "my_client_id"
var client_secret = "my_client_secret"
var redirect_url = "http://localhost:8000/instagram/callback"
func main() {
srv := startHttpServer()
openbrowser(fmt.Sprintf("https://api.instagram.com/oauth/authorize/?client_id=%v&redirect_uri=%v&response_type=code", client_id, redirect_url))
// Backup to gracefully shutdown the server
time.Sleep(20 * time.Second)
if err := srv.Shutdown(nil); err != nil {
panic(err) // failure/timeout shutting down the server gracefully
}
}
func showTokenToUser(w http.ResponseWriter, r *http.Request, srv *http.Server) {
io.WriteString(w, fmt.Sprintf("Your access token is: %v", r.URL.Query().Get("code")))
if err := srv.Shutdown(nil); err != nil {
log.Fatal(err) // failure/timeout shutting down the server gracefully
}
}
func startHttpServer() *http.Server {
srv := &http.Server{Addr: ":8000"}
http.HandleFunc("/instagram/callback", func(w http.ResponseWriter, r *http.Request) {
showTokenToUser(w, r, srv)
})
go func() {
if err := srv.ListenAndServe(); err != nil {
// cannot panic, because this probably is an intentional close
log.Printf("Httpserver: ListenAndServe() error: %s", err)
}
}()
// returning reference so caller can call Shutdown()
return srv
}
func openbrowser(url string) {
var err error
switch runtime.GOOS {
case "linux":
err = exec.Command("xdg-open", url).Start()
case "windows":
err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
case "darwin":
err = exec.Command("open", url).Start()
default:
err = fmt.Errorf("unsupported platform")
}
if err != nil {
log.Fatal(err)
}
}
しかし、上記の原因このエラー:
2017/11/23 16:02:03 Httpserver: ListenAndServe() error: http: Server closed
2017/11/23 16:02:03 http: panic serving [::1]:61793: runtime error: invalid memory address or nil pointer dereference
私はこれらの行をコメントアウトした場合私がコールバックルートをヒットしたときにサーバーをシャットダウンすることなく、完璧に動作します。
どこが間違っていますか?ユーザーにテキストを表示した後で、コールバックルートをたどったときにサーバーをシャットダウンできるようにするには、何を変更する必要がありますか。
完全に動作します。 – James