I need to make a webrequest with HTTPS URL. But it always return (403) error. is there any other way for HTTPS URLs?
You can try this:
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
func main() {
dataMap := map[string]interface{}{} // own map
data, err := json.Marshal(dataMap)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", "https://newsapi.org/v2/everything", bytes.NewBuffer(data)) // replace url
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := (&http.Client{}).Do(req) // send request
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body) // read body
if err != nil {
panic(err)
}
var jsonResp map[string]interface{} // response map
err = json.Unmarshal(body, &jsonResp)
if err != nil {
panic(err)
}
fmt.Printf("Response: %s\nStatus: %s\n", jsonResp, resp.Status)
}
The output was:
Response: map[status:error code:apiKeyMissing message:Your API key is missing. Append this to the URL with the apiKey param, or use the x-api-key HTTPheader.]
Status: 401 Unauthorized
There still is an error, but that is caused by the server, because there is no API key.
Related
I am trying to get the list of hosts from ansible tower using the API defined in here
I am using the ansible tower URL -> https://zzzztower.zzzz.com/api/v2/hosts/
and the bearer token -> aaaaaaaaaaaaaaaaaaaaaaaaaaa
to hit the API.
When I use postman to hit the API I am getting a proper response
but when I use golang code, I am getting error
Get "https://ansibletower.micron.com/api/v2/hosts/": x509: certificate relies on legacy Common Name field, use SANs instead
Here is my code:
package globals
import (
"fmt"
"io/ioutil"
"net/http"
)
// var AUTH_TOKEN string = os.Getenv("AUTH_TOKEN")
func GetAnsibleHosts() (string, error) {
url := "https://zzzztower.zzzz.com/api/v2/hosts/"
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
return "", fmt.Errorf("Error creating request: %v", err)
}
bearerToken := "aaaaaaaaaaaaaaaaaaaaaaaaaaa"
// Add the Bearer Auth token to the request
req.Header.Add("Authorization", "Bearer "+bearerToken)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return "", err
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return "", err
}
// fmt.Println(string(body))
return string(body), err
}
I tried finding the error on google but i didn't find much help.
Few articles mentioned to use GODEBUG=x509ignoreCN=0 but it didn't worked.
I would really appreciate you help.
I'm trying to obtain the current market value of a coin from the bingx exchange, and I'm doing an http get request on what I believe is the correct api endpoint. after acquiring an access token it's still not allowing me to access the resource, is my logic flawed or am I just querying the wrong endpoint?
// get the current market value of a coin on Bingx - not working
func getBingxPriceWithAuth(currency string) {
// set API endpoint
url := "https://api.bingx.com/api/v3/ticker/price?symbol=" + currency
// create HTTP client
client := &http.Client{
Timeout: time.Second * 10,
}
// create HTTP GET request
req, err := http.NewRequest("GET", url, nil)
if err != nil {
}
// add the API credentials
req.Header.Add("Bingx-API-Key", MYKEY)
req.Header.Add("Bingx-API-Secret", MYSECRET)
// HTTP GET request
resp, err := client.Do(req)
if err != nil {
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
}
fmt.Println()
// parse the JSON
var data map[string]interface{}
err = json.Unmarshal(body, &data)
if err != nil {
}
fmt.Println(data)t
//return data["price"].(float64)
}
I am able to fetch the secrets from AWS secrets manager and using this secrets (ex : {"x-api-key":"123456789qwertyuiop"}) as an header, I want to call an API, I am new to golang and can anyone help me on this?
My code example
func fetch_api() {
?? How to call an POST API with below header??
// I get header secrets from below func getsecrets in above mentioned example
secret, _ := getsecrets("MyAPISecrets")
fmt.Println(secret)
}
func getsecrets(s string) (string, error) {
// Create a session
mySession, err := session.NewSession(&aws.Config{
Region: aws.String(os.Getenv("REGION"))},
)
if err != nil {
log.Fatal(err)
}
svc := secretsmanager.New(mySession)
result, err := svc.GetSecretValue(&secretsmanager.GetSecretValueInput{SecretId: &s})
if err != nil {
log.Fatal(err.Error())
}
return *result.SecretString, nil
}
func main() {
lambda.Start(fetch_api)
}
You can modify this code, it is just an example
func fetch_api() {
// I get header secrets from below func getsecrets in above mentioned example
secret, _ := getsecrets("MyAPISecrets")
fmt.Println(secret)
client := &http.Client{}
// create POST request
req, err := http.NewRequest("POST", url, body)))
if err != nil {
panic(err)
}
// set content-type header
req.Header.Set("Content-Type", "application/json")
// set x-api-key header
req.Header.Set("x-api-key", secret)
// send request
resp, err := client.Do(req)
if err != nil {
panic(err)
}
// print response
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
fmt.Println(string(body))
}
I am developing a Twitter bot using golang. I have been following the instructions written here
In order to make my webhook listen (subscribe) to the activity of a Twitter account (the bot), I have to subscribe my webhook to events. The guideline is in here
This is where I am stuck. I have managed to register my webhook but I keep failing to subscribe it to events.
Here is the code I run:
func main() {
//Load env
err := godotenv.Load()
if err != nil {
log.Fatal("Error loading .env file")
log.Println("Error loading .env file")
}
subscribeWebhook()
}
func CreateClient() *http.Client {
//Create oauth client with consumer keys and access token
config := oauth1.NewConfig(os.Getenv("CONSUMER_KEY"), os.Getenv("CONSUMER_SECRET"))
token := oauth1.NewToken(os.Getenv("ACCESS_TOKEN_KEY"), os.Getenv("ACCESS_TOKEN_SECRET"))
return config.Client(oauth1.NoContext, token)
}
func subscribeWebhook() {
log.Println("Subscribing webapp...")
client := CreateClient()
path := "https://api.twitter.com/1.1/account_activity/all/" + os.Getenv("WEBHOOK_ENV") + "/subscriptions.json"
resp, err := client.PostForm(path, nil)
if err != nil {
panic(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
defer resp.Body.Close()
//If response code is 204 it was successful
if resp.StatusCode == 204 {
log.Println("Subscribed successfully")
} else if resp.StatusCode != 204 {
log.Println("Could not subscribe the webhook. Response below:")
log.Println(string(body))
}
}
And this is the response I get:
{
"errors": [
{
"code": 348,
"message": "Client application is not permitted to access this user's webhook subscriptions."
}
]
}
Please, anyone help me figure this out. Thank you folks.
I have figured it out.
Turns out, on the app setting in the developer portal you have to give full permission (Read, Write, and Direct Messages) to you app. Then, regenerate your keys and tokes. Lastly update your env variables with the new keys and tokens.
I'm trying to POST a comment to imgur through the Imgur API. But I can't make the payload right. I have looked through Imgur's page about this and they showed that it should be coded like I have in strings.NewReader. The imageID is nP0uKKO
func HandleComment(w http.ResponseWriter, r *http.Request){
parts := strings.Split(r.URL.Path, "/")
switch r.Method {
case "POST":
// URL for POSTing comment
url := "https://api.imgur.com/3/comment"
// Authorization key
token := "Bearer " + os.Getenv("TOKEN")
// Payload
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
// Get body and http status code
body, status := DoStuff(parts[2], url, payload, token)
// If status is not OK
if status != 200 {
http.Error(w, "Could not post comment", status)
} else {
fmt.Fprintln(w, string(body))
}
DoStuff() does this
func DoStuff(method string, url string, body io.Reader, key string) ([]byte, int) {
// New request
req, err := http.NewRequest(method, url, body)
if err != nil {
fmt.Println(err)
}
// Add header with 'key' authorization
req.Header.Add("authorization", key)
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
imgBody, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return imgBody, res.StatusCode
}
I just get this error
{
data: {
error: "The parameter, image_id, is required.",
request: "/3/comment",
method: "POST"
},
success: false,
status: 400
}
The thing missing is the Content-Type header. You can modify your code like this:
In your handler HandleComment you can define the headers you want to pass to the request
case "POST":
// URL for POSTing comment
url := "https://api.imgur.com/3/comment"
// Authorization key
token := "Bearer " + os.Getenv("TOKEN")
// Payload
payload := strings.NewReader("------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"image_id\"\r\n\r\nnP0uKKO\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"comment\"\r\n\r\nI'm a giraffe!\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--")
// Headers
headers := map[string]string{
"Authorization": token,
"Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
}
// Get body and http status code
body, status := DoStuff(parts[2], url, payload, headers)
// If status is not OK
if status != 200 {
http.Error(w, "Could not post comment", status)
} else {
fmt.Fprintln(w, string(body))
}
Update DoStuff to read and pass the headers
func DoStuff(method string, url string, body io.Reader, headers map[string]string) ([]byte, int) {
// New request
req, err := http.NewRequest(method, url, body)
if err != nil {
fmt.Println(err)
}
// Add headers
for k, v := range headers {
req.Header.Add(k, v)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
imgBody, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return imgBody, res.StatusCode
}
I would suggest instead of using multipart/form-data; you might utilize the json content type. It is easier to manage and more readable
// Payload
payload := strings.NewReader("{\"image_id\": \"nP0uKKO\", \"comment\": \"I'm a giraffe!\"}")
// Headers
headers := map[string]string{
"Authorization": token,
"Content-Type": "application/json",
}