Skip to content

Commit

Permalink
add user info
Browse files Browse the repository at this point in the history
  • Loading branch information
CrowdHailer committed Aug 22, 2024
1 parent 63004e2 commit 2ad4571
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 37 deletions.
36 changes: 35 additions & 1 deletion src/midas/sdk/google.gleam
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import gleam/bit_array
import gleam/dynamic
import gleam/http
import gleam/http/request
import gleam/http/response
import gleam/int
Expand Down Expand Up @@ -67,10 +66,45 @@ pub fn auth_redirect(redirect) {
use access_token <- try(key_find(parts, "access_token"))
use token_type <- try(key_find(parts, "token_type"))
use returned_state <- try(key_find(parts, "state"))
// other parts expires_in and scope
Ok(#(access_token, token_type, returned_state))
}

fn key_find(items, key) {
list.key_find(items, key)
|> result.replace_error("Did not find key: " <> key)
}

const openid_host = "openidconnect.googleapis.com"

const userinfo_path = "/v1/userinfo"

pub fn userinfo(token) {
let request = userinfo_request(token)
use response <- t.do(t.fetch(request))
use response <- t.try(userinfo_response(response))
t.Done(response)
}

pub fn userinfo_request(token) {
request.new()
|> request.set_host(openid_host)
|> request.prepend_header("Authorization", string.append("Bearer ", token))
|> request.set_path(userinfo_path)
|> request.set_body(<<>>)
}

pub fn userinfo_response(response: response.Response(BitArray)) {
use json <- try(
bit_array.to_string(response.body)
|> result.replace_error(snag.new("not utf8 encoded")),
)
use message <- try(
json.decode_bits(response.body, dynamic.field("email", dynamic.string))
|> result.map_error(fn(reason) {
snag.new(string.inspect(reason))
|> snag.layer("failed to decode message")
}),
)
Ok(message)
}
95 changes: 59 additions & 36 deletions src/midas/sdk/google/gmail.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ import gleam/dynamic
import gleam/http
import gleam/http/request
import gleam/http/response
import gleam/int
import gleam/json
import gleam/list
import gleam/option.{None, Some}
import gleam/result.{try}
import gleam/string
import gleam/uri.{Uri}
import midas/task as t
import snag

Expand All @@ -21,11 +17,11 @@ fn base_request(token) {
|> request.prepend_header("Authorization", string.append("Bearer ", token))
}

// fn get(token, path) {
// base_request(token)
// |> request.set_path(path)
// |> request.set_body(<<>>)
// }
fn get(token, path) {
base_request(token)
|> request.set_path(path)
|> request.set_body(<<>>)
}

fn post(token, path, mime, content) {
base_request(token)
Expand All @@ -43,47 +39,74 @@ pub fn send(token, from, to, message) {
}

pub fn send_request(token, from, to, message) {
let path = "/gmail/v1/users/" <> from <> "/messages/send"
let mime = "application/json; charset=UTF-8"
let email =
"From: "
<> from
<> " To: "
<> "\r\nTo: "
<> to
<> " Content-Type: text/html; charset=utf-8 "
<> "\r\nContent-Type: text/html; charset=utf-8 "
<> "\r\n"
<> message
let raw = bit_array.base64_encode(<<email:utf8>>, True)
let body = json.object([#("raw", json.string(raw))]) |> json.to_string
request.new()
// non-standard host
|> request.set_host("content-gmail.googleapis.com")
post(token, path, mime, <<body:utf8>>)
|> request.set_query([#("alt", "json")])
|> request.prepend_header("Authorization", string.append("Bearer ", token))
|> request.set_path("/gmail/v1/users/" <> from <> "/messages/send")
|> request.prepend_header("content-type", mime)
|> request.set_body(<<body:utf8>>)
}

pub fn send_response(response: response.Response(BitArray)) {
use json <- try(
bit_array.to_string(response.body)
|> result.replace_error(snag.new("not utf8 encoded")),
)
// let decoder = dynamic.list(site_decoder)
// use videos <- try(
// json.decode_bits(response.body, decoder)
// |> result.map_error(fn(reason) {
// snag.new(string.inspect(reason))
// |> snag.layer("failed to decode sites")
// }),
// )
Ok(json)
use message <- try(
json.decode_bits(response.body, message_decoder)
|> result.map_error(fn(reason) {
snag.new(string.inspect(reason))
|> snag.layer("failed to decode message")
}),
)
Ok(message)
}

pub type Message {
Message(id: String, thread_id: String)
}

fn message_decoder(raw) {
dynamic.decode2(
Message,
dynamic.field("id", dynamic.string),
dynamic.field("threadId", dynamic.string),
// dynamic.field("labelIds", dynamic.list(dynamic.string)),
)(raw)
}

pub fn list_messages(token, user_id) {
let request = list_messages_request(token, user_id)
use response <- t.do(t.fetch(request))
use response <- t.try(list_messages_response(response))
t.Done(response)
}

pub fn list_messages_request(token, user_id) {
let path = "/gmail/v1/users/" <> user_id <> "/messages"
get(token, path)
}

pub fn list_messages_response(response: response.Response(BitArray)) {
use json <- try(
bit_array.to_string(response.body)
|> result.replace_error(snag.new("not utf8 encoded")),
)
let decoder = dynamic.field("messages", dynamic.list(message_decoder))
use message <- try(
json.decode_bits(response.body, decoder)
|> result.map_error(fn(reason) {
snag.new(string.inspect(reason))
|> snag.layer("failed to decode messages")
}),
)
Ok(message)
}
// fn site_decoder(raw) {
// dynamic.decode4(
// Site,
// dynamic.field("id", dynamic.string),
// dynamic.field("state", dynamic.string),
// dynamic.field("name", dynamic.string),
// dynamic.field("url", dynamic.string),
// )(raw)
// }

0 comments on commit 2ad4571

Please sign in to comment.