How can google app engine create new contacts? - google-app-engine

I'm developing a membership sign up app for an organization on Google App Engine, for new members, they can use a sign up page to become a member, is there a way in Google App Engine to add new members as gmail contacts ? So each time a new user clicks a submit button with his info, a new gmail contact is auto generated and added to my contact list [ my gmail address is registered with the GAE app ].
Here is some of my code try to do that, but it doesn't add new contacts each a submit button is pressed :
String Add_New_Contact_Url="https://www.google.com/m8/feeds/contacts/default/full";
protected void processRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
{
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8"); // UTF-8 GB18030
PrintWriter out=response.getWriter();
String Email=request.getParameter("Email");
if (Email==null || Email.trim().length()<1)
{
StrBuf=new StringBuffer("<Html><Head><Title>Signup</Title></Head>\n<Body>\n");
StrBuf.append("<P><Br><P><Br><P>\n");
StrBuf.append("<Table Border=1 Align=Center Cellpadding=8 Cellspacing=1><Tr Bgcolor=\"#0088FF\" Colspan=2><Th><Font Color=White>Sign up</Font></Th></Tr></Table>\n<P>\n");
StrBuf.append("<Center>\n");
StrBuf.append("<Form Name=Singles_Club_Signup_Form>\n");
StrBuf.append("<Table Border=1 Cellpadding=6 Cellspacing=1>\n");
...
StrBuf.append("<Tr><Td Align=Right><B><Font Size=3 Color=#0066FF>Email</Font></B></Td><Td><Input type=text name=Email size=36 /></Td></Tr>\n");
...
StrBuf.append("</Table>\n");
StrBuf.append("<P><Br><P>\n");
StrBuf.append("<Input type=submit value=Sign_Up/>\n");
StrBuf.append("</Form>\n");
StrBuf.append("</Center>\n");
StrBuf.append("</Body>\n</Html>");
}
else
{
try
{
LinkedHashMap<String,String> Key_Value_Pairs=new LinkedHashMap<String,String>();
String A_Contact=createContact(Email);
Key_Value_Pairs.put("A",A_Contact);
getFromUrlDoPost(Add_New_Contact_Url,Key_Value_Pairs); // Create new contact in Gmail account
}
catch (Exception e) { out.println(e.toString()); }
finally { if (pm!=null) pm.close(); }
}
}
String createContact(String Email)
{
return "<atom:entry xmlns:atom='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>\n"+
"<atom:category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/contact/2008#contact' />\n"+
"<gd:name>\n"+
"<gd:givenName>AAA</gd:givenName>\n"+
"<gd:familyName>BBB</gd:familyName>\n"+
"<gd:fullName>AAA BBB</gd:fullName>\n"+
"</gd:name>\n"+
"<atom:content type='text'>Notes</atom:content>\n"+
"<gd:email rel='http://schemas.google.com/g/2005#work' primary='true' address='"+Email+"' displayName='E. Bennet' />\n"+
"<gd:email rel='http://schemas.google.com/g/2005#home' address='liz#example.org' />\n"+
"<gd:phoneNumber rel='http://schemas.google.com/g/2005#work' primary='true'>\n"+
"(206)555-1212\n"+
"</gd:phoneNumber>\n"+
"<gd:phoneNumber rel='http://schemas.google.com/g/2005#home'>\n"+
"(206)555-1213\n"+
"</gd:phoneNumber>\n"+
"<gd:im address='liz#gmail.com' protocol='http://schemas.google.com/g/2005#GOOGLE_TALK' primary='true' rel='http://schemas.google.com/g/2005#home' />\n"+
"<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>\n"+
"<gd:city>Mountain View</gd:city>\n"+
"<gd:street>1600 Amphitheatre Pkwy</gd:street>\n"+
"<gd:region>CA</gd:region>\n"+
"<gd:postcode>94043</gd:postcode>\n"+
"<gd:country>United States</gd:country>\n"+
"<gd:formattedAddress>\n"+
"1600 Amphitheatre Pkwy Mountain View\n"+
"</gd:formattedAddress>\n"+
"</gd:structuredPostalAddress>\n"+
"</atom:entry>";
}
StringBuffer getFromUrlDoPost(String A_Url,LinkedHashMap Key_Value_Pairs) throws MalformedURLException,IOException
{
StringBuffer Text_Out=new StringBuffer(""),Text_In=new StringBuffer("");
String data="",key,value,inputLine;
try // Sending a POST Request Using a URL
{
// Construct data -- List the entries
for (Iterator it=Key_Value_Pairs.keySet().iterator();it.hasNext();)
{
key=it.next().toString();
value=Key_Value_Pairs.get(key).toString();
if (data.length()==0) data=URLEncoder.encode(key,"UTF-8")+"="+URLEncoder.encode(value,"UTF-8");
else data+="&"+URLEncoder.encode(key,"UTF-8")+"="+URLEncoder.encode(value,"UTF-8");
}
// Send data
URLConnection conn=new URL(A_Url).openConnection();
conn.setRequestProperty("Content-Type","application/atom+xml");
conn.setDoOutput(true);
OutputStreamWriter wr=new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
Text_In.setLength(0);
// Get the response
BufferedReader rd=new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((inputLine=rd.readLine()) != null) Text_In.append(inputLine+"\n");
wr.close();
rd.close();
}
catch (Exception e) { }
return Text_In;
}
It doesn't cause error either, what did I do wrong ? I suspect this line :
Key_Value_Pairs.put("A",A_Contact);
Because I don't know what to put in the place of "A" ?

Your users can authorize your application (via OAuth) to interact with their gmail contact list via the Contacts Data API.

I found out why : don't need to include google-collect-*.jar, source of error.

Related

Microsoft Botframework V4 Virtual Assistant Azure AD Authentication

I have downloaded, configured and deployed the Microsoft Virtual Assistant open source project from GitHub here: https://github.com/Microsoft/AI
I want to start with the calendar skill and have configured everything.
When I request my current calendar entries, the authentication prompt is shown in the botframework emulator and I am able to authenticate with my Azure AD Account.
After that, there is silence...
In SummaryDialog.cs in the CalendarSkill there is a definition for a WaterfallStep like this:
var showSummary = new WaterfallStep[]
{
GetAuthToken,
AfterGetAuthToken,
ShowEventsSummary,
CallReadEventDialog,
AskForShowOverview,
AfterAskForShowOverview
};
The step GetAuthToken is executed, but then execution stops. AfterGetAuthToken is not called at all.
This is the GetAuthToken function inside the project:
protected async Task<DialogTurnResult> GetAuthToken(WaterfallStepContext sc, CancellationToken cancellationToken)
{
try
{
var skillOptions = (CalendarSkillDialogOptions)sc.Options;
// If in Skill mode we ask the calling Bot for the token
if (skillOptions != null && skillOptions.SkillMode)
{
// We trigger a Token Request from the Parent Bot by sending a "TokenRequest" event back and then waiting for a "TokenResponse"
// TODO Error handling - if we get a new activity that isn't an event
var response = sc.Context.Activity.CreateReply();
response.Type = ActivityTypes.Event;
response.Name = "tokens/request";
// Send the tokens/request Event
await sc.Context.SendActivityAsync(response);
// Wait for the tokens/response event
return await sc.PromptAsync(SkillModeAuth, new PromptOptions());
}
else
{
return await sc.PromptAsync(nameof(MultiProviderAuthDialog), new PromptOptions());
}
}
catch (SkillException ex)
{
await HandleDialogExceptions(sc, ex);
return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs);
}
catch (Exception ex)
{
await HandleDialogExceptions(sc, ex);
return new DialogTurnResult(DialogTurnStatus.Cancelled, CommonUtil.DialogTurnResultCancelAllDialogs);
}
}
Am I doing anything wrong in the code or is there anything missing in my configuration?
I found out, if ngrok is not on the PC and configured, the virtual Assistatn does not work.

Send a PDF as an attachment through Sendgrid

I'm using Sendgrid to send emails through an app on GAE. It's working fine, but I also want to be able to send PDFs as an attachment.
I'm not using Sendgrid.jar file in my project. I've just used Sendgrid.java. And this class has no methods by which i can add attachments. Can someone help me?
public static boolean sendEmail(String fromMail, String title, String toMail, String message) throws IOException {
Email from = new Email(fromMail);
String subject = title;
Email to = new Email(toMail);
Content content = new Content("text/html", message);
Mail mail = new Mail(from, subject, to, content);
Path file = Paths.get("file path");
Attachments attachments = new Attachments();
attachments.setFilename(file.getFileName().toString());
attachments.setType("application/pdf");
attachments.setDisposition("attachment");
byte[] attachmentContentBytes = Files.readAllBytes(file);
String attachmentContent = Base64.getMimeEncoder().encodeToString(attachmentContentBytes);
String s = Base64.getEncoder().encodeToString(attachmentContentBytes);
attachments.setContent(s);
mail.addAttachments(attachments);
SendGrid sg = new SendGrid("sendgrid api key");
Request request = new Request();
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
if (response != null) {
return true;
} else {
return false;
}
}
Define above static method and call with relevant arguments as your program wants.
Here is the code of a servlet that sends a mail with a PDF as attachment, through Sendgrid:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
....
ByteArrayOutputStream os = null;
try {
PDFGenerator pdfGenerator = new PDFGenerator(invoiceOut);
os = pdfGenerator.getPDFOutputStream();
} catch (Exception e) {
....
}
SendGrid sendgrid = new SendGrid(Constants.SENDGRID_API_KEY);
SendGrid.Email email = new SendGrid.Email();
email.addTo(....);
email.setFrom(....);
email.setFromName(....);
email.setSubject(....);
email.setHtml("......");
ByteBuffer buf = null;
if (os == null) {
//error...
} else {
buf = ByteBuffer.wrap(os.toByteArray());
}
InputStream attachmentDataStream = new ByteArrayInputStream(buf.array());
try {
email.addAttachment("xxxxx.pdf", attachmentDataStream);
SendGrid.Response response = sendgrid.send(email);
} catch (IOException e) {
....
throw new RuntimeException(e);
} catch (SendGridException e) {
....
throw new RuntimeException(e);
}
}
PDFGenerator is one of my classes in which getPDFOutputStream method returns the PDF as ByteArrayOutputStream.
I personally find it easier to directly construct the JSON request body as described in the API docs than to use Sendgrid's libraries. I only use the Sendgrid library for sending the request after I construct the JSON data myself.
When constructing the JSON data you need to specify at least a filename and the content (i.e., the PDF file). Make sure to Base64 encode the PDF file before adding it to the JASON data.
I'd include some code, but I do Python and not Java so not sure that would help.

Google Plus credentials for application Login

I am creating an app and I want to confirm user using the Google credentials in Java environment. It can be done using google API but I am not sure how to code it as a servlet.
I found a code snippet to authorize the credentials but the AuthorizationCodeInstalledApp() is throwing an error and I am not sure which api to use.
private static Credential authorize() throws Exception {
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(Test.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://code.google.com/apis/console/?api=plus "
+ "into plus-cmdline-sample/src/main/resources/client_secrets.json");
System.exit(1);
}
// set up authorization code flow
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(PlusScopes.PLUS_ME)).setDataStoreFactory(
dataStoreFactory).build();
// authorize
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
Hope someone can help me with this and also let me know the process it'll be great...
If you really are writing a servlet to run under Google AppEngine, it is much much easier than that.
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
...
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
UserService userService = UserServiceFactory.getUserService();
User currentUser = userService.getCurrentUser();
if (currentUser == null) {
resp.sendRedirect(userService.createLoginURL(req.getRequestURI()));
}
else {
// show the view
}
}

Deleting Contact not working on Google Glass

My app creates a contact item that is used to communicate images to the application via a timeline subscription.
When I am deleting contacts via the REST API I am getting a success status and when I list the contact items via the REST API I can verify that the contact is removed.
But on the device itself the contact is still there. Only when I shutdown and startup the device the contact is gone. How can I make that happen immediately after my request?
My Device info: XE9 up to date. The device has a connection and I can update/delete timeline items without any problem.
Deletion of contacts can happen by your Glassware only if those contacts were inserted into your Glass by the same Glassware.
I have tried this DeleteAllContacts code, that works pretty well.
NewUserBootstrapper.deleteAllContacts(MirrorClient.getMirror(credential), credential);
and this is the method.
private static void deleteAllContacts(Mirror service, Credential credential)
{
try {
ContactsListResponse contacts = service.contacts().list().execute();
for (Contact contact : contacts.getItems())
{
LOG.info("Contact ID: " + contact.getId());
LOG.info(" > displayName: " + contact.getDisplayName());
if (contact.getImageUrls() != null) {
for (String imageUrl : contact.getImageUrls()) {
LOG.info(" > imageUrl: " + imageUrl);
}
}
MirrorClient.deleteContact(credential, contact.getId());
}
}catch (IOException ioe) {
LOG.warning("An error occurred: " + ioe.getMessage());
}
}

How to upload file on GAE with GWT?

I've been trying this for hours, so maybe a fresh set of eyes will help.
I'm trying to upload a file to the server using GWT (using UiBinder) on Google App Engine. Following all the examples I can find, things look like they should work, but the server's 'post' method is showing 0 items uploaded.
Here's the client code:
FormUploader.ui.xml:
<g:FormPanel action="/formImageUploader" ui:field="formPanel">
<g:VerticalPanel>
<g:FileUpload ui:field="uploader"></g:FileUpload>
<g:Button ui:field="submit">Submit</g:Button>
</g:VerticalPanel>
</g:FormPanel>
FormUploader.java:
#UiField
FormPanel formPanel;
#UiField
FileUpload uploader;
#UiField
Button submit;
public FormUploader() {
initWidget(uiBinder.createAndBindUi(this));
formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
formPanel.setMethod(FormPanel.METHOD_POST);
addSubmitHandlers();
}
private void addSubmitHandlers() {
formPanel.addSubmitCompleteHandler(new SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
Core.log("Inside submitComplete");
Window.alert(event.getResults());
}
});
}
web.xml:
<servlet>
<servlet-name>formImageUploader</servlet-name>
<servlet-class>com.company.server.FormImageUploader</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>formImageUploader</servlet-name>
<url-pattern>/formImageUploader</url-pattern>
</servlet-mapping>
FormImageUploader.java:
public class FormImageUploader extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
log.info("Request.getContentLength(): " + request.getContentLength());
log.info("Content type: " + request.getContentType());
log.info("Parm names: ");
for (Object paramName : request.getParameterMap().keySet()) {
log.info("__Param name: " + paramName.toString());
}
log.info("Attribtue names: ");
Enumeration enu = request.getAttributeNames();
while (enu.hasMoreElements()) {
log.info("__Attribute name: " + enu.nextElement().toString());
}
log.info("Header names: ");
enu = request.getHeaderNames();
while (enu.hasMoreElements()) {
log.info("__Header name: " + enu.nextElement().toString());
}
resp.getWriter().println("Post Code has finished executing");
}
All this executes just fine, the client shows an alert box containing Post Code has finished executing, but I can't figure out how to get the content of the file I want to upload.
Here's the server side log:
Request.getContentLength(): 63
Content type: multipart/form-data; boundary=---------------------------194272772210834546661
Parm names:
Attribtue names:
__Attribute name: com.google.apphosting.runtime.jetty.APP_VERSION_REQUEST_ATTR
Can anyone help me see why I'm not seeing any files on the server after clicking "submit" on the client?
Thanks in advance
Edit:
Still can't figure out why I can't get the form data on the server. I'm following this example, and just trying to write the response out to the client, but the server is definitely not seeing any content from the client.
Server code:
try {
log.info("Inside try block");
ServletFileUpload upload = new ServletFileUpload();
log.info("created the servlet file upload");
res.setContentType("text/plain");
log.info("set the content type to text/plain");
FileItemIterator iterator = upload.getItemIterator(req);
log.info("Got the iterator for items");
while (iterator.hasNext()) {
log.info("__inside iterator.hasNext");
FileItemStream item = iterator.next();
log.info("__assigned the file item stream");
InputStream stream = item.openStream();
log.info("__opened said stream");
if (item.isFormField()) {
log.warning("Got a form field: " + item.getFieldName());
} else {
log.warning("Got an uploaded file: " + item.getFieldName() +
", name = " + item.getName());
int len;
byte[] buffer = new byte[8192];
while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
res.getOutputStream().write(buffer, 0, len);
}
log.info("Done writing the input to the output stream");
}
}
} catch (Exception ex) {
log.severe("Exception; " + ex);
throw new ServletException(ex);
}
log.info("Done parseInput3");
Logs:
Inside parseInput3
Inside try block
created the servlet file upload
set the content type to text/plain
Got the iterator for items
Done parseInput3
Again, it's definitely not able to iterate over the file items on the server... any idea why?
Turns out, GAE has a completely different way of uploading files (Blobs):
http://code.google.com/appengine/docs/java/blobstore/overview.html#Uploading_a_Blob
You need to supply the form's on the client with a Blobstore Upload URL (which times out) from the server, retrieved using:
blobstoreService.createUploadUrl('urlToRedirectToAfterUploadComplete')
After setting that upload URL on the form's action, the form will be submitted and the blobstore service will redirect to the supplied URL, which can then access the BlobKey of the object stored by Google.
So with this, I added the following ChangeHandler to my GWT FileUpload:
private void addChangeListener() {
Core.log("Selected file: " + uploader.getFilename());
uploader.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
MyApp.SERVICES.getUploadUrl(new SuccessAsyncCallback<String>() {
#Override
public void onSuccess(String uploadUrl) {
form.setAction(uploadUrl);
form.submit();
Core.log("Submitted form with upload url: " + uploadUrl);
}
});
}
});
}
Then in the servlet I have the GAE redirect to after uploads:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Exception {
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
// where 'uploader' is the name of the FileUploader (<input type='file'>) control on the client
List<BlobKey> blobKeys = blobs.get("uploader");
resp.getOutputStream().print(blobKeys.get(0).getKeyString());
}
Note!
GAE will throw a OutOfMemory exception when trying to get the uploaded blob's value if the FileUpload control doesn't have a name="whateveryouwantthenametobe" attribute defined, even if you tell it (using UiBinder) that the id is ui:field="nameofControl"
You cannot write to the local file system - you should take a look at the files api.

Resources