Skip to content

Commit

Permalink
Add a basic interface with Google Sheets API
Browse files Browse the repository at this point in the history
A demo of reading and writing from a private Google Sheet. Nice credential
storage has not been set up nicely yet, credentials and access to the private
Google Sheet can be provided if you DM me on Slack.
  • Loading branch information
benjimarshall committed Nov 10, 2020
1 parent febcc9c commit 995b29b
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
21 changes: 21 additions & 0 deletions DiscordBot.DataAccess/DiscordBot.DataAccess.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Google.Apis.Sheets.v4" Version="1.49.0.2111" />
</ItemGroup>

<ItemGroup>
<None Update="credentials.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="example_credentials.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
89 changes: 89 additions & 0 deletions DiscordBot.DataAccess/EventsSheetsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Sheets.v4;
using Google.Apis.Sheets.v4.Data;
using static Google.Apis.Sheets.v4.SpreadsheetsResource.ValuesResource;

namespace DiscordBot.DataAccess
{
public class EventsSheetsService
{
private static readonly string[] scopes = { SheetsService.Scope.Spreadsheets };
private static readonly string applicationName = "Softwire Discord Bot";
private static readonly string spreadsheetId = "";

private SheetsService sheetsService;

private static async Task<ServiceAccountCredential> GetCredentialsAsync(string path = "credentials.json")
{
await using var stream =
new FileStream(path, FileMode.Open, FileAccess.Read);

var googleCredential = GoogleCredential.FromStreamAsync(stream, CancellationToken.None);

return (await googleCredential)
.CreateScoped(scopes)
.UnderlyingCredential as ServiceAccountCredential;
}

public EventsSheetsService() { }

public async Task StartService()
{
var credential = await GetCredentialsAsync();

// Create Google Sheets API service.
sheetsService = new SheetsService(new BaseClientService.Initializer
{
HttpClientInitializer = credential,
ApplicationName = applicationName
});
}

public async Task ReadColumns()
{
var range = "A2:B27";
var request =
sheetsService.Spreadsheets.Values.Get(spreadsheetId, range);

var response = await request.ExecuteAsync();
var values = response.Values;
if (values != null && values.Count > 0)
{
Console.WriteLine("Alpha, Numeric");
foreach (var row in values)
Console.WriteLine($"{row[0]}, {row[1]}");
}
else
{
Console.WriteLine("No data found.");
}
}

public async Task WriteRow()
{
var valueRange = new ValueRange
{
Values = new List<IList<object>>
{
new List<object>
{
"Test write:",
1
}
},
Range = "A30:B30"
};
var request = sheetsService.Spreadsheets.Values.Update(valueRange, spreadsheetId, "A30:B30");
request.ValueInputOption = UpdateRequest.ValueInputOptionEnum.RAW;

var response = await request.ExecuteAsync();
}

}
}
17 changes: 17 additions & 0 deletions DiscordBot.DataAccess/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Threading.Tasks;

namespace DiscordBot.DataAccess
{
class Program
{
private static async Task Main(string[] args)
{
var service = new EventsSheetsService();
await service.StartService();

await service.ReadColumns();

await service.WriteRow();
}
}
}
8 changes: 7 additions & 1 deletion DiscordBot.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30611.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{9B14A1D6-7521-44A9-AE51-ABFEDE10EE58}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DiscordBot", "DiscordBot\DiscordBot.csproj", "{9B14A1D6-7521-44A9-AE51-ABFEDE10EE58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBot.DataAccess", "DiscordBot.DataAccess\DiscordBot.DataAccess.csproj", "{05CC360C-58AE-4515-9DE5-EA0F08E22B82}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand All @@ -15,6 +17,10 @@ Global
{9B14A1D6-7521-44A9-AE51-ABFEDE10EE58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9B14A1D6-7521-44A9-AE51-ABFEDE10EE58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9B14A1D6-7521-44A9-AE51-ABFEDE10EE58}.Release|Any CPU.Build.0 = Release|Any CPU
{05CC360C-58AE-4515-9DE5-EA0F08E22B82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{05CC360C-58AE-4515-9DE5-EA0F08E22B82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{05CC360C-58AE-4515-9DE5-EA0F08E22B82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{05CC360C-58AE-4515-9DE5-EA0F08E22B82}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down

0 comments on commit 995b29b

Please sign in to comment.