Questions/Help Regarding Golang API response to CSV


(Alex Treichler) #1

Hello Everyone,

First time here and I am excited to join. I would like to get a few things out there first and hope everyone is okay with it.

I am not a Programmer. I am a “technical” person and I enjoy learning new things. I have learned using PHP (very basic) from online courses and just something about Golang attracted me to learn. I have purchased a “Learn Go” program on Udemy and I am working my way through it.

I am looking to create a very basic program that cycles through an API and pastes the Json results into a CSV file. Most of the code I will provide below has been stitched together from different locations online. However, I am currently at a standstill and have not been able to get past my current question/code, which is why I am hoping the community here could assist me or point me in the right direction.

I am using the API from a product called Message360 (think exactly like Twillio, but better IMO). They have a “carrier lookup” API. Essentially, this API, when sending a phone number, will spit back some information in a Json Response. I then want to take that response and create a CSV file with the data in it. My end goal is to have a list of say 10,000 phone numbers that I can upload and the program will run the API each time and paste the results into this CSV. Ideally, I would like it to be able to do “multiple” numbers at once (to increase the speed) since I will be using this to run through thousands of numbers at a time.

Below is the Code that I have so far. I have an example of what the Json Response is from the Carrier Lookup API, which is assigned to a variable called “exampleJSON”. The Main function then runs using this sample and pastes the results into a CSV file. This part works. However, that will not work for my end goal. I have a function called “carrierlookup” that, when run on it’s own, spits out the Json response I am looking for.

The thing I am not sure how to do, is to instead of using the “exampleJSON” variable, it uses the results from the “carrierlookup” API.

Any help or direction on documents that can point me in the right direction would be much appreciated.

Thank you

package main

import (
    "encoding/csv"
    "encoding/json"
    "fmt"
    "log"
    "os"
    "strconv"
    "strings"
    "net/http"
    "io/ioutil"
)

func decodeJson(m map[string]interface{}) []string {
    values := make([]string, 0, len(m))
    for _, v := range m {
        switch vv := v.(type) {
        case map[string]interface{}:
            for _, value := range decodeJson(vv) {
                values = append(values, value)
            }
        case string:
            values = append(values, vv)
        case float64:
            values = append(values, strconv.FormatFloat(vv, 'f', -1, 64))
        case []interface{}:

        case bool:
            values = append(values, strconv.FormatBool(vv))
        case nil:
            values = append(values, "nil")
        }
    }
    return values
}


func carrierlookup() {

    url := "https://api.message360.com/api/v3/carrier/lookup.json"

    payload := strings.NewReader("phoneNumber=9998881111")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
    req.Header.Add("Authorization", "Basic XXXXX")
    req.Header.Add("Cache-Control", "no-cache")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

   // fmt.Println(res)
   // fmt.Println(string(body))

}



func main() {
    var d interface{}
    err := json.Unmarshal(exampleJSON, &d)
    if err != nil {
        log.Fatal("Failed to unmarshal")
    }
    values := decodeJson(d.(map[string]interface{}))
    fmt.Println(values)

    f, err := os.Create("outputfile.csv")
    if err != nil {
        log.Fatal("Failed to create outputfile.csv")
    }
    defer f.Close()
    w := csv.NewWriter(f)
    if err := w.Write(values); err != nil {
        log.Fatal("Failed to write to file")
    }
    w.Flush()
    if err := w.Error(); err != nil {
        log.Fatal("Failed to flush outputfile.csv")
    }
}



var exampleJSON []byte = []byte(`{
    "Message360": {
        "ResponseStatus": 1,
        "Carrier": {
            "ApiVersion": "3",
            "CarrierSid": "8ad76a2e-aeb9-1184-47a2-747f08c91e58",
            "AccountSid": "0823da9f-d8d7-c062-75fd-f152705c746a",
            "PhoneNumber": "+19998881111",
            "Network": "Cellco Partnership dba Verizon Wireless - CA",
            "Wireless": "true",
            "ZipCode": "92604",
            "City": "Irvine",
            "Price": "0.0003",
            "Status": "success",
            "DateCreated": "2018-02-05 16:28:30"
        }
    }
}`)


(Leaf Bebop) #2

You need to let carrierlookup return a value and unmarshal that value:

func carrierlookup() []byte {
    ...
    return body
}

And unmarlshal it like err := json.Unmarshal(carrierlooup(),&d).


(Alex Treichler) #3

Thank you for the information and I appreciate your quick response and help. I made the mentioned changes and I am receiving the following error,

./carrierlookupgo.go:56:5: cannot use body (type []byte) as type string in return argument
./carrierlookupgo.go:66:35: cannot convert carrierlookup() (type string) to type []string
./carrierlookupgo.go:89:1: comment not terminated

(Leaf Bebop) #4

I got the type of body wrong. Sorry for that. The code is now updated.


(Alex Treichler) #5

Thank you.


(system) #6

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.