Skip to content

Instantly share code, notes, and snippets.

@ImaginaryDevelopment
Created October 15, 2018 15:07
Show Gist options
  • Save ImaginaryDevelopment/b99cd55a70fd0b4faba09bf06d34f3ab to your computer and use it in GitHub Desktop.
Save ImaginaryDevelopment/b99cd55a70fd0b4faba09bf06d34f3ab to your computer and use it in GitHub Desktop.
Discord Bot F# interactive attempt
#if INTERACTIVE
#r @"C:\Users\bdimp\AppData\Local\LINQPad\NuGet.FW46\BrokenDiscord\Hopac.0.3.23\lib\net45\Hopac.Core.dll";;
#r @"C:\Users\bdimp\AppData\Local\LINQPad\NuGet.FW46\BrokenDiscord\Hopac.0.3.23\lib\net45\Hopac.dll";;
#r @"C:\Users\bdimp\AppData\Local\LINQPad\NuGet.FW46\BrokenDiscord\BrokenDiscord.1.0.0\lib\net461\BrokenDiscord.dll";;
#r @"C:\ProgramData\LINQPad\Updates50\beta\LINQPad.exe";;
#r @"C:\Users\bdimp\AppData\Local\LINQPad\NuGet.FW46\BrokenDiscord\FSharp.Control.AsyncSeq.2.0.21\lib\net45\FSharp.Control.AsyncSeq.dll"
open LINQPad
open BrokenDiscord.Client
open BrokenDiscord.Events
open BrokenDiscord.Types
open Hopac
open FSharp.Control
;;
#endif
// GO
open System
open System.Reflection
module Option =
let getOrDefault y = function | Some x -> x | None -> y
module Reflection =
type System.Reflection.Assembly with
member x.Name =
x.FullName
|> Option.ofObj
|> Option.map (fun n -> n.Split(',').[0])
|> Option.getOrDefault x.FullName
member x.Version =
try
x.GetName().Version.ToString()
with ex -> "Unknown"
type LocationStage =
| AN of AssemblyName
| A of Assembly
with
member x.Location =
match x with
| AN an ->
try
if isNull an.CodeBase then
Assembly.ReflectionOnlyLoad(an.FullName).Location
else an.CodeBase
with _ex -> null
| A a -> a.Location
member x.ToDump() =
let loc = x.Location
match x with
| AN an ->
let v = string an.Version
sprintf "%s - %A - %s" an.Name v loc
| A a -> sprintf "%s - %s - %s" a.Name a.Version loc
let getRefAssemblies () =
let needsTypeReferenceToLoad =
// put types that need to be forced to show up (or to get a location) at this point in the program's execution
let types: Type list =
[
typeof<Hopac.EmbeddedJob<_>>
typeof<Hopac.Core.AltAfter<_,_>>
typeof<BrokenDiscord.BrokenDiscord>
typeof<FSharp.Core.AbstractClassAttribute>
typeof<FSharp.Control.AsyncSeq<_>>
]
types
|> List.map(fun t -> t.Assembly)
|> Seq.map (fun a -> a.Name, a)
|> Map.ofSeq
let found =
Assembly.GetExecutingAssembly().GetReferencedAssemblies()
|> Seq.sortBy(fun ra -> ra.Version)
|> List.ofSeq
|> List.rev
|> List.map (fun a ->
a.Name,
if Map.containsKey a.Name needsTypeReferenceToLoad then
A needsTypeReferenceToLoad.[a.Name]
else AN a
)
|> Map.ofList
needsTypeReferenceToLoad
|> Map.fold(fun map name ass ->
if Map.containsKey name map then
map
else Map.add name (A ass) map
) found
|> Map.fold (fun items _ ls -> ls.ToDump() :: items) List.empty
open Reflection
// GO
#if !INTERACTIVE
//getRefAssemblies();;
getRefAssemblies().Dump()
#else
getRefAssemblies() |> List.iter (fun x -> printfn "%A" x);;
#endif
module Discordantly =
let dumpAuthorizeForChannelLink () =
Util.GetPassword "Client ID"
|> sprintf "https://discordapp.com/oauth2/authorize?&client_id=%s&scope=bot&permissions=0"
#if INTERACTIVE
|> printfn "%s"
#else
|> fun x -> LINQPad.Hyperlinq(x,"Add Bot to Server link")
|> LINQPad.Extensions.Dump
#endif
|> ignore
let pong (client:Client) (m : Message) =
job {
// fails here
if m.content = "!ping" then
return! client.CreateMessage m.channelId <| MessageCreate.T.New "pong!"
|> Job.startIgnore
else return ()
} |> start
let handleEvents client = function
| MessageCreate m -> (pong client m)
| _ -> ()
open Discordantly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment