Command permissions Discord.net - discord.net

user type : "test",
if user have role "vip" then message show up "you have permission"
else "you dont have permission"
my code :
Public Async Function onMsg(message As SocketMessage) As Task
If message.Source = MessageSource.Bot Then
Else
If message.Content.Contains("test") Then
Dim userName As SocketGuildUser
Dim user = TryCast(message.Author, SocketGuildUser)
Dim role = (TryCast(user, IGuildUser)).Guild.Roles.FirstOrDefault(Function(x) x.Name = "vip")
If Not userName.Roles.Contains(role) Then
Await message.Channel.SendMessageAsync("you have permission")
Else
Await message.Channel.SendMessageAsync("you dont have permission")
End If
End If
End Function

First off, for creating commands in general, you should consider using the Command Service that's provided in Discord.Net, instead of If/Else checks in your message received event handler.
There's also an error in your code. You declare a userName variable, but never actually assign anything to it. Yet you attempt to do userName.Roles
Solution:
If message.Source = MessageSource.Bot Then
Return
ElseIf message.Content.Contains("test") Then
Dim user = TryCast(message.Author, SocketGuildUser)
'If casting the user to a SocketGuildUser was not successful, then exit
If user Is Nothing Then Return 'This can occur if a user message the bot via Direct Messages
'Using "Any" returns true if a match is found, false otherwise
If user.Roles.Any(Function(role) role.Name.Equals("VIP", StringComparison.OrdinalIgnoreCase)) Then
Await message.Channel.SendMessageAsync("you have permission")
Else
Await message.Channel.SendMessageAsync("you dont have permission")
End If
End If

a simply trick, if your vip's member can count as not many member's you can select them id's to let them permission.
If message.Content.Contains("test") Then
If message.Author.Mention = "<#!ID>" Then 'vip's permission |OrElse statement
Await message.Channel.SendMessageAsync("you have permission")
Else
Await message.Channel.SendMessageAsync("you dont have permission")
End If

Related

Roblox - Call external GraphQL API

I would like to call an external graphql API (without authentication for the moment).
Here is my code :
local open_api = "https://graphqlzero.almansi.me/api"
local payload = '{"query": "query { post(id: 1) { id title body }}"}'
local headers = {
}
local function craftCall()
local response
local data
pcall(function ()
response = HttpService:PostAsync(open_api, payload, Enum.HttpContentType.ApplicationJson, false, headers)
data = HttpService:JSONDecode(response)
end)
if not data then return false end
print(data)
return false
end
if craftCall() then
print("Success")
else
print("Something went wrong")
end
I get always something went wrong. I need some help on what is going wrong... Specially I don't know if am I correctly formatting the Payload.
After your http call, you never return a success result. You've only outlined failure cases :
if not data then return false end
print(data)
return false
So your conditional, if craftCall() then always evaluates to false.
Why not make it return true or data after the print(data)? Then you'll know that it made it to the end of the call successfully.
local function craftCall()
local success, result = pcall(function()
local response = HttpService:PostAsync(open_api, payload, Enum.HttpContentType.ApplicationJson, false, headers)
return HttpService:JSONDecode(response)
end)
if not success then
warn("PostAsync failed with error : ", result)
return false
end
-- return the parsed data
return result
end

Telegram API Client doesn't find group/send message

Im using TLSharp API Client for sending messages to groups, TLSharp is C#, but im trying to use it for VB.NET
C# Code:
//get user dialogs
var dialogs = (TLDialogsSlice) await client.GetUserDialogsAsync();
//find channel by title
var chat = dialogs.Chats
.Where(c => c.GetType() == typeof(TLChannel))
.Cast<TLChannel>()
.FirstOrDefault(c => c.Title == "<channel_title>");
//send message
await client.SendMessageAsync(new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = chat.AccessHash.Value }, "OUR_MESSAGE");
My VB.NET Code:
Dim dialogs = Await ((Await client.GetUserDialogsAsync()))
Dim chat = dialogs.Chats.lists.Where(Function(c) c.[GetType]() = GetType(TLChat)).Cast(Of TLChat)().FirstOrDefault(Function(c) c.title = "Group1")
Dim ChatId
Await client.SendMessageAsync(New TLInputPeerChat() {ChatId = chat.Id}, "TEST MSG")
The error i get:
Could not find public member 'GetAwaiter' in type 'TLDialogs'.'
I know it's not practical to convert it to vb.net, but I need it to integrate it into a project written in vb
I don't think that the client.GetUserDialogsAsync() method returns anything that is awaitable, so you should probably only have one Await in the line Dim dialogs = Await ((Await client.GetUserDialogsAsync())), and it may also require a cast:
Dim dialogs = DirectCast(Await client.GetUserDialogsAsync(), TLDialogsSlice)

Discord Bot [VB.net] Check if message has a mentioned user

Case "-move" 'The command 'n shizzle like that ;p
If message.serverpermission.Administrator = true then
Dim user = message.Message.MentionedUsers.FirstOrDefault()
Dim role = message.Server.FindRoles(arg, True).FirstOrDefault()
Await user.AddRoles(role) '!error on this line!
I want to check if the admin specified an user, if not, he will receive an error like ,,There is no one online with that name" or like ... ,,You need to specify/mention an user"
(Program returns an error if no one is mentioned&crashes;
System.NullReferenceException; 'Object reference not set to an
instance of an object.')
If you could help me with this problem, thanks! ^^
I've found the fix for the problem here;
If IsNothing(user) Then
Await message.Channel.SendMessage("You need to mention a user.")
else
if isnothing(role) then
Await message.Channel.SendMessage("That role is invalid.")
else
Await message.Channel.SendMessage("Success message here ;P")
end if
end if

Google task API authentication issue ruby

I am having the problem to authenticate a user for google tasks.
At first it authenticates the user and do things perfect. But in the second trip it throws an error.
Signet::AuthorizationError - Authorization failed. Server message:
{
"error" : "invalid_grant"
}:
following is the code:
def api_client code=""
#client ||= (begin
client = Google::APIClient.new
client.authorization.client_id = settings.credentials["client_id"]
client.authorization.client_secret = settings.credentials["client_secret"]
client.authorization.scope = settings.credentials["scope"]
client.authorization.access_token = "" #settings.credentials["access_token"]
client.authorization.redirect_uri = to('/callbackfunction')
client.authorization.code = code
client
end)
end
get '/callbackfunction' do
code = params[:code]
c = api_client code
c.authorization.fetch_access_token!
result = c.execute("tasks.tasklists.list",{"UserId"=>"me"})
unless result.response.status == 401
p "#{JSON.parse(result.body)}"
else
redirect ("/oauth2authorize")
end
end
get '/oauth2authorize' do
redirect api_client.authorization.authorization_uri.to_s, 303
end
What is the problem in performing the second request?
UPDATE:
This is the link and parameters to user consent.
https://accounts.google.com/o/oauth2/auth?
access_type=offline&
approval_prompt=force&
client_id=somevalue&
redirect_uri=http://localhost:4567/oauth2callback&
response_type=code&
scope=https://www.googleapis.com/auth/tasks
The problem is fixed.
Solution:
In the callbackfunction the tokens which are received through the code provided by the user consent are stored in the database.
Then in other functions just retrieve those tokens from the database and use to process whatever you want against the google task API.
get '/callbackfunction' do
code = params[:code]
c = api_client code
c.authorization.fetch_access_token!
# store the tokens in the database.
end
get '/tasklists' do
# Retrieve the codes from the database and create a client
result = client.execute("tasks.tasklists.list",{"UserId"=>"me"})
unless result.response.status == 401
p "#{JSON.parse(result.body)}"
else
redirect "/oauth2authorize"
end
end
I am using rails, and i store the token only inside DB.
then using a script i am setting up new client before calling execute, following is the code.
client = Google::APIClient.new(:application_name => 'my-app', :application_version => '1.0')
client.authorization.scope = 'https://www.googleapis.com/auth/analytics.readonly'
client.authorization.client_id = Settings.ga.app_key
client.authorization.client_secret = Settings.ga.app_secret
client.authorization.access_token = auth.token
client.authorization.refresh_token = true
client.authorization.update_token!({access_token: auth.token})
client.authorization.fetch_access_token!
if client.authorization.refresh_token && client.authorization.expired?
client.authorization.fetch_access_token!
end
puts "Getting accounts list..."
result = client.execute(:api_method => analytics.management.accounts.list)
puts " ===========> #{result.inspect}"
items = JSON.parse(result.response.body)['items']
But,it gives same error you are facing,
/signet-0.4.5/lib/signet/oauth_2/client.rb:875:in `fetch_access_token': Authorization failed. Server message: (Signet::AuthorizationError)
{
"error" : "invalid_grant"
}
from /signet-0.4.5/lib/signet/oauth_2/client.rb:888:in `fetch_access_token!'
Please suggest why it is not able to use the given token? I have used oauth2, so user is already authorized. Now i want to access the api and fetch the data...
===================UPDATE ===================
Ok, two issues were there,
Permission is to be added to devise.rb,
config.omniauth :google_oauth2, Settings.ga.app_key,Settings.ga.app_secret,{
access_type: "offline",
approval_prompt: "" ,
:scope => "userinfo.email, userinfo.profile, plus.me, analytics.readonly"
}
refresh_token must be passed to the API call, otherwise its not able to authorize.
I hope this helps to somebody, facing similar issue.

Using Rx to Geocode an address in Bing Maps

I am learning to use the Rx extensions for a Silverlight 4 app I am working on. I created a sample app to nail down the process and I cannot get it to return anything.
Here is the main code:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
var gsc = new GeocodeServiceClient("BasicHttpBinding_IGeocodeService") as IGeocodeService;
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var myFunc = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(gsc.BeginGeocode, gsc.EndGeocode);
gcResp = myFunc(gcr) as GeocodeResponse;
if (gcResp.Results.Count > 0 && gcResp.Results[0].Locations.Count > 0)
{
returnLocation = gcResp.Results[0].Locations[0];
}
return returnLocation as IObservable<Location>;
}
gcResp comes back as null. Any thoughts or suggestions would be greatly appreciated.
The observable source you are subscribing to is asynchronous, so you can't access the result immediately after subscribing. You need to access the result in the subscription.
Better yet, don't subscribe at all and simply compose the response:
private IObservable<Location> GetGPSCoordinates(string Address1)
{
IGeocodeService gsc =
new GeocodeServiceClient("BasicHttpBinding_IGeocodeService");
Location returnLocation = new Location();
GeocodeResponse gcResp = new GeocodeResponse();
GeocodeRequest gcr = new GeocodeRequest();
gcr.Credentials = new Credentials();
gcr.Credentials.ApplicationId = APP_ID2;
gcr.Query = Address1;
var factory = Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>(
gsc.BeginGeocode, gsc.EndGeocode);
return factory(gcr)
.Where(response => response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
.Select(response => response.Results[0].Locations[0]);
}
If you only need the first valid value (the location of the address is unlikely to change), then add a .Take(1) between the Where and Select.
Edit: If you want to specifically handle the address not being found, you can either return results and have the consumer deal with it or you can return an Exception and provide an OnError handler when subscribing. If you're thinking of doing the latter, you would use SelectMany:
return factory(gcr)
.SelectMany(response => (response.Results.Count > 0 &&
response.Results[0].Locations.Count > 0)
? Observable.Return(response.Results[0].Locations[0])
: Observable.Throw<Location>(new AddressNotFoundException())
);
If you expand out the type of myFunc you'll see that it is Func<GeocodeRequest, IObservable<GeocodeResponse>>.
Func<GeocodeRequest, IObservable<GeocodeResponse>> myFunc =
Observable.FromAsyncPattern<GeocodeRequest, GeocodeResponse>
(gsc.BeginGeocode, gsc.EndGeocode);
So when you call myFunc(gcr) you have an IObservable<GeocodeResponse> and not a GeocodeResponse. Your code myFunc(gcr) as GeocodeResponse returns null because the cast is invalid.
What you need to do is either get the last value of the observable or just do a subscribe. Calling .Last() will block. If you call .Subscribe(...) your response will come thru on the call back thread.
Try this:
gcResp = myFunc(gcr).Last();
Let me know how you go.
Richard (and others),
So I have the code returning the location and I have the calling code subscribing. Here is (hopefully) the final issue. When I call GetGPSCoordinates, the next statement gets executed immediately without waiting for the subscribe to finish. Here's an example in a button OnClick event handler.
Location newLoc = new Location();
GetGPSCoordinates(this.Input.Text).ObserveOnDispatcher().Subscribe(x =>
{
if (x.Results.Count > 0 && x.Results[0].Locations.Count > 0)
{
newLoc = x.Results[0].Locations[0];
Output.Text = "Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
}
else
{
Output.Text = "Invalid address";
}
});
Output.Text = " Outside of subscribe --- Latitude: " + newLoc.Latitude.ToString() +
", Longtude: " + newLoc.Longitude.ToString();
The Output.Text assignment that takes place outside of Subscribe executes before the Subscribe has finished and displays zeros and then the one inside the subscribe displays the new location info.
The purpose of this process is to get location info that will then be saved in a database record and I am processing multiple addresses sequentially in a Foreach loop. I chose Rx Extensions as a solution to avoid the problem of the async callback as a coding trap. But it seems I have exchanged one trap for another.
Thoughts, comments, suggestions?